From patchwork Thu Feb 22 18:13:47 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 204935 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:a81b:b0:108:e6aa:91d0 with SMTP id bq27csp122179dyb; Thu, 22 Feb 2024 10:17:08 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCVvBgH6pXURLVE/XkYVz9IEld4+OyCNrQymzoq165Yy23V9lBxjP8BXsNMUyA4WKCpldWT/sqcRl2Uzs4LpDDTXmvEk5A== X-Google-Smtp-Source: AGHT+IEvgCphyrqsq0R0uVasquuzRjbFAKExoQAxtbudQFikphS0FmL6AuQX58NLB0ORpkvYhu2M X-Received: by 2002:ac8:5952:0:b0:42e:4f7e:5fb1 with SMTP id 18-20020ac85952000000b0042e4f7e5fb1mr3493256qtz.18.1708625827837; Thu, 22 Feb 2024 10:17:07 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708625827; cv=pass; d=google.com; s=arc-20160816; b=D/FhOqIbFv4fHs3rhehqWBn0Nl+Kv/TdAq22Yams6Oh704kTG67rBOILm1k0KoI0W8 eVn91OUR4Bssoftcc95RF3VyEM27Mlcer8zycEm395+KevfKIiYobiRKMlC2r8nRFNn1 BrVlh6jo7PT/DrI3nukXbBjdy69kC1hHVbdOmpj1LxpBod+J3KGr8dXtWSAkXKsdYq28 J3NFc66yAq67ncts2ApcFL6EP9J3ghEr2blm+MJBiSqk/rpZE0kYhnxW/iYio3iJ8Nod tcqKh4LoBGIoURy038UZ5eGViPrx08eA50sAowLFF4rmkYEx7TYXtaPR8U4iqX9ES1+Q Wv6Q== 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=8SP8nLa7a120byFHksgvH+jH7UT4yjMb+TQrFcWf+kY=; fh=7mnR4/DMo6zaWtUGaVI9DND4TR+QGflpVaaXOChu5h0=; b=Tpq2Y0xGwAVg5DiVfNFW9UhjKhbeXyV3Asw/V5GmuoN+iA8scIyyoQuSyON7HcLnhN v6ZHYCa+0bOFv0OSAPTWfb6RJ0ILGKKzRXg2kDmY0NdwqCUHkSPn6Q4PSHcd5WKGKVIj huaDTqau15MKNjVsW6zf59cGnHuEeYZtc5BNGQJ7+C949CNhY3Xew/TTLWltU5FAukRI 1eCd4JwJh92cNmA8j0h5IoutaUV6NqPZ/KejNoS2cPkqYFRebmE1k7jxsBhJ4i4FI7oJ p9iP/OYdkx3cK9p0Mm5U/WsDSOcMGgMJt+ehy2e2ZJRVkStLGnxEfTzvrdVA5VLZqjga rGKA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=g3zBTaDI; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77061-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77061-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [147.75.199.223]) by mx.google.com with ESMTPS id u21-20020a05620a085500b0078735aa2219si13342121qku.198.2024.02.22.10.17.07 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Feb 2024 10:17:07 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-77061-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=g3zBTaDI; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77061-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77061-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 ED5471C25E79 for ; Thu, 22 Feb 2024 18:16:06 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id D8B5415A4BF; Thu, 22 Feb 2024 18:14:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="g3zBTaDI" 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 2ACC515957D; Thu, 22 Feb 2024 18: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=1708625671; cv=none; b=hSFiFrP7TCblD6x4f6rD5Ju8ZXKtZmzdB7K0AKTPsWMaFCtteLVdSMczn6s5iiVzHDaQodxEW/xQk6/Fey+UGLNdJ83qt3iBy2JVSYv9Pibu3ruf5uwTbV+Ym2V0DgfH1qA5BQoEv/iArp+BYQx4kH77nTRVYFYVk9nrcl704Rs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708625671; c=relaxed/simple; bh=kHekB7+ds8HZQmTIIDcT/8myymC9mYLsud01YExrJOg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=kT51Pu4wmSwkiZThDmk/AsOdqES+RYOGlNG3VBhRRmD01RPqjZ8tw+fP4ueGDXaLaD3YidfZFci4q7Osq83d/5oF66wPxyhJKnU2BMBdSXpVN8NDwzi8qh2Sg5UW7sLS2iEySLB8dElWfUv4oAjO9DTBRYHsTQV+Ekkw2yn0OX4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=g3zBTaDI; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6C23AC433C7; Thu, 22 Feb 2024 18:14:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1708625670; bh=kHekB7+ds8HZQmTIIDcT/8myymC9mYLsud01YExrJOg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=g3zBTaDItjm2XsKVKjxzwnBiuzy4wNXnVf4UYigdnUHlIBqP105EyAoYw1osMwpJM aMnUJvo0HCmK4cFpqouGt7Y8kLbOsY+EGzHu4rJO1W69bpA3nVT7ZPJkW8p/2DmLEP I6uBgaVc+ZJ3RwKSHbHsp3LLzfj1dyhWKUphOwiMb+//cxELWiEKcQ/n44G14DmEKb 8fyx883D8W1OmsOof61Lda6qUjkPeQf2KnnvgI+LX2E0WcZLCc4RhaRu1uqsRBwiEn iSsaRJjCa7Bv2QUUN1U5erKp4Ara5IzUddvlwcvwior7wpnawQYD5kN0+oaQIwnPSi MDoICaAnAGe+g== From: Maxime Ripard Date: Thu, 22 Feb 2024 19:13:47 +0100 Subject: [PATCH v7 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: <20240222-kms-hdmi-connector-state-v7-1-8f4af575fce2@kernel.org> References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , Sebastian Wick , =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= , dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-sunxi@lists.linux.dev, Maxime Ripard 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=kHekB7+ds8HZQmTIIDcT/8myymC9mYLsud01YExrJOg=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKnX+14+OPGD65yaVsrXhVmJuUeYFHZas6m/kLWwjn/uM e2Q+QW2jlIWBjEuBlkxRZYYYfMlcadmve5k45sHM4eVCWQIAxenAEzE6Cojw8dX7G+ZpRLPTvky 72jM/sy/Xqt2bxLjSFZ5zHvgq6fpOROGf3bOQpurI/9sPsWz6HlQz6qaOm62E3fYiyTfejJ9UOr 2YQAA X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791624035590318788 X-GMAIL-MSGID: 1791624035590318788 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 Reviewed-by: Maíra Canal --- 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 Thu Feb 22 18:13:48 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 204939 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:a81b:b0:108:e6aa:91d0 with SMTP id bq27csp122518dyb; Thu, 22 Feb 2024 10:17:37 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCXvdORs1E6mdGICnQLWWmZ4Q3k7WPDh1qaJeXM16MKNzDgDnO3IN1Cw4dkAAW3NWZZJ15IH8pC5PNimd4d35ya+JuaZsQ== X-Google-Smtp-Source: AGHT+IEByOkmiN1nuXFpnanvSSpeJUKUshyXUfYcVvL5mY+RRV3EEEpFrCrpxqfSFpIza4yM6o6f X-Received: by 2002:aa7:d7c6:0:b0:565:5913:c385 with SMTP id e6-20020aa7d7c6000000b005655913c385mr516516eds.8.1708625856949; Thu, 22 Feb 2024 10:17:36 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708625856; cv=pass; d=google.com; s=arc-20160816; b=QEpggHNEMXgBHP5De9Y6Zqu7qBg+bwmFA06A1StBvkBD2csLgo2dXBftlbefIjMxmQ Eeq6EoWJzXQmH6XlmikzoLcz1M2bc8atU81JWRUBgFuYj7mJzd1BAd3z/aFHs+RLLaKy UyXeyXslk4ZHyTTF06Xwjl4+MSGx+A6B9fLxtGa7/XAl1nkv7DxQr8BFsxLcXzbqxwmL i/KZD6KrqUazVgobtpkOg6SGUHPEdmepPlZ3IYHTMEl55CHY0nuSMhIcqpGaXgNNtZlv kZlvssBopVpvhY4yoyOjqVK2kXmiv7j1SVwIFbHjIKwkGn4sqJCsh1rRKhDVT3Qcnziw d3kw== 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=LGU1uoSYV6XFxmpWP17GkUNO3Z1gMHblacZZR0S6V/8=; fh=7mnR4/DMo6zaWtUGaVI9DND4TR+QGflpVaaXOChu5h0=; b=iwOp7e0ydXxjozO3PHwDbI0WhSbAghVl7xRbfK8qwzdks56mHpQO0j8i0sL7hI7T11 ZGIlP8dgiN71p0gwoHVLKLE810QQo2rAFBWcOd4keCyNhAXWu1gWmVAUziutyrj+ezye ilVCSEtz3LY0csRO8gSV0iHVxLcfUCliheDSpENHDwtitTUfH/WlyH1q9vKl3UkkGwmL pv7F8NGHaYmhVwdKK3sSYJxogjbkqkU1q4qaJZ2jooJhb+wdvgkQUA9fxHO67/l+7YN5 yf2U9WNvZ8DJqAN72zH2UjXxtnBhKlu5bQe1eGzAFxVvmUvaMBWSYbBjz2bbivVA75oL F/3w==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=X+M5ANkB; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77064-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77064-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [147.75.80.249]) by mx.google.com with ESMTPS id b11-20020a056402350b00b00564746e88f9si4065531edd.72.2024.02.22.10.17.36 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Feb 2024 10:17:36 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-77064-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=X+M5ANkB; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77064-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77064-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 0943D1F26BB5 for ; Thu, 22 Feb 2024 18:16:50 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id E63F915B0F9; Thu, 22 Feb 2024 18:14:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="X+M5ANkB" 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 46A9915AAAA; Thu, 22 Feb 2024 18: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=1708625674; cv=none; b=gVnzCdmi/8vKkA9DdZBtPfThwOUIlqgUi+iw8+lrgmVClZSUZN/Cvsy0uTCsRcJ/xxtF0tUO0fvY0Ve8/U+r9sI9f/0CZ42QvcFnvtytH+mnosetnBeeSJtEnlQuBQwWAx8mHY/isx0oAozfOUvv+tzr5MfMSqI7dUCkK4do+TE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708625674; c=relaxed/simple; bh=TPv8mjAc7k5WixCBRXHynM6H/AaB/bUbe1H5MJSrFTQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=b6qHN3zItMNj5J8LKUF/Cz6KMRCc5jUj7qLKst4l0Y9tRjkZIrZmDmls1MrbbqWqWqZ8dcu55CY9TonOXWji3WkdAdrONJDmUSL3D5CQOZEsOardBz4JcXlES5rOCdF3kQnKZMP0YcwQYndNXvy/H4mYNHoKDINY0+UGjoHZpCM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=X+M5ANkB; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 63CADC43399; Thu, 22 Feb 2024 18:14:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1708625673; bh=TPv8mjAc7k5WixCBRXHynM6H/AaB/bUbe1H5MJSrFTQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=X+M5ANkB1G/XImwHDpav6Puqp1tOivphrSFKAYvmOdJchFlHyCPJYfTXMrxPNi+Wo Xi5p2qC9Q92a0AH97//XjY6qjSMO0pzcsMplhKKuHRAp1/CqdU62EflPbnWwI1NHpL iMgRNV2C3AoV7bcRuCBbhihhYOGTyP9b/j9oB/of4n8ncIufeKXgVJXY+fOJF67P7T SP3Ecy3Hpc1uA2/A7mPcdN+szfNbAFddDScakVfzxdnXN0yizutE9sfcQP5w1UuOfO y/MM1ie2l+ekMhxnRguIo1l6hd2rWld2YAFHsP5Yg2I5vyTn100oEuAB6E6Q3s5smY DT1CAmYDF8+JQ== From: Maxime Ripard Date: Thu, 22 Feb 2024 19:13:48 +0100 Subject: [PATCH v7 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: <20240222-kms-hdmi-connector-state-v7-2-8f4af575fce2@kernel.org> References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , Sebastian Wick , =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= , dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-sunxi@lists.linux.dev, Maxime Ripard 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=TPv8mjAc7k5WixCBRXHynM6H/AaB/bUbe1H5MJSrFTQ=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKnX+17F6uVucBPQ2WjBInZLQdLzjvr37ZceBBx8Ei6y/ 9tibRnRjlIWBjEuBlkxRZYYYfMlcadmve5k45sHM4eVCWQIAxenAEzkpyAjw7GvS26/03vapBp3 bfr1pd/XHs1av5C7ZnvFwfhDn96/aFrIyPBO/Z2sBptBi2LkPzHmdT0fdRIXNsttmvNX64XIVPa zbpwA X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791624066527101711 X-GMAIL-MSGID: 1791624066527101711 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 Reviewed-by: Maíra Canal --- 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 Thu Feb 22 18:13:49 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 204941 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:a81b:b0:108:e6aa:91d0 with SMTP id bq27csp122576dyb; Thu, 22 Feb 2024 10:17:42 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCUYAAN/51TowhUerwQ5KvU+ufesiSntKSI9Z0OxSAmu+1m2aIfhMU31Yz6mHGkICMS+TxiIrRq0u9dNLdFnt+Dq4pa7AQ== X-Google-Smtp-Source: AGHT+IEJT/yvCLfHy1cRi3lzygX10VOsHPN3rdF80m3MldKI0qIcfc3G5b3OK1zot3H4MVmgaX6M X-Received: by 2002:a05:6a00:6c95:b0:6e4:6a3f:f065 with SMTP id jc21-20020a056a006c9500b006e46a3ff065mr12562286pfb.10.1708625862024; Thu, 22 Feb 2024 10:17:42 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708625862; cv=pass; d=google.com; s=arc-20160816; b=ntCM0sJtwvgs4c/6QRs5WLf9CG3drH51vOMNoqT/FAbQViJBG0J7bFSB/da9Acqke8 rjthrYtRRhFa0nWmYXQaFtwBfQvPC8HcpA3DnYVB7jh6BD9tZSpNTtw2FIpqqxP+NrCz y+hoYA7sSGRgqdU8o/wTygyqyNeAPLfT4Z9uX62oeAhD5hSKLp1eyAHSxKMM8ejAly/T OvUgwLU76yvCQc3hkj0ysH8OreRQnP0bwvNCnrW6K2uuBSwgudeeDLH/otKtt4GKwxS+ 9H75CRWWEXky7DFVh2ZNL8qiC1OdyZwlqrH/jiQjbagN88zfoerMj8mq2Vz+B/gtk1w1 GI6Q== 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=PnX968uCL3A4UpMj1PEiTX97CKD3pWHCd+e4RNRXo1c=; fh=7mnR4/DMo6zaWtUGaVI9DND4TR+QGflpVaaXOChu5h0=; b=iYRIoRomisNNrWoQPYpaEshciEvIx24Q9uRD3DdCfGiRoxQ2DZN5akDDjUhbJhT1TU Wptgoe7fItEhPeQczmLExba9DsZVJKB35Aksnrf/9337uUkQlyRN1cHoN/XwIZted/qo i3e0RSLFArH7ZEyn0CGMDtSpJt/7xo3Su43GqUD8S+VD0I3wEA3eLgJlQQuS9WqTAcA5 gpoFqGN23nM8UmoXXZpLtRnraD+cLhZ7n/X1saoRCcnIbBRekiNynrwJLRM2sZ5SyldR JrYBUY++kUbxQhLHGrnCFDghDzPGm6G8AxdBDGGCYnTLzsKb9TfvFzHDRCXiEDbGkR7m 9ngg==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=SrhdV9+h; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77066-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77066-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [2604:1380:45e3:2400::1]) by mx.google.com with ESMTPS id 16-20020a056a00071000b006e243cf00ffsi10180498pfl.163.2024.02.22.10.17.41 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Feb 2024 10:17:42 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-77066-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=SrhdV9+h; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77066-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77066-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 21DF5282D1B for ; Thu, 22 Feb 2024 18:17:37 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 7460615B99F; Thu, 22 Feb 2024 18:14:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="SrhdV9+h" 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 325A415B0FD; Thu, 22 Feb 2024 18: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=1708625677; cv=none; b=CTVMfC2nkrOud3wl8npvs0Jh1OYq62VKTFBd3JPS6KtUvsWFI2Wm6Ke9dV1rsLjFKBSxFY+7+RuiERoU4bMED9X+bXNHIigsv5goJoIGdOf4eczCd2tpf2St/bTL3w8/2EEiKDT6UYkECvnVbv2Ct6biQqRTM1RmMnXzV7D8P6k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708625677; c=relaxed/simple; bh=1ZewVq1VdElOMix4yzkeT47wHJmNn7LzalSFh1GQZY4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Mzo+gYDDi5QdmNDvIn/A0VllpshgS07bxEZmbkKbNtb34qenVypIacUa4VHQDaLjXnkRCbOR/rMwpB+uq0PKIHGVipS9Ogs1pZWvesauq8OTRUtHgN3QHZYuh3hRZzM9sKzRUIWiPL+3mg6CsfVOW3mzYXFRHkNDacW+f2qicKk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=SrhdV9+h; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 19E8EC433F1; Thu, 22 Feb 2024 18:14:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1708625676; bh=1ZewVq1VdElOMix4yzkeT47wHJmNn7LzalSFh1GQZY4=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=SrhdV9+hCdPfPtwYyUU3l3UAAq1WLmeEROhir6gx7OZCW57ekMjOBbAWo7CddLsH8 Eate8zXjRdUeiGJN+Bw3e4IPd8blvmkoj4AfBK/RDjsHEof+VgmcgIjOLP9R5Tqhrd RLcUDbF9ZyppCR4JLtaEByZPy8N9JwzamGPDDHIfwSZdFfFeyYItotbqAXZlYEX+w/ Qdy/8/Sg0jcS4vywSVbemRmTKUMNVNIdDRldoFDvN3eJLD66ENbbiSxV9cXNivG/B6 cOCQiHDSUWCHpdcyhl7T+o/bF/ce6njxHsbMDImDHl34Q3pouA7gFdS3St9SNlMJWh G1puVZd4YnR2A== From: Maxime Ripard Date: Thu, 22 Feb 2024 19:13:49 +0100 Subject: [PATCH v7 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: <20240222-kms-hdmi-connector-state-v7-3-8f4af575fce2@kernel.org> References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , Sebastian Wick , =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= , dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-sunxi@lists.linux.dev, Maxime Ripard 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=1ZewVq1VdElOMix4yzkeT47wHJmNn7LzalSFh1GQZY4=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKnX+17p6G/lCz0rHHfk5FpdgRMGu30O/a7g+y14M0Osw uGurGRqRykLgxgXg6yYIkuMsPmSuFOzXney8c2DmcPKBDKEgYtTACay6A7DXwF57o3CmhM7kv+y WvHyx1xexVdyT2pN4fHvoUumeLdVyDMyTFjxm+FBdDvbjb3P2GS9pt5kvzVT5ebBP8+7fpgIWs2 9yAkA X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791624071897722109 X-GMAIL-MSGID: 1791624071897722109 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 Reviewed-by: Maíra Canal --- 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 Thu Feb 22 18:13:50 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 204943 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:a81b:b0:108:e6aa:91d0 with SMTP id bq27csp123028dyb; Thu, 22 Feb 2024 10:18:19 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCVIcjo/+ffqm9IS4XJf31HTcr3SJ+MlGl9XMZyqK6GkB9VDoQTjwkKpHfXHMmdxiCY/i5YGziH+NXItpDg6QJxA4deONA== X-Google-Smtp-Source: AGHT+IGqyBgjv0ku5KUlzP+eusDfUFUZ5lcemjgpZxaOmDyqDNyqBlMV4NIqTGda/IslmAj2pzo+ X-Received: by 2002:a0c:a692:0:b0:68f:7b19:675d with SMTP id t18-20020a0ca692000000b0068f7b19675dmr10708836qva.3.1708625899418; Thu, 22 Feb 2024 10:18:19 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708625899; cv=pass; d=google.com; s=arc-20160816; b=bf9CHH0uMw7xA4930R00yYhXqWKcTFxaIe75GV8HUdLGKUvZkWwznn0SQoeIRF1CH9 mWe24t9mE6T+Ckeze0kP0/O/m4+Mwr+sby3M/ykrXjnQZn74Ae8KJbkK/I4gcQaGR5jP a5NtDO/uShIhRhQEfYkxXWiNvBDOMNwWYpp/iIEjBxreA8J9aW1fkCAfaAO1olppRSdp ZYwU5EqRNZAhml3tO1BaAv71/t6cBa8Q9VtkTYOH50azXiafKMI4wG4zHG9doPYg8T+i cL1mXaBf6RLoVkHuA8Y7trTYVYKZuKqT8wcXfQ6lD7fQOK2Uf+Ly4xsNatb75kZS54Ma zDqQ== 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=NyM5WwLHCQ8kcNNuykIG0lYgEGjrMzTAcwMIS0N2Ln4=; fh=7mnR4/DMo6zaWtUGaVI9DND4TR+QGflpVaaXOChu5h0=; b=lvRB8SpiNVQoWUbRgW8LC+CcrR3PiJm37xfFfWn7eSKSX1YBpWG1Rt6T4AYivqeFPG bCiwaVcMkjiXUKmhR0LEuLvjlNoqARhd1bp/JbRWxWgY8xTkau3D0iQad5xvTnjqosU9 AefZ0P33vitZJXDRByzCsoUFSzGaVjwApSHcSiMkciNKRjkpwefWiDI0hzKMYzl30cm6 VmZg+OpM2ym/nx7pLYkum6OMf+4bZofqrmWBAZOeXClmT902FssfeX8BqURvuh7O2WO4 LyEHFbsp/s7I2ogpvSB6Q1kFruuOkGkJIfwCSVJ7d3b8rp9A39fZlF04iq8N+g6USR5S uXXw==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=VTou2p8d; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77069-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77069-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [147.75.199.223]) by mx.google.com with ESMTPS id s7-20020a0562140ca700b0068cc3b0f1e4si13375735qvs.411.2024.02.22.10.18.19 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Feb 2024 10:18:19 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-77069-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=VTou2p8d; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77069-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77069-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 DD23A1C229E9 for ; Thu, 22 Feb 2024 18:18:18 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 45BBC1586E5; Thu, 22 Feb 2024 18:14:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="VTou2p8d" 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 3328615B992; Thu, 22 Feb 2024 18:14:39 +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=1708625680; cv=none; b=TXINuz4G4xp/cZrDtc8cEmZUwIg43MnOpU4fHhNStd5VYsDWqFXqeAHvC5Tia6cp3FzKAM8KZGs0NG5at4QVlo8uQbFWMVoN1xUtcnyMRRseqLEqXpFyaqVLqDfHS9/r41brm93ZAIsiL1D0JBysHmeWb78fxTy5zZVAxi+zGRk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708625680; c=relaxed/simple; bh=+carovPUcrljcpRVv3z7gkTq0nha5XSrXPMvLfHaNxg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=sZTXZFgiVV/HYcEcrcvkp8caIodlTzMaqGNw0rNujxRH/r4eF4z4rTzin4nXnK99VJeGuHtQSbuNe9TJYNmkcPlG1Gg7ncoY5jNiUIn/wvgXwgLqulPo4ByAXt9eab+r9papuraCUWgMm4TpxwhwXETS4PMNBilRA474ySXFPu0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=VTou2p8d; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5BDDCC433C7; Thu, 22 Feb 2024 18:14:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1708625679; bh=+carovPUcrljcpRVv3z7gkTq0nha5XSrXPMvLfHaNxg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=VTou2p8d5pbdwCO+Z3GcUPUivBLpLhufXqW8+OuEelivIxPbghA+PYfDssNS9cQvW PzMNpHlt7W84SRvfR1YIr4O2j+HqmAPo0Xy/THcrFGkxc4QNIhVVzK+ULkmExuWVnN obPiBogyAuxx+aVMYoDnUETyR4nYjfrKXkC00K5qfvTLdsuAp9XkKRVs57Blyhm1op +fPF6SEw4ku8nyTrYEM3i562cf0WmT530YbXaneZbD8XEI4EzBTb253/RMOcVZus76 N+XSHhummEb3AUf3ZgmWC6x1/9/QBgmkeMxFamaU+YuoIU+Wrue7QoWG6gcqf0l3Ys oUTXxM3hfiMAg== From: Maxime Ripard Date: Thu, 22 Feb 2024 19:13:50 +0100 Subject: [PATCH v7 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: <20240222-kms-hdmi-connector-state-v7-4-8f4af575fce2@kernel.org> References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , Sebastian Wick , =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= , dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-sunxi@lists.linux.dev, Maxime Ripard 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=+carovPUcrljcpRVv3z7gkTq0nha5XSrXPMvLfHaNxg=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKnX+16XHBar+OE7IWvpjKy0Y49FT84w9d/UVemtuWmGb lbNOZHnHaUsDGJcDLJiiiwxwuZL4k7Net3JxjcPZg4rE8gQBi5OAZjI3zZGhgcLp77/cPPhwsA/ 5nWW8+c+jzRTm/1ljU73On4Xiw+Cp94yMmxf2JHh+i8td3ZH3d2HKjOSLVO1A0QbvZu0Oa50fTc r5wAA X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791624110953018784 X-GMAIL-MSGID: 1791624110953018784 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 Reviewed-by: Maíra Canal --- 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 Thu Feb 22 18:13:51 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 204945 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:a81b:b0:108:e6aa:91d0 with SMTP id bq27csp123574dyb; Thu, 22 Feb 2024 10:19:02 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCXM2ZpsFKONauFOUYj4iwyKevxDSevskjjxjkQApt7GLBl5C3xWgZl4+HCdx4SGEOm2AiQ+ex6tCHOp6OuQ4EidOnQClg== X-Google-Smtp-Source: AGHT+IELsZj0x/70blujoDz3q7n4aappBjIsPCAThbHEkwT+UzJ7nm4/TpnF/IJwEstX6446MopB X-Received: by 2002:a25:7903:0:b0:dc7:3165:2db1 with SMTP id u3-20020a257903000000b00dc731652db1mr3002498ybc.49.1708625941912; Thu, 22 Feb 2024 10:19:01 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708625941; cv=pass; d=google.com; s=arc-20160816; b=kZEc7EmGhbsywe2nWbOVVfDua5oYK7Xv4JF0OVWLYNl/uMR5W9I1enWwRplzNynV76 ErQKcAL2sSUFOWgmbgAlwbRB4/aTilCoQmxexDXPXwqn5u8Qdqzct/k3HgWeCCjk6AbR w8Zho7esMHgG6iQREURF9iIhkCdz/ikwjpymyR2mmy90rNfmRXVgpFZK/DX2XRUqf+5r GdiDtFClLvo646GLaIFxzHvbP0ATopen45FuWs7j30s48OQGa4p0Y6YtfZDW/qkWzahu zYvkfUxeFJPeA1DLAJvqD7y32MxZdCHD0milOlJ3b+7hAgo1tWC2PHaN3TWYyBGadbOJ 5TZw== 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=ZxYKgETjTQKKiJVl7CnttRo2Ctq/C9ls9VGtsqIbLZU=; fh=7mnR4/DMo6zaWtUGaVI9DND4TR+QGflpVaaXOChu5h0=; b=xUbXbv8yiYBq2fdnuewXrz2cb3Fh2uBOxgvyISwIB4XRJjyz4SEP7wipMMA1rKLR8g doIpX4/HwhGuWHnt0ilY9wAdgCx96pT8EmgLPXy2hYp37F6Tj1hKAX74Zj/0JR/pPP2o TQ1LgrUHRSqLahvJpg61dY1xSgXdZEMIfyftQKrTlCVusCo9K0TShL8UdcziuptnZ8lE 7sBXBK6tKl6OfgfE1mSY+EOnVn+qjOvZeO23u24de0V8PfpHMGFfLfL++Yo6j+O8MZ3/ eaQ+DOhrq59Ic5hqub9FoMLJCpspcFYU1IKgW16neDwxGK1UOQlwH/zsR+X1jgskVAYU fvFA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=jfIZQKjx; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77072-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77072-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [147.75.199.223]) by mx.google.com with ESMTPS id v11-20020a05620a440b00b00787953a68e6si2907461qkp.30.2024.02.22.10.19.01 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Feb 2024 10:19:01 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-77072-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=jfIZQKjx; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77072-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77072-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 A0E8D1C214F4 for ; Thu, 22 Feb 2024 18:19:01 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 758F315E5A1; Thu, 22 Feb 2024 18:14:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="jfIZQKjx" 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 2417215D5AF; Thu, 22 Feb 2024 18:14:42 +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=1708625683; cv=none; b=R19ila7JUIkbhot9ASj+ma8iTOhgDU8FV8wXeVq8N+ffAgeJ+qViwl+rFegdTdYzEnEM1pYuA2gkdDYBXMVIBF7SLvNtVzroHDhs//mVvtwV2FKBvEYfqCwOXKFZ3mgL8dQL9nZK3KC702NG1oXjVpU9An2aNZUCyGzI1DNGwRY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708625683; c=relaxed/simple; bh=CpWPwPjnSG0Utx4KGltVz+v8L6+sya4K3NyhwxON/7g=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=tnxWs4CF4BbCJ1+IfKpFS0bH1NFNGw17gc/OfEnNvnSW2ImLbdjzYamNUjtWajCB8/k93YuzBZBpXFOTxhAqfK1uGo35BF9GsD9Mr130TnNtLscBNEfRWEVhkPxCFnZL9QnOE2KG3/p0ihw60Wm5RRE/Yl8xM8bR3WepM+TFD0k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=jfIZQKjx; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3786FC43399; Thu, 22 Feb 2024 18:14:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1708625682; bh=CpWPwPjnSG0Utx4KGltVz+v8L6+sya4K3NyhwxON/7g=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=jfIZQKjxM+/Wb0t5zKKKALeXw/nhaRsVzBRU6GZk8FyDmQaShLaE6WtdGTg2RAoaW d/Cs1GCNAsrMTzbk+rsivGwPHkHU/tZYoCmqSYuGqGObO2TFm7hYtDVfeFtu2avs2h wyBG274/LogrYE6wFA+SdpvLSWhPWpYieAKIXvKE5V/eXEzHQX/YEE9sRC+Qekz5jR X2olI5f/QaOGaxFgqcSwtSw4YvJ6kxR2yEMlCLx308/KnVMI3E6MsLKG1TWZDNWpIU ej6WPth/zz/X2SZyp2I0JWf3tIKolg93mD+4oucb6v858BUqYZ9fG+Lsp+n/6j4LcA ImfzNNuh9cnAQ== From: Maxime Ripard Date: Thu, 22 Feb 2024 19:13:51 +0100 Subject: [PATCH v7 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: <20240222-kms-hdmi-connector-state-v7-5-8f4af575fce2@kernel.org> References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , Sebastian Wick , =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= , dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-sunxi@lists.linux.dev, Maxime Ripard 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=CpWPwPjnSG0Utx4KGltVz+v8L6+sya4K3NyhwxON/7g=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKnX+97YfJyb9Pnqp/ivArO2POGYBZSwZ3jcGb9tX/paa 7/Xfz93lLIwiHExyIopssQImy+JOzXrdScb3zyYOaxMIEMYuDgFYCLKGxgZHq5vX97Zs0oy/aGb e9/hNTtr7s5qcSi22ev6PFgl+nOrE8M/DfFEs9ktK9mXLnuYFT9P9Hh+7FbZi3GenYITb9RvCap nAwA= X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791624155606518496 X-GMAIL-MSGID: 1791624155606518496 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 Reviewed-by: Maíra Canal --- 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 Thu Feb 22 18:13:52 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 204947 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:a81b:b0:108:e6aa:91d0 with SMTP id bq27csp123961dyb; Thu, 22 Feb 2024 10:19:39 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCW+bAQuH8U7FiuF+q0ayj5yG6VbqCZ1vt5k/iDbk5xu4F+Y5JtXHtCC0F5dbeDXcHoHq78CYFc9RSIxRwXpooDygtA0eA== X-Google-Smtp-Source: AGHT+IE5e+1Gh+6b2ZhsC/971QgaOg+KFq4T5h9pqImjCpJMf+Vou88I1FWHN9xrfbM7RW1CGGQd X-Received: by 2002:a17:906:490d:b0:a3f:9c9e:d8d4 with SMTP id b13-20020a170906490d00b00a3f9c9ed8d4mr1291087ejq.65.1708625978938; Thu, 22 Feb 2024 10:19:38 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708625978; cv=pass; d=google.com; s=arc-20160816; b=t4H8QD59KS7QTtZNuHBcQvyycFUYUED6rVcr3BgwEGJchylep3Tk/QCpGfPgePANOG uPAfTxFaLsFg/rqkNmR/mx0UTg0LYhEEmpIqvFistWPnpBoAGQlcquYjiYfikSsSZ4lK W/dE1adV1ghYu9O0mMA3P5Ng9AmRXBYyvazglvRwOrkx7EQCjejt6Wt2kWq5QCQ/k5nf NwYmevrSScLqL4hlRvPf4h4MVKoFtzfFRsexXn8RXsDJkoNQiiU5ppi/zjopbjMeAW81 tkv4pSgofAUXb1zq+zmwDtyHefhRuaPEdD8vAgVB7op9DxYVnV5JeIoQzPAWdxe8QtHz nflQ== 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=k61gKP/GU5M4u3BYV1ZwK5qDDzVZ12zrM86wbSr399E=; fh=8wcoxKk21hICD+6obVirG13fsSSMhKa/pufykSf87d0=; b=EjzvK4hHrHYP7JN5Cu/b+3w5DPe5Trb2eSbqHXqDC5n2FILOOJKy/VkSFgku/AweCC MNd+D/zisAW62cxStNZ0Sp3w4SHqRz9i3wopRadVFjxFtfmNAGX+i+Vqk/dD9+DmiC54 2Y2FSnuWPUljQwW6W8QTDv97p9zpL6JnUgYHhYAG4tLpQ8FnVWPeez42UwZqF3br7taS BW7hDFM/zSGx7d4oyTVu3c7wcgj4edRi61HA8BMGQTDqA2lm3GOLF/Pu/baS7EMjCKEA Mlff+61pWWOxQvV8UEjqQfd1XXbXkwf3OaVEJidsNwIQ2m+z26m2sif5rbqNdWNwW3rR Axsw==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=jg4vLAoD; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77074-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77074-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [147.75.80.249]) by mx.google.com with ESMTPS id u23-20020a170906409700b00a3e7ca7d7afsi4327545ejj.7.2024.02.22.10.19.38 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Feb 2024 10:19:38 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-77074-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=jg4vLAoD; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77074-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77074-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 89EA01F2185E for ; Thu, 22 Feb 2024 18:19:38 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 707A615F309; Thu, 22 Feb 2024 18:14:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="jg4vLAoD" 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 690AD15DBA8; Thu, 22 Feb 2024 18:14: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=1708625686; cv=none; b=Ip+u2LxmKwaQnTqNtUhZ+qfERfEWX2TuX3YS+utCIT1VGNOARbxrBIAvK+/BJOm7xD7wNQcAMz6ycaXHC1XE2weWHQUCkH1aOwVsYWAiRIJgIC5mXDSeXj3f7G71bmOz/Frrt+wRnpwVNNRIb+p68HVuLtKFtKO0rCo+0B02N/0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708625686; c=relaxed/simple; bh=EOzt+ac2VEJaQqn9R1VvC99pxlRc+ECtg0akisOt/iA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=a7Ubeu8N9sTo7kOp02x7vF+1exnd85d3jaGxV8wYlBpsiKWh4iYe2OcrjqolTWp5E+8QmiBFlDGaOqIl/4tdJW3AciYZfQVtQ9tOo4iwN90uF2O68bvb2iB86tx+RwXNHHkatfTgqqYEnRXveQVP81dukG8UB/oAFt1k34Og6Wg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=jg4vLAoD; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 372AEC43394; Thu, 22 Feb 2024 18:14:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1708625685; bh=EOzt+ac2VEJaQqn9R1VvC99pxlRc+ECtg0akisOt/iA=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=jg4vLAoD48Wz7hB8s5/0/Sss0B/uk45kUvfboV7jl/D62+lk0azLcJ6zaSfB7HVL9 gqLKSYCj3xaNLzkzZ21bqX6Xqcpp59qHjbnNRbqXe4ruwVOwle/daMjCZDjg37bkP4 KDMCgcjQq8BTujHwJ+fCYK2aLz8myVFAtMMVF550zCCIoopvo16D289iZyTl8+T+0G xIZ1y42lsKQV1cXJ89+W3eI/Xy6I234EcSTCyM7Yn+itgcJICg3cxD8/JKWTJC07LD PCh44uOgr45RxCtWbs6hKSA6yUaafMBrjHpCEIU+Of13lisEOPcMe4olA2RINelJPZ SWq0rnNHXQOsw== From: Maxime Ripard Date: Thu, 22 Feb 2024 19:13:52 +0100 Subject: [PATCH v7 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: <20240222-kms-hdmi-connector-state-v7-6-8f4af575fce2@kernel.org> References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , Sebastian Wick , =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= , dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-sunxi@lists.linux.dev, Maxime Ripard , Dave Stevenson X-Mailer: b4 0.12.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=3492; i=mripard@kernel.org; h=from:subject:message-id; bh=EOzt+ac2VEJaQqn9R1VvC99pxlRc+ECtg0akisOt/iA=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKnX+96szVkkWKki//xdjn9O5bUD/tP7svViHpnrWOT07 kzo2mLcUcrCIMbFICumyBIjbL4k7tSs151sfPNg5rAygQxh4OIUgImkGDIynIyVjJGWcA8TvXl+ h0PHnCfnVa7t/vJ/w/eNn5z/L55nvZGRYc6d2L0vfOXX7Sp40rTwteRtoXm3Vc8FXPzLOPn4hsY pqawA X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791624194961329149 X-GMAIL-MSGID: 1791624194961329149 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 Thu Feb 22 18:13: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: 204948 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:a81b:b0:108:e6aa:91d0 with SMTP id bq27csp124481dyb; Thu, 22 Feb 2024 10:20:24 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCXzQR/ALmWdeNsAA7jkGKlOxyyfuc5fgKc1Fy1Uots66k+dEsZ7PGsds3w0hUs2MOO/s5V0Fyc0qFipVS2WsVfq0ZqFfA== X-Google-Smtp-Source: AGHT+IGNsYZiEawnlLnK6Ho+/zJHf24Vrgr3wNT+AXxZLS+P/43Wsbq+zgL/qVzyLevIJmkT6df2 X-Received: by 2002:a05:6a21:1788:b0:1a0:ddbb:75f with SMTP id nx8-20020a056a21178800b001a0ddbb075fmr815704pzb.2.1708626023831; Thu, 22 Feb 2024 10:20:23 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708626023; cv=pass; d=google.com; s=arc-20160816; b=vZ112oBw1fbxRcnuly4PvAVTC3Cf98KsChYWF0EGkkhCbRQ5kiWzEBxxeDWWZPUa1P DE8a7RUckSdKtciPPoDQW75SwoS95UTgIpxZuxq5Q/YDTFrAL5Wfb9svVOQI5CFoYfLW Pxh97Y+juWgvKtEEEmRU41QfqqSTztdewvOsnBNiHS6jE1eKxowAA46+7+BTNNc2GkvZ tMcVNS3Ar9AtYT1bKd0cLqPFqIpZxIlrlcqgN9aVz9VNcB89llLR3/YKEavItlKjj97R KX7Y7i7KdEsSz8xNRTDLrovkYijCXrdQSH1cUvQ1/QGabn5GI+CKna/EyWkojB2gBs+4 pSgg== 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=/g0uBO0LG+TGLa9P6ILFpKyw+iTt81TCRIuyctMLaMg=; fh=8wcoxKk21hICD+6obVirG13fsSSMhKa/pufykSf87d0=; b=FHO2NFzOJwgIZq7CcuKswp2r9c6C2fbKRxvNsHpyMwMSJ++TyDdlmznYknnD4Dv/OC BiMsF+BB5S3ozpu2EKps/42n/8HGE9N+XPk321+CT/mkIJ3xmHFTmAZyVDtN8m/fRJkz rLiAm12NZTYS+DFuI/kF6e+4e5OUAUlCuUvifVVNqQaY6fHZvLSHcehn3YtQRqziF5bH kEOjiM1ntjKCUMy2a+G1wQ20LfLhMXewhBPk6ctOU7CEq58YLuzMeQNEYOtKNLljSmAH a3qiQTK5XAut+TAaecdL8jUj0KuTie4BOSdsMDcFDPy+V8oD1PKAf7b/GEC+FeK5Yn3r ozcw==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b="ZsBjIOY/"; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77076-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77076-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [139.178.88.99]) by mx.google.com with ESMTPS id s28-20020a63925c000000b005dc855c40a4si10784020pgn.645.2024.02.22.10.20.23 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Feb 2024 10:20:23 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-77076-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="ZsBjIOY/"; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77076-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77076-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 95DE1283CC1 for ; Thu, 22 Feb 2024 18:20:13 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 06443163A89; Thu, 22 Feb 2024 18:14:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="ZsBjIOY/" 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 C77EE15E5D0; Thu, 22 Feb 2024 18:14: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=1708625688; cv=none; b=lskR57LtLHufl8A/CYXt5v2IzxysP8VZdZ8gB4gcJ3skZTQqLt9fEDZp3ZNGsteUW9Fk73a2oqMl7KxArF25GSLIEm/YfT1wUGKcJewxoFVpjFI87Yx/kwb5La4oQRMMyZMsDrjkssvAuGGQyvtNcslYD1psMQv1NHijSLolTMc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708625688; c=relaxed/simple; bh=aMMsGSd3iTeiTa5R3x1EcUbWFB61oRzNzaAaKePtu+0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=tiF8UfFvCWp/xsSzGTyqpX8/Zpbk/StW8EKUHlJ2qJ3H3c7m/vIK3ga+pTsTXPcG/W0DridFWpteTAnpHY6F6EInCs4msJHtI6Z9jPew0CM3j1y+5cmrcYyByN6TWU/oeKf31fcl+mUcOpOYkIkHhaW/oz9P4jsyZfq2AWJFEtk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ZsBjIOY/; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id EBE5AC43399; Thu, 22 Feb 2024 18:14:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1708625688; bh=aMMsGSd3iTeiTa5R3x1EcUbWFB61oRzNzaAaKePtu+0=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=ZsBjIOY/uJP7kxAZQ6u7lhEhsV0Xt6R0OdKFwHcru2XK0hGXZxupuxo2jmRd9rHMb 5KzeNNmy0pX/XWKuPQkvqa90l7bu3xUruGKqWRMKDmrArG736LXsw/TSFI0q0hN/8D iNoLNA9X2P7f9K5CvAchb8T+kxUoWoND9tBuUN8zHui17Sc6uhKYeWUbeeSGWn/JsX qZNHnx/1hxCoRMKowH8VbvZfQyEVVHKy0FPm7zktJYKgmZVqMMMEADP0pWzsq8cvBB sfD0q+fbNlaAMxr2+hEQz+ItZvhhv070Y2Z1QwshkFpYWOvt9de9kKKegFRlYPJrxk qhtgYOZ52yDLw== From: Maxime Ripard Date: Thu, 22 Feb 2024 19:13:53 +0100 Subject: [PATCH v7 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: <20240222-kms-hdmi-connector-state-v7-7-8f4af575fce2@kernel.org> References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , Sebastian Wick , =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= , dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-sunxi@lists.linux.dev, Maxime Ripard , Dave Stevenson X-Mailer: b4 0.12.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=4892; i=mripard@kernel.org; h=from:subject:message-id; bh=aMMsGSd3iTeiTa5R3x1EcUbWFB61oRzNzaAaKePtu+0=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKnX+97GSvXVP1eaYbtU+85vvdV15+3aToe+Of9I6MLyL y/slFN4OkpZGMS4GGTFFFlihM2XxJ2a9bqTjW8ezBxWJpAhDFycAjCRU8IM/4umBEf4RChuLeRm WyMceeLJlCuWQToLN3IKcn4v93+mlM/w36NsaqZYWZ7+IvY3bYLLH7THlpwsVT9wv9GFV8/kxpo 8PgA= X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791624241386497078 X-GMAIL-MSGID: 1791624241386497078 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 Thu Feb 22 18:13: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: 204950 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:a81b:b0:108:e6aa:91d0 with SMTP id bq27csp124733dyb; Thu, 22 Feb 2024 10:20:44 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCWxNlCvFpHXqR/zAqf3P0BoadxbbfLIwyUt2cbExht1VgUcRmyk8jnSJFG6X1m24U5VR9g50uTWZuW6x30cNS8FXigzQQ== X-Google-Smtp-Source: AGHT+IHYIirmc67YMgaT5Ln77UV5ExJiyKqkLrshObAYosHLkFGwXdKs2Qg9f4DR89e1TzP6eAdR X-Received: by 2002:a17:90a:ff15:b0:299:63cf:4cfb with SMTP id ce21-20020a17090aff1500b0029963cf4cfbmr11497746pjb.1.1708626043957; Thu, 22 Feb 2024 10:20:43 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708626043; cv=pass; d=google.com; s=arc-20160816; b=Mb1uCnfHs9TIAQ7YvYBnU0t5dcVoxvSlJGVBUgVcC9hDmfHXXoQX/q05tkC5sPnhZg Qscl1o4aB4jGHW+l3UnRIyLw5+JEKbW5rG7dE908I87N7HSCn8ghkBpEhtEBPvPfi5sh IiezmL6qJFH3pq5ujylkPIO8z/VCoJrsCI/0Qtu/uZW9e6ftvTXOIvQEfb0fQ1Xqcv/L 2qPb6deQbGD3Pzk1tBKUouDj4NBJzAGvy7s5GwQ/hOwj8c/NbLqjndgmnhH9QVEE725U RgLx4nbvWURpZJCd4hNJqPk601b/DEtns8XOOy3svEyrOObrlSt4PwCJL6DOiM/sSs8w 4Nhg== 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=dVJUyGsT9fgyDE15RLqQu2zYooaguPtq+TCmSztn/KE=; fh=8wcoxKk21hICD+6obVirG13fsSSMhKa/pufykSf87d0=; b=LbL7Vfp/z9ed2LorIGIX1fp4je/O9O9U+BqtjUiMzmI4tk3HtW6uXjBc56nkgXpC53 zX8xAjUthGifgy4cPcXUYejqrPNr3bekL4yoFqgvkLxDfud2h1HxnA1aMthTI676fTJL /sbkyeDieJuAb0uYTRvqOIJXnvFTcbQXCX8YpmXqpXH47kLiuZCwoaS6llMuAKzvkGF3 /dorzfWUV74zgI5QC5K5J7eULQtgC3PfUnQQZWl3o5MlV+0Oxsc0Cx+1gaG1JWx8dEna QjVayP7/2KlyGCrbQVMGip+CKP6kMRz5oBmT7L1fuZeg1teXOKgm0tTtO6or/cOjskXZ VwUQ==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b="HwC0Q/lZ"; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77079-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77079-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [139.178.88.99]) by mx.google.com with ESMTPS id y8-20020a17090a784800b002993349c774si3994853pjl.113.2024.02.22.10.20.43 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Feb 2024 10:20:43 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-77079-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="HwC0Q/lZ"; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77079-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77079-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 BE8DB281950 for ; Thu, 22 Feb 2024 18:20:43 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 6E38E548F3; Thu, 22 Feb 2024 18:14:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="HwC0Q/lZ" 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 56A9A15DBC7; Thu, 22 Feb 2024 18:14: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=1708625691; cv=none; b=YNVGZrN5dAiufydCBL5hnuaDRl9GUAsE6TcQRTC7aCdOLG5aYXg/FrpxbcT5Fkxo8MVU8mtOqL0Vwx7TgdKZDuJxuDQvviDT7FAknt/SW3BCZmg8CFdYEKdXvfua/aX5F6tKeW6BLGU2rfXExcQqZ221LPZVmqiOELIdKhA6sK0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708625691; c=relaxed/simple; bh=dIHdoNoMMYJJWCyQW9ADJIPyW+T8ZvZzWQOUCZiYfEQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=YMHTmYVNUDp8IF/hkXTh69gHc92qV0ND643YUCWmTQ0FnGjPw2Qex+T/ynPJeSMLOCAmKAzttm54EDjwhrAjljzQGZV9lhpFRviuByJjvnIgRDa6ddkuwRLAjeMySM69JQsYa8jczNGLFq9OCN4sl/dJXkR37rQzTPlZ7vkiiiE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=HwC0Q/lZ; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id A58DAC43390; Thu, 22 Feb 2024 18:14:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1708625691; bh=dIHdoNoMMYJJWCyQW9ADJIPyW+T8ZvZzWQOUCZiYfEQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=HwC0Q/lZEjQ3YqAzTLwrczFmYfdq8ge73ARsPl1kYq0atRkSuUHeMnkXhaNKO+Wm+ /Zm4LZIC9PLvgQzpLgpmvjmnSEBojMf51CCVmmBoZvW23V5W7ryI8qCMchIloBl9tD e/h+xfcNdl7i5XnfbLKc54rVrCmptYUTzC1UiB/GeDdXNdXSw1OIog5q34xYmrkyJa 2YQZtdXvKQribnPtSpLzBS1TwHJ9yM9hSGMkoFv9KSnyncaFsQJEeMhb5SML+9xqfF Vv70bXiS/oKlKOYNobrZZS9G4x40SM9xWa8xtTIBXp1IJNx6VvwLq2S5C1szNg0xdT Et6Dcy4NBac3g== From: Maxime Ripard Date: Thu, 22 Feb 2024 19:13:54 +0100 Subject: [PATCH v7 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: <20240222-kms-hdmi-connector-state-v7-8-8f4af575fce2@kernel.org> References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , Sebastian Wick , =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= , dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-sunxi@lists.linux.dev, Maxime Ripard , Dave Stevenson X-Mailer: b4 0.12.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=4256; i=mripard@kernel.org; h=from:subject:message-id; bh=dIHdoNoMMYJJWCyQW9ADJIPyW+T8ZvZzWQOUCZiYfEQ=; b=kA0DAAoW4+8Nb2cYUcUByyZiAGXXju7IbNNjjO09fnav5cAV9V6W3b1QeU5yob2RoehN5JTRy 4h1BAAWCgAdFiEEXBM3pF7KmuuJBg6e4+8Nb2cYUcUFAmXXju4ACgkQ4+8Nb2cYUcUaBAD7BWDD jOrbPJYJ24RkduFyarqX48f+aoSKn2IGT0fNcvwA/RV6Mbbi89dJA/lIu1FpOW+hUMgiox8t/0U b63z/kP8B X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791624262651147225 X-GMAIL-MSGID: 1791624262651147225 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 Thu Feb 22 18:13: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: 204976 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:a81b:b0:108:e6aa:91d0 with SMTP id bq27csp130019dyb; Thu, 22 Feb 2024 10:29:56 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCVvqDzOoVQh5CgRbkm3BGQ5di68y1oKQ8+3gQVKumVcO28kMnS5HhbS8wRFY35TH+mEYlyAkwK2HHMylGtHuU4bxhPqYQ== X-Google-Smtp-Source: AGHT+IGo8bFYz39gcYkHYgkz/kumxpO8mkq+obS1cwM/nqw3w7KNKegRuhrw7nwc+6xIoADnbThW X-Received: by 2002:a17:90b:2243:b0:29a:6b65:3e86 with SMTP id hk3-20020a17090b224300b0029a6b653e86mr641706pjb.17.1708626596347; Thu, 22 Feb 2024 10:29:56 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708626596; cv=pass; d=google.com; s=arc-20160816; b=CUC5z1aMOBTeq0nhQV7YKvcdI2L6Y7l/HSb2JeQubN5NTnC3jelzbF4ww0z7LQRCmn kBiXunkNi5NvYD8UaKewK3PqZTTgcHqzsbL3zCaA/qC5Fo6AIxuhgdx2mOXgaEDgelBT NNDBcqKfXv/nY4OUP+jCkV7BIvYnX/voVjssyb/zA8Hop0AN4nQ0kA5kXSXrxyfDN09c wmeHAy/eFX+1EiCQVw3DS9ra3K70cy1mG7iZ9gWFb9aWqXRncdITVXtnCYlIPLZhqSQM bgtzmz31mj/jIF8anMSluSzNi0bCV/WrimZaoRHuUgwOud382+NRJ9NIfOybAASxaLY7 2tgg== 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=fLKeVAr2dk6pbz0au6ltyMpszNJ95+isirPVuX+EgRo=; fh=8wcoxKk21hICD+6obVirG13fsSSMhKa/pufykSf87d0=; b=qyVTH+QLVmE2MaqUEJByNCZtNrmHTDpvFjS2kPoUqDcCAluSr6GpNm+bvXb3Pn6faH pU8/ozEwqu1sug9lestUFpXiwPQTm8R3uGvd0CrSPxfhSZLENabbeLVpEbIrbdB+5duw r8wjzF6QfpbvBLjzLSm0Fr18SJlIEa8oJL8er2ri6r5VAxxZ1mL4S4JanMMFvmmxSb4X 1D7ArewAPnfEIIrvoh9pmwkyz1FXnalkEAgcTzbPTI9n5bSwfMntJp1NK1nJJO9cZ3Gm N4FRoVClU3cV9Qr2X0YgeifB1wDvH8w6R+8dFoTqWo4mlB8/APfYmqqjL1jypY6nf/DT i79g==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=KbCrI6L1; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77080-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:40f1:3f00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77080-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from sy.mirrors.kernel.org (sy.mirrors.kernel.org. [2604:1380:40f1:3f00::1]) by mx.google.com with ESMTPS id a8-20020a17090acb8800b002993602c9c8si4032303pju.68.2024.02.22.10.29.55 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Feb 2024 10:29:56 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-77080-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=KbCrI6L1; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77080-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:40f1:3f00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77080-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 B5D9AB22E51 for ; Thu, 22 Feb 2024 18:21:32 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id C24B66AFB9; Thu, 22 Feb 2024 18:14:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="KbCrI6L1" 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 7E42915E5C3; Thu, 22 Feb 2024 18: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=1708625694; cv=none; b=R0GqsT/CVxmtgz/vT5MtAKnk8sUFrLQ672+BryJFUXRkRvb7ylK7MhhfPijNgOm+YggVKxM8VCrs9xywlx4pfoc29UmOHJoA1wQwOwfRcMRZ7uu7x5vAecMNzvY/Ncpr6npxcttkubLoE3WHMR/DONC1bDe3PfQ8Iby6RKGoP/c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708625694; c=relaxed/simple; bh=pSNXmp0c3bxRBDh2tzEv2eshg+rV1t1u/wJNsU+JbLE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ICIxrgnyWYSs6+Fx+YQwlz4Wzvv8jGJScdaGYPQ1l6jVAKVmWojGWsfCp9eaCL3ReKLmybvLNZGUdGJY6gZPdk7yVetGL+piVFViGXDBKHy7sghh6ikhPE3SlIkWjfTPwx/J6fpriees1eKxZROc1xLlMjPFsIrOFmY2T1inSQg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=KbCrI6L1; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id AB444C43399; Thu, 22 Feb 2024 18:14:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1708625694; bh=pSNXmp0c3bxRBDh2tzEv2eshg+rV1t1u/wJNsU+JbLE=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=KbCrI6L1xZOKL9hHVVKrlVdFJTXH5iTlEvwUTJAtgDU+crqujjOdDgdB++PBFSny1 CkHjIOeAh5NyPaegeAvZw/XvJRUIrBnVk81k3BOTP4L4w3ye7fWfJuTFKPybuglv5z vd5/sas316sT8eYCEC/KFN6ocZB+d5hblXsQvi7rlbCqo5G5R7tFkCM+X6feCLp+++ D7h0Nw6Q3QBoFU9KsYBIUEKaYv86i28yzXdVE8Gng9xIqRD76oVN27SQpWCuRoQS6D +kD9DEd6wcmFKjTzVdPpHsJzVNA04xYyhckOD1wANNZMrVTHEryIYI166B1HFWRLYn pI3zTZC3FKghQ== From: Maxime Ripard Date: Thu, 22 Feb 2024 19:13:55 +0100 Subject: [PATCH v7 09/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: <20240222-kms-hdmi-connector-state-v7-9-8f4af575fce2@kernel.org> References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , Sebastian Wick , =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= , dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-sunxi@lists.linux.dev, Maxime Ripard , Dave Stevenson X-Mailer: b4 0.12.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=7393; i=mripard@kernel.org; h=from:subject:message-id; bh=pSNXmp0c3bxRBDh2tzEv2eshg+rV1t1u/wJNsU+JbLE=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKnX+97Z3Zk2rUT6zdWeoBmT95Re/tTqdmmSHOf9gnld8 xe8NVzq2VHKwiDGxSArpsgSI2y+JO7UrNedbHzzYOawMoEMYeDiFICJVNUwMnTa+sV6dn9S1Ptq KV947HjbRt/w64dMpDvYO9c0nPp3RYSRYfL5k5xKofIb1Zdbpml5cYT840rUF2yMDiqMi3v8tO4 4AwA= X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791624841384275725 X-GMAIL-MSGID: 1791624841384275725 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 | 5 +++++ drivers/gpu/drm/drm_atomic_state_helper.c | 20 ++++++++++++++++++++ drivers/gpu/drm/drm_connector.c | 20 +++++++++++++++++++- drivers/gpu/drm/tests/drm_connector_test.c | 12 ++++++++---- include/drm/drm_connector.h | 12 +++++++++++- 5 files changed, 63 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index a91737adf8e7..4e11cfb4518b 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, "\toutput_bpc=%u\n", state->hdmi.output_bpc); + } + 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..460454904fe3 100644 --- a/drivers/gpu/drm/drm_atomic_state_helper.c +++ b/drivers/gpu/drm/drm_atomic_state_helper.c @@ -584,6 +584,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; } EXPORT_SYMBOL(__drm_atomic_helper_connector_hdmi_reset); @@ -651,6 +655,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.output_bpc != new_state->hdmi.output_bpc) { + 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_connector.c b/drivers/gpu/drm/drm_connector.c index d9961cce8245..da51a2bcb978 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_connector_test.c b/drivers/gpu/drm/tests/drm_connector_test.c index 8f070cacab3b..d8d30aea9fdc 100644 --- a/drivers/gpu/drm/tests/drm_connector_test.c +++ b/drivers/gpu/drm/tests/drm_connector_test.c @@ -184,7 +184,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); } @@ -200,7 +201,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); } @@ -217,7 +219,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); } @@ -248,7 +251,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); } diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 000a2a156619..d4d2ae15bc1e 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -1037,6 +1037,10 @@ struct drm_connector_state { * @drm_atomic_helper_connector_hdmi_check(). */ struct { + /** + * @output_bpc: Bits per color channel to output. + */ + unsigned int output_bpc; } hdmi; }; @@ -1682,6 +1686,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. @@ -1915,7 +1924,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 Thu Feb 22 18:13: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: 204956 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:a81b:b0:108:e6aa:91d0 with SMTP id bq27csp126249dyb; Thu, 22 Feb 2024 10:23:11 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCVtVACzpIirEhPM+3z7Y73CZegQjjkNx75oUpLej35il3T0d1i0iJFRlOHV919RZZypYAjZ0cvN4rT8qXQLyNrG3ZwiWA== X-Google-Smtp-Source: AGHT+IFA+NMN0Q1RLmqWFlq4OEhS8kYzXTsqgKGGgrXVajxWawvphSoCtGcjO15jCx0HfAEmwOSq X-Received: by 2002:ac2:456b:0:b0:512:a9aa:ab48 with SMTP id k11-20020ac2456b000000b00512a9aaab48mr8000829lfm.7.1708626191037; Thu, 22 Feb 2024 10:23:11 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708626191; cv=pass; d=google.com; s=arc-20160816; b=nLe856+mX9NKw7gcWpfVgEzumWR6PvC6BHhY5cFcB5ZwFnFS4sm78OjHojAODSsJhp T4RPmmALLSWeuTYsFfhZk76eKrf1K8kQA4wfYPR/70CF4lRM72dPBLRVp8GTiRqI0JAh NFRLkcS2oYgjGBXelVjBCjCO9RPigHtf453h9uEu7nSRuDDqVvIXFcLZz/yc0xZq3ijw jIeqN4C0aV8KP8HL0JcXXETubMJUq3d5oRJc/CCidO1bXYreFZBZRoDD1IkYo2Ahams+ MmmplUAQ5iOVFixB1G9Q/2KHIbzxcxO4+QdYsKxGQo6VfrKMNJVD9oDrR0/IJ6YHIFCb nhwg== 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=1XuOa4fe2l7KMcdSkkwXm1M9KEMLZUXfIw0UcdEFyjE=; fh=8wcoxKk21hICD+6obVirG13fsSSMhKa/pufykSf87d0=; b=gjHrHAQBRBw2djrsfK9bxx6hGuRxv0d6YrUaHi1+NTg76FzaKHM3eqBZrQYpwPdXWT b1T8GhguVgO3U1PBiekHH6NL1unt0lUaKm+r/ndWUbF/+OllBI0vTz8LGJOJTQAhYhPk LB8xJwHR8PVtXlOFvldYKo57644JmgPfjzxUeei0OWuhz1vIkTICJdKVUjCP3JD2onOR cNpHgqbzR4cpnMxi3GJCL2AGxIYB7qlSzQUwJYcJk+KT7tRXluZn8DKQ30a7CJZmXbYr s0ECA9QMJ3qcIErV1J0VrRQoMtC3ojBKtPPLwbu12+aJXjwepKScZ4zjhlkQt86uOZRN ko0A==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=Xw1BR3oy; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77083-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77083-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [147.75.80.249]) by mx.google.com with ESMTPS id lt25-20020a170906fa9900b00a3f4169cd7dsi1514904ejb.182.2024.02.22.10.23.10 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Feb 2024 10:23:11 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-77083-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=Xw1BR3oy; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77083-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77083-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 6FB941F2351A for ; Thu, 22 Feb 2024 18:23:10 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id AF1B012D210; Thu, 22 Feb 2024 18: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="Xw1BR3oy" 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 67DE36AF81; Thu, 22 Feb 2024 18: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=1708625697; cv=none; b=r/cAlfBbE/tp+0NEBSkzU65yk/jl+6JxcIz6FXoF8MzAkowv5jTI5IZAJeyQ/gk5F/YxliQsTJ4tWk7KQkPcjbQKDl2gTT283I66bkrBObwkyyQ5t3khJkT+lkd2RXsRoyPFTvfP3341v4B4t1dvGPBB+Z4qoCbbq4HGxypz8Xs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708625697; c=relaxed/simple; bh=QPJRkxqjP01RUg2z8z3iXSIXfC6H+239piRhBWe3oTI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=PJ3duLLWPBPIs8CyNKPiTBVyePbLbt+IKEfgtW7/dZLtJKHkj0L541/WChhA41cDBxgSCMOlB38LLkKp8ExhB8Hl13YlK7zXVcJ+aAlzwPo4w7TaX6CsXNGk90L808waH0ixv/AdLQtyIkHzDiHfeu9NbdC0DMhOodco+f+f7vo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Xw1BR3oy; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 70DA8C43399; Thu, 22 Feb 2024 18:14:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1708625697; bh=QPJRkxqjP01RUg2z8z3iXSIXfC6H+239piRhBWe3oTI=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Xw1BR3oypV8jBD/KSthJnxNslISx/31Q8/rA0/2XGMfxeg1WaUZknsqPWKn3zstc1 2LjEKbqW4p8J2aEWhLa33MbAKzRmnmnZS9yUPMye+RO2ZVnL75lg5IzlXvjjMIj9Lu Q6aiQvcq8ktE7UAPRGI2ssQc3MjOJEBwquKfjln2Ho1B2RJ/D77fuZlze2kVd3Ymyu BYzl2w33dRDj3HBGtwo2vJqon5wG3t9/MMj2QWLrJm19evALn3GcTjXmafmhapBXoM c0TwA1S43A0qPxRLfaxbBjC6XKvO3ST6vLrWrPQttOg6JSEEnS6tVDL0GcN0RkwW6t GvaiF+mVR4XMA== From: Maxime Ripard Date: Thu, 22 Feb 2024 19:13:56 +0100 Subject: [PATCH v7 10/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: <20240222-kms-hdmi-connector-state-v7-10-8f4af575fce2@kernel.org> References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , Sebastian Wick , =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= , dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-sunxi@lists.linux.dev, Maxime Ripard , Dave Stevenson X-Mailer: b4 0.12.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=25959; i=mripard@kernel.org; h=from:subject:message-id; bh=QPJRkxqjP01RUg2z8z3iXSIXfC6H+239piRhBWe3oTI=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKnX+95nTrumk/szRlHrZE3bp+uxDwy7mNwuip989TZF+ DnbDHn2jlIWBjEuBlkxRZYYYfMlcadmve5k45sHM4eVCWQIAxenAEzkNwsjw6wNARfaYlrVq3+d FX4cuux8aOni00t7bVcwpSi99LT+2MnIsIPd/Vn2FYbnkVoVOUwHUuYaSFqdvsukJVvu+zn0DNM XRgA= X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791624417091721262 X-GMAIL-MSGID: 1791624417091721262 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 --- drivers/gpu/drm/tests/Makefile | 1 + .../gpu/drm/tests/drm_atomic_state_helper_test.c | 436 +++++++++++++++++++++ drivers/gpu/drm/tests/drm_connector_test.c | 140 +++++++ drivers/gpu/drm/tests/drm_kunit_edid.h | 106 +++++ 4 files changed, 683 insertions(+) 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..5d1a1dbff433 --- /dev/null +++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c @@ -0,0 +1,436 @@ +// 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, + unsigned int max_bpc) +{ + 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, + max_bpc); + 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 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_output_bpc_crtc_mode_changed), + KUNIT_CASE(drm_test_check_output_bpc_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 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_bpc_8_value), + KUNIT_CASE(drm_test_check_bpc_10_value), + KUNIT_CASE(drm_test_check_bpc_12_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 d8d30aea9fdc..20da290abff3 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; @@ -206,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. @@ -284,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), 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 Thu Feb 22 18:13: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: 204955 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:a81b:b0:108:e6aa:91d0 with SMTP id bq27csp126238dyb; Thu, 22 Feb 2024 10:23:08 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCVWMCK/Hhrriph5lbjeylwdxK0TLg4yj9HjI6rw6MzRVwxaRDJ8K25qnLj+VTeFXrBcZZhKGccKqHWtTDp7xkOgWbGLvQ== X-Google-Smtp-Source: AGHT+IFfkBGfsDVqz4DIisZI1gw+A9ldPEoXKwQPp/vszDY27t4CW374+2BNB3EtsIcV2ZTuH9V1 X-Received: by 2002:a17:902:bb94:b0:1d9:a2d3:812a with SMTP id m20-20020a170902bb9400b001d9a2d3812amr20000932pls.56.1708626188579; Thu, 22 Feb 2024 10:23:08 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708626188; cv=pass; d=google.com; s=arc-20160816; b=r5Exr4BbGgMqCHC3xvEXVLfV7uNRk2RShhl1joN0jciWRPM7BM8Obotrczpt6OQw5x BlGC+7fHbaz1orw3RdeVqpdxGlYAylRqEaspmyNbBs6GadvNoCbc6S9wNUcdQUIvyvZM gzcUQIyRnswnjGGk+Crshvjna9EvFwVuEvzGIe1vSuILwipcZCVBvxnbrpNOd83cZ3Uy PdvpJn0JG0OxJDGEUBhYFBOBfAv1EonHnUpn3n0EyOYRg5EtS8AHfUIgQTZejDpwxir6 ES1O2tvuvX0vweo+tWfQobn9hFDiEeW8ElnrkTEDbgbKuMy+bKIbPBSVPC5vzSfKGDLj WEng== 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=ZFsNk7N/Ifl2aQQUK1qQzMtYKK4bDnwi8au/JAqe7NM=; fh=8wcoxKk21hICD+6obVirG13fsSSMhKa/pufykSf87d0=; b=THj1yn4Mx3PYHSnCQpw6qTrncncB+WISIqr5acefaV9DZL6U+Nv6lv3V8RPQIwjNW7 Gaqp8VGiOBzdZ5g1+O7OMGjG28YblGlAxL/S+uUDVM/GkVDyjbpuWeYte+AgOF9Ybcd3 cpAgsEgo7OPyXcHk8gr1liCspFzZPpiRA9XrnX0TMYjKR5RdHJ9k1shJBD4vrN7p23Ad pliJ2PKB7ooNZOfQ+HXEMrVmAL8XpoNlvdY0VZRuOtp09svmasYuSvHxcykGdtvgSogH 8lsVKlKFgTXkWqcdWu1eBQtybC8nauOCXg+LqVo3er59z2Q4ov/s3BlPsEo/EF1fXP3x ttWw==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=MRAyjeka; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77086-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77086-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [139.178.88.99]) by mx.google.com with ESMTPS id p7-20020a170903248700b001d92086fe43si10485908plw.436.2024.02.22.10.23.08 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Feb 2024 10:23:08 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-77086-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=MRAyjeka; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77086-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77086-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 62F27284F14 for ; Thu, 22 Feb 2024 18:23:08 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id C187712D211; Thu, 22 Feb 2024 18: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="MRAyjeka" 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 35ABA71735; Thu, 22 Feb 2024 18:14: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=1708625700; cv=none; b=ph2/Ck+AqvU4UO8zrO5rdG8CnVpb9MHLiyL0wtCT/QN22v0hF+jgW0D29B8l7Whd0c2+/8YRooP95RronHtSel2e0bDQveNiyVuk87uDKufUp2GY5F8Ry2C3Ecii/KF1Bem/JwifyxP/DMWwh5yklod5gJPcnng1vEhjj+3W+G0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708625700; c=relaxed/simple; bh=sJk+iLTFxQ+htecxrkrYH5cdVnbGhOy+H6wNvmnfl9g=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=g2wrmbRELgULD1neWoj63O8l2lSLyvEE6W+3DbaN9plvhW2AKU3PMHd3U8xfit6OBKwnJymW4lLeQsANA3owwOPG490NURHdKxXxMthE+HYNKr/rKffECZMtZ9fL5SW+lYC9FseFHlfNDI+6BxZ0KzPeK1js7FvjfJJOCDlOh4g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=MRAyjeka; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 50DD6C433F1; Thu, 22 Feb 2024 18:14:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1708625699; bh=sJk+iLTFxQ+htecxrkrYH5cdVnbGhOy+H6wNvmnfl9g=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=MRAyjekaJWnFCibf/8lRly5LpNhCrqCamCfqZSAGKYI0Fu+I2GihG8D4ZYAs9MJ1X 5YeDwUpW0fX43VfhyZFqZ+9Xe5sOAd+C7jOya4XsJh/qT4nn4LykNMZpotrV5Xjcoq Ap5ndFigpz9SxZyEiJfMXfjyS6XRKMIIp/RaZV3vXltWLJerB4LsrdEYTsngZNpVWM rnAQko12J8/ZECxscZ/ZBqNCbMTOh0h4zsL8sYwnY5E5TyOEPF73hV6SPB044NNGwX FwFhM34EuR8twNSZ7q328BDA5eMnlI3QN8r2MvNpypCZbnclmLLmKtKK/hruukmJxM DQQxlWGwrTiow== From: Maxime Ripard Date: Thu, 22 Feb 2024 19:13:57 +0100 Subject: [PATCH v7 11/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: <20240222-kms-hdmi-connector-state-v7-11-8f4af575fce2@kernel.org> References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , Sebastian Wick , =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= , dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-sunxi@lists.linux.dev, Maxime Ripard , Dave Stevenson X-Mailer: b4 0.12.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=11786; i=mripard@kernel.org; h=from:subject:message-id; bh=sJk+iLTFxQ+htecxrkrYH5cdVnbGhOy+H6wNvmnfl9g=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKnX+z64mfDFZnPPio2ROMUvlcqa9d4rfWGF5xfXbw1Pb wpU3nvdUcrCIMbFICumyBIjbL4k7tSs151sfPNg5rAygQxh4OIUgIk4vWZkeGxxo/PWUdH5Th+1 rv9Zt25P0Trr/7sTYs8kNZu/S1r57hDD/8THzeuSLymksj29J2wyY+7201s3WvV9f8d6K6VQ/8h WLlYA X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791624414267676586 X-GMAIL-MSGID: 1791624414267676586 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 | 22 +++++++++++---- drivers/gpu/drm/tests/drm_connector_test.c | 9 +++++++ include/drm/drm_connector.h | 20 ++++++++++++++ 6 files changed, 81 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 4e11cfb4518b..8730137baa86 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -1146,6 +1146,8 @@ static void drm_atomic_connector_print_state(struct drm_printer *p, if (connector->connector_type == DRM_MODE_CONNECTOR_HDMIA || connector->connector_type == DRM_MODE_CONNECTOR_HDMIB) { drm_printf(p, "\toutput_bpc=%u\n", state->hdmi.output_bpc); + drm_printf(p, "\toutput_format=%s\n", + drm_hdmi_connector_get_output_format_name(state->hdmi.output_format)); } 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 460454904fe3..ae99765c45de 100644 --- a/drivers/gpu/drm/drm_atomic_state_helper.c +++ b/drivers/gpu/drm/drm_atomic_state_helper.c @@ -660,7 +660,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); - if (old_state->hdmi.output_bpc != new_state->hdmi.output_bpc) { + if (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 da51a2bcb978..b629c8e990f4 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. @@ -1201,6 +1208,30 @@ static const u32 dp_colorspaces = BIT(DRM_MODE_COLORIMETRY_BT2020_CYCC) | BIT(DRM_MODE_COLORIMETRY_BT2020_YCC); +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 5d1a1dbff433..a129ea5f014c 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_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); @@ -292,7 +296,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); @@ -361,7 +367,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; @@ -383,7 +391,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; @@ -405,7 +415,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 20da290abff3..a9a57cb23235 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); } diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index d4d2ae15bc1e..29883e6f8e50 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -368,6 +368,9 @@ enum drm_panel_orientation { DRM_MODE_PANEL_ORIENTATION_RIGHT_UP, }; +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 * &drm_display_info @@ -1041,6 +1044,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; }; @@ -1902,6 +1910,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) @@ -1925,6 +1944,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 Thu Feb 22 18:13: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: 204981 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:a81b:b0:108:e6aa:91d0 with SMTP id bq27csp131181dyb; Thu, 22 Feb 2024 10:31:43 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCX7a+jkDIhC/2dds3rqdTdWmBJ1XfQsl9YNPBioMXLN1p9Gy2lrM6vW5mU7VuxOtdIBLRTQhQGOhhND+HNppjkYvLctZQ== X-Google-Smtp-Source: AGHT+IG5/sNRhyVbSfCpQlclt5u9ND3g/7JfiDH1iVNNPRKKCb7XArf6DVY4Wh7Q/Hntm7+5yDAH X-Received: by 2002:a05:6358:d26:b0:17b:570c:7eb7 with SMTP id v38-20020a0563580d2600b0017b570c7eb7mr7695803rwj.11.1708626702965; Thu, 22 Feb 2024 10:31:42 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708626702; cv=pass; d=google.com; s=arc-20160816; b=MyeU9knPNRvuQwewdDEaTVcEAjvfTFp6K0DOrWW6m0XEPyXGUz/wDaGepR33t02lex kJeemR9qAnfGKjujqUQiqfxyC60K4btIfyQuBCuqBlzaDYpArWJYQfu8ZFNbGcTBd8lB ckhStpWnBiUKKsW9zHj1wRLRZEX0L26OMdzBGXpgWnsYUxs0WyKGLWTd7mbFqiHFNsls 2Qudlf4qGBR4ez7wXkbfnX7hY4v7PzfpSPlidz4goOaLam+HGWNnsOemIg9HB7nRCbLv 03W0BnPhVDu3j8AYcJc9ZKmGgAeMarT8rGh+CBBtP+/FYQJk3VK+94FK6iwm9ftY0Dqf hHkw== 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=gujZOU2pwvxo+dyJ8DOtVEZvw7pjQXhi2g7E92ndXhw=; fh=8wcoxKk21hICD+6obVirG13fsSSMhKa/pufykSf87d0=; b=v+kIUMXs4EOYiaMCkab4oiv/MTzZ5zX6qHDmnoBx8CIRt9p8Hu+MAHu/ThUJMhoOen KanRoXzvgW80cnS0YtvD5LHMZi2MJHLzcTi2RdZjXRemoSXRd0vPRA5emwc36ANWJxY0 3lG+2IX68mjQqk8B7T/r1RRSKeorxjhuHQAANs9csF1Br5SjwkbV+yp4vokt1fhuwddV Zgt24FjtTSfDgIvrdnnfwV1lFXjT9ARoZw41dIKyssGY+QLbhE66UGugD0M+cOGaDYcJ TsXb8I1AHOeqQNyrbPk3Mwf4vTniMN1A4wTALZ4jT3eZo+2ogUZQ6iNnwuPMO1cDQHbx 9Yjg==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=o3rLDusK; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77089-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77089-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from sy.mirrors.kernel.org (sy.mirrors.kernel.org. [147.75.48.161]) by mx.google.com with ESMTPS id fk1-20020a056a003a8100b006e476b6392bsi6039604pfb.287.2024.02.22.10.31.42 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Feb 2024 10:31:42 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-77089-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=o3rLDusK; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77089-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77089-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 471E9B250F2 for ; Thu, 22 Feb 2024 18:23:29 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id EB727137914; Thu, 22 Feb 2024 18:15:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="o3rLDusK" 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 94E7B73F1C; Thu, 22 Feb 2024 18:15: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=1708625702; cv=none; b=uOr+oQhASNwiOMrgmrzc/XzTH3J3NDcHx1m1Si0EUO+IVR94I3QVAogChsP5XK6+zEAhKL9mzNl0dY2ac6a91sEuDLfCP5dqMlO0BpaDisZszrL5BJ7oxQ5ROlWJL6b8ypreAZj1MSPrdGxisQAFeFgtIynr2IeVrQlD6E1ZDNE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708625702; c=relaxed/simple; bh=35dEQopjUt6A2W23PQkFev/rOQ1owYxpUGVppcAXPW8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=S31slbDrtuqPvPwpnvS+8x5zD/CoWFVczkdZX1GT8+Y+mv6ltXr3U6CMxsa+xFABQgElK8ZTQHk3Mgrk2AOGNfAh3Tz2/jgU48mt/daN9jCRlnPwWhh5699TRYukFuKFC3pi6ycz/NT1QcchJhN5PiMzpIugl2HSkDgGbYBnKNo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=o3rLDusK; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 179C3C433F1; Thu, 22 Feb 2024 18:15:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1708625702; bh=35dEQopjUt6A2W23PQkFev/rOQ1owYxpUGVppcAXPW8=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=o3rLDusK1Vw0bjrO7qrIF4iJhbGDg6FozAm37wlI3AQmiuDM+fhZG/H0OLsrCBKpf tZA618Fds6vgfNxYnNBDhULGM98xbvKCbsrEoiHHPH4Psu2/yuFiGyHfKGYW9l0+Xi pqnFHKUjnMpSXxjmJvoQH2VebiaDN14iL0B+WFogkGHkJakkD+6/r/w3UNok18r3fH UeFsZN6/NVvbJQmK85+UspdD4daU35QqqkxLOhi6EvVgW6xPTXi+KM0A1ysI0QOcyK XJfXQFHlOZkgW30Oh0xK6oUZIEAEedT8hknOjurXc/f37ynF3QnJx5HK0yvz9DTqiP 4AL66vAYjgGlQ== From: Maxime Ripard Date: Thu, 22 Feb 2024 19:13:58 +0100 Subject: [PATCH v7 12/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: <20240222-kms-hdmi-connector-state-v7-12-8f4af575fce2@kernel.org> References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , Sebastian Wick , =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= , dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-sunxi@lists.linux.dev, Maxime Ripard , Dave Stevenson X-Mailer: b4 0.12.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=7105; i=mripard@kernel.org; h=from:subject:message-id; bh=35dEQopjUt6A2W23PQkFev/rOQ1owYxpUGVppcAXPW8=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKnX+z7oCuXVxn849X/rxa/77958NnPOD/nqxveX/rdzT JhzlP/D7Y5SFgYxLgZZMUWWGGHzJXGnZr3uZOObBzOHlQlkCAMXpwBMxN6A4Q+HQc3NaV4KAbWT w5Vk1c73LdwVVnXsfX6T3oxXzj3FTGUM//NzLl42vJhwqpdTTsq1kHF/cxnbKhPtwu5LCpF8Iq/ kGQE= X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791624954018095485 X-GMAIL-MSGID: 1791624954018095485 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 a129ea5f014c..1c3dd8a98fb0 100644 --- a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c +++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c @@ -347,6 +347,15 @@ static void drm_test_check_output_bpc_crtc_mode_not_changed(struct kunit *test) static struct kunit_case drm_atomic_helper_connector_hdmi_check_tests[] = { 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. + */ { } }; @@ -427,10 +436,33 @@ 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_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 a9a57cb23235..5bff67fbed87 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), @@ -510,10 +548,69 @@ 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_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, +}; + kunit_test_suites( &drmm_connector_hdmi_init_test_suite, &drmm_connector_init_test_suite, - &drm_get_tv_mode_from_name_test_suite + &drm_get_tv_mode_from_name_test_suite, + &drm_hdmi_connector_get_output_format_name_test_suite ); MODULE_AUTHOR("Maxime Ripard "); From patchwork Thu Feb 22 18:13: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: 204958 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:a81b:b0:108:e6aa:91d0 with SMTP id bq27csp126776dyb; Thu, 22 Feb 2024 10:23:58 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCWRsehFiZeoaOG5vgS5EnsNyj2H+Wgpdr7uOdw4AhrwXG3ORfDCjQlCAO4h5s6DH5OEVwaDmYt0unzMHga5qU2K5z6msA== X-Google-Smtp-Source: AGHT+IHbY3cvYVa9Uhqyr8BkD5ON+mhor3KPvJ/cS1GEP5zmiVDIkxV8/Ss28zXDEOIXj0zsGWKJ X-Received: by 2002:a05:6a20:1b30:b0:1a0:db5c:9762 with SMTP id ch48-20020a056a201b3000b001a0db5c9762mr1109128pzb.19.1708626238226; Thu, 22 Feb 2024 10:23:58 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708626238; cv=pass; d=google.com; s=arc-20160816; b=HfgyB4PQZsyHD09yI5ySbA01kYkHXOXpdJqv9QzcmtMQTpM24Crns5Cxjk3MMo2XMm JfB0ibZOfju+FzlyV+DFZMOBeUnbnzNxLMNG4CPvUyXIhALSwlIxHGqboXuviw1YN8zF wZJ4/Y83z/z10whU7oP51yluDiKylPkVBCVyYD358+jXPomYWoejZCxI8PF3Bt1Msc4c +xYQleScZqGP9/vhXdzG4/uWnT6zLw1j3Tw+aRtmersL9OTquTxJDqge2pmk/zYibVm/ VCMosZLTMY4w9AhHqwLbWoUpnCoV84zYxr0q6aoxGDb9hohhE5sYIte0cRDQwSY8HEK7 yO4w== 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=Xy17dsD1lCO9uPc2lkfo0V9gblRagmFiVy0uC3OyX80=; fh=8wcoxKk21hICD+6obVirG13fsSSMhKa/pufykSf87d0=; b=PUax3Uawm8D//bTOa/lI+AmTdEmetMHzdns9swGCNIW3CGmPUTz9bXcpsP7Sijg4Zh mj9udpg49PQr+9dnvjcEWdp7sxnNH2WWhn9TlT3QPN+vtPC5oc8DVo0myA118hirGGvu TRVZBLHWuofHAK6n+rxLIfc8xZxXSkvlTQbSXmq2Wg+7eFXY5jvVmnS0kqMNDrz1DMWK aTZwCJB4pFM0pf7g0z/OcNsy1cWewPOqlz1m1q2vfV44hy3UyDXJm873lAhZ/f6wnaAU mJLV7RvnMaqFJhRGEI5a+rBpgVtZ5iF8Q3TJy1ao5n2F0UJ+rK7sfj4FOOwZr/JbgALz SKuA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=LvyFNzgD; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77090-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77090-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [2604:1380:45e3:2400::1]) by mx.google.com with ESMTPS id nl13-20020a17090b384d00b0029927c58570si11119379pjb.12.2024.02.22.10.23.58 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Feb 2024 10:23:58 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-77090-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=LvyFNzgD; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77090-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77090-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 0E56F28506E for ; Thu, 22 Feb 2024 18:23:58 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 00D2C13BAC7; Thu, 22 Feb 2024 18:15:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="LvyFNzgD" 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 A2D8312D20E; Thu, 22 Feb 2024 18: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=1708625705; cv=none; b=UvWIWSjTqWY9qaG/BJx8Vk8GJn1ORUF5nH8lC6ovezSR3XGsK+TTcuyi4HXx4qx3c12P4YrKNiwgMmvhAM8EDVzJPzaof0n9YSy0uXtYKlKi3/niMjiaqkE1X7ilR3PwYiVEy/ajptSTgtI5zeZyr+QXWeSEbwWrIFgImnWK/9I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708625705; c=relaxed/simple; bh=mh6yrZRFWWWgJBk2sU4bljECM9b4FtLl0mec212hJfc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=G8p11/Z07rgWkW6QpdO93w/+xMrPn3X3OXFs7WkjZKZN3k7/YAQdIVoezzwpc7WD1J4qOO+d5DCCzUKBlKjvCSgfUnxXX3dWnhkDlCmSIzWRrl2mvU0n6pKDJNgJdmHqWCFRg2mKg2ByM+SqgQaDf7ZcBvzLuLRF+Myq7YMg+gI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=LvyFNzgD; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id CB1C5C433F1; Thu, 22 Feb 2024 18:15:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1708625705; bh=mh6yrZRFWWWgJBk2sU4bljECM9b4FtLl0mec212hJfc=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=LvyFNzgDE13kd6VGv2xijkQwQX8ujAAe6vaMdo5zRRzb37jaxP24x0rtuGc4fW/le yzKkevujM1S5D+PNXpWFphGPuWe2uDAlkSgnuKmJNN5ZGxkT2kdzGf6cXzz2pxVDAA jSmPuHZH4mscj6tU85CATGgp5+qK2ARaHtqtySny7OIC1myGHWRpaGslQpyOvrBWTT aelzxobALmoBu+x2T2/oOMX9htJJOSPD9OMFFM3o9t684kneUov/mx1xepyM27U/bn 4s9V5LvWaocHn91BEW2EX84o6UcgQk+95YJZlXWNaWDJosjRY+waKhVbtWadikJfN0 ZIfEh0wT83Adw== From: Maxime Ripard Date: Thu, 22 Feb 2024 19:13:59 +0100 Subject: [PATCH v7 13/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: <20240222-kms-hdmi-connector-state-v7-13-8f4af575fce2@kernel.org> References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , Sebastian Wick , =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= , dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-sunxi@lists.linux.dev, Maxime Ripard , Dave Stevenson X-Mailer: b4 0.12.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=4017; i=mripard@kernel.org; h=from:subject:message-id; bh=mh6yrZRFWWWgJBk2sU4bljECM9b4FtLl0mec212hJfc=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKnX+z7GcMXcWSeRGnorTf30af/4AzK3283C3II+vwxes eGy1JfPHaUsDGJcDLJiiiwxwuZL4k7Net3JxjcPZg4rE8gQBi5OAZjIh0cM/0w/lr0I/LNmouSr oPabZTXb3jf/Li67Yty1U6GIZ/sFB3tGhrly8oe4VDOPnuu8NXP6fy2Fz5/iDtnI7BTfvsH9qWm GNysA X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791624466619089152 X-GMAIL-MSGID: 1791624466619089152 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 b629c8e990f4..8cc1332f11c2 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -2897,6 +2897,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 29883e6f8e50..a859ad7ee04b 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; @@ -2094,6 +2095,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 Thu Feb 22 18:14: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: 204960 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:a81b:b0:108:e6aa:91d0 with SMTP id bq27csp127146dyb; Thu, 22 Feb 2024 10:24:36 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCVYNXmBoBC0lwMW8Er4jtYefwK5pncstb6YNx/sUobJbqN7uNFq72uhpH0GBH+wLisbuUzXdBD4uCYFM26rH19BSosOeg== X-Google-Smtp-Source: AGHT+IE2MDmbFFrLvb2c1mqR9O8LUgt9YuVJSCq/D2wlM8IcUrRByd1PihpChFsme/hFpStHg27h X-Received: by 2002:a0c:f551:0:b0:68f:4d2d:3f30 with SMTP id p17-20020a0cf551000000b0068f4d2d3f30mr14427656qvm.51.1708626275757; Thu, 22 Feb 2024 10:24:35 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708626275; cv=pass; d=google.com; s=arc-20160816; b=E2RPqvD6Bb6RAye9Ioh+292z2Bs0Jhw2CRQ93PMnMo1Zol89AlX5UV3CHe2ppDGU5t tAdIeQlZ4DIAdzH8FGiUHbxsXGeRwu25a137+PzGe7R1L4WTgaCKr/fJFpS+BcIKzMV1 D1HS6vigUWlhVQLZyp/hoZ7J4sspU9/aHwLI+i/p+1FYCvYlDntdMGSu4YgqgXuOrpeG gG5eb/HCIF3PUR1qRh4TjXYyW/r9+1/B8TBFLGTnD2Y4ahdVoZQpmmJAcnztkiGlul9Q wplHImf0AT5+u4Nqy1LWMAQHBj4t+QbTdIAKiPd75mFzRVEZS93TfcD9Y019IDHo4qCA 1Ecw== 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=o90C05sMmWnGfLFUG+SS2X0FiMZbxT9WU/vuyzsYAfI=; fh=8wcoxKk21hICD+6obVirG13fsSSMhKa/pufykSf87d0=; b=j84VYWsncIy66+CBZZCMz3/RW4E3MakiDEoTRCFaybnQqWFqgPBYhxWQLn64Bs5vBJ F+f9iXZYMXPmsYxyAppgJrhW46n28hlzMacwrbwVJG3Ao65GABQb1tyn5VmJtQ1gve6L C7ePCkRattFp+qRHc3LJvereN4X1jL77WW9KKQP5ccuFRpOYReHZ6JKaCQgrRAumnEpe v5iXUkR5xyFs58kGcQ7xL1MboDJ4KxBvTr4W3y/Liq/9t2j5nJp/dL2cJ37Q0rSoFryY IyKoTrqVYzeGYAhkFBNCkxoXuUY92Gy+/KhqHMtUDvSUK4zE0hQ2Bv7YjopBuqbv54Xq z/KA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=X27aknGJ; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77092-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77092-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id p13-20020a05621421ed00b0068f74b25787si8585396qvj.306.2024.02.22.10.24.35 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Feb 2024 10:24:35 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-77092-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) client-ip=2604:1380:45d1:ec00::1; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=X27aknGJ; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77092-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77092-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 7CB991C249D3 for ; Thu, 22 Feb 2024 18:24:35 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 2FF96158D99; Thu, 22 Feb 2024 18:15:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="X27aknGJ" 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 4E68A13793B; Thu, 22 Feb 2024 18: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=1708625708; cv=none; b=ZPi4ddMZled5gtY7RYttdh39EJT+8ArP3GPAhjrAurFFXii9WmJNZektL5fTUxbXv0Z9l7fJYDq8KesJKbPYESEKNbS/2rX3F2zcABvG+BzO50Thno5G2do47Yy+NEPh4IIgvKcrLHEI+6gV8HcH4kD0atyXHkjTfqMRqoM8JGg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708625708; c=relaxed/simple; bh=mAIhr8nqS+HP2elA+wn+XSXcyKvdZ0lT8gK2O7nwn+U=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=eHok4dNkv09Zd/96OKI7mm3/8np5QYjxMbddqsmCs9YuISq4YMXgDTQGb26y+n73/IlZn9s002i5p5GGinLr0IxJEO1NiGHxAAm4iEW5eGC9X+vHOa3qrczW3FR+3nKCdDiBbzatGC3HPK9jJI7MVRjGOu2xw/RRK1cnn5lQ+80= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=X27aknGJ; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 913B6C433C7; Thu, 22 Feb 2024 18:15:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1708625707; bh=mAIhr8nqS+HP2elA+wn+XSXcyKvdZ0lT8gK2O7nwn+U=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=X27aknGJYAlIqRxGFtiTTmdZXbn0ygSAc7JM2itkFWHJxfDZAbkJM2CyQvQWXpCso dcDZXgVDyNyZdDOGJ1AvE8G1ons5NJX7hCgqxkb2e9LB2KHOoRtwhZ7TKaOVN60aWx qFxjMKoB/xvoWm6peBHkBoE+MutjLpRj1kdkiQI/Ij3z4CYLsqeBsjUnJeLT6daKzs LxuRf1a7I7eVW2DYKBoYw8rWUxZAKOH7Y/FSnjQSH1+kf4SWvXxw/WnH/GNP7ExyVI mnErxOw/Ul/AaDxjbeKZeL0Agcj/D14Xq7HJztDPkGmhjcdZZBRdgsPuQMpAU3moyY RlUrtkDr6nexg== From: Maxime Ripard Date: Thu, 22 Feb 2024 19:14:00 +0100 Subject: [PATCH v7 14/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: <20240222-kms-hdmi-connector-state-v7-14-8f4af575fce2@kernel.org> References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , Sebastian Wick , =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= , dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-sunxi@lists.linux.dev, Maxime Ripard , Dave Stevenson X-Mailer: b4 0.12.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=13182; i=mripard@kernel.org; h=from:subject:message-id; bh=mAIhr8nqS+HP2elA+wn+XSXcyKvdZ0lT8gK2O7nwn+U=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKnX+z768Fy9kcFxfeWfhYkxMnPce6aVHheXmHry07tXs urPOpcFd5SyMIhxMciKKbLECJsviTs163UnG988mDmsTCBDGLg4BWAiOzgZGZ60GGSZS02ZxLbe 1sifzS5R/Uo/X9yjJX3vTPxaGLYzhzD8r20SyA8/MDWqKvmPnrx8/i+3wGQf20TdWfJK7SvyHPq YAA== X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791624505456590504 X-GMAIL-MSGID: 1791624505456590504 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 5bff67fbed87..882b9269148e 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 @@ -606,9 +608,330 @@ static struct kunit_suite drm_hdmi_connector_get_output_format_name_test_suite = .test_cases = drm_hdmi_connector_get_output_format_name_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_hdmi_compute_mode_clock_test_suite, &drm_get_tv_mode_from_name_test_suite, &drm_hdmi_connector_get_output_format_name_test_suite ); From patchwork Thu Feb 22 18:14:01 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 204959 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:a81b:b0:108:e6aa:91d0 with SMTP id bq27csp127216dyb; Thu, 22 Feb 2024 10:24:42 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCXhcs67DsgB539WT3MKHWLGpyJ7RIOT1eigiq6Df/upFrXCr75Dyn6bK90yrRG4yUNb0Gst/WS1TGyqNTd5YP5GWc6xcw== X-Google-Smtp-Source: AGHT+IEans0Dl3kDsZ6oPRIvFRoAR0dH7uNfvTENy9DXtQ8JxAPYBsrzVdSm9Wdl2Jm0H8rkdNr0 X-Received: by 2002:a17:90b:3104:b0:299:4a62:548a with SMTP id gc4-20020a17090b310400b002994a62548amr17230095pjb.34.1708626281957; Thu, 22 Feb 2024 10:24:41 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708626281; cv=pass; d=google.com; s=arc-20160816; b=LK9kJYFNtgoO8y0yYLOuD8x+KVUTS8r4tMspW/yF/NCbahBVJwszaFOOEbT0xl2xmK pfXqWoCb+8eHuYQE960QGbxZlcRC69mj9NkjV4M00SvbMPBhKeUgG/w4JHQbyWl8Efo3 UZKRP7FZ3Nv+iicb4gJvmHEMeAzB/ahcWHTB/Lt5ZCNjGKaW66mWX0kZPVkwr/gO92dp fNhQQw0kE6gl6rAKVpKsV4DJybVc/xA5dpehi8+1UmwhGnevNk0bwwHHUNnjk9W2nkAE /EODOIvqX1TXZ2sdablLKt0Vkuvou74EyRNblkGMr3AynBXcr519zY6FjtdxW12DtF0V KxZg== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:list-unsubscribe:list-subscribe:list-id:precedence :subject:date:from:dkim-signature; bh=mgAnGd78OFonJQM5iGQmupvozSUtdkNpzXztua2jqBU=; fh=8wcoxKk21hICD+6obVirG13fsSSMhKa/pufykSf87d0=; b=ZnqPOQm5pbn/Muik2sPg6qE4WhFEMExle5CxG+W9hxYLk+GtY4qGtJbxOgAxdsgDrH LOvjmW2kurKp8h6FmcWkanlgzrAyzdvNU+quGEJVGqY49io5u39u4kx5CI9V7xOP8O40 d2IzPRCavynexZLSSf3bjjGWEgorR2PFrAJRfT9QNLb+7sn32vtvACvMYDgS20V3sZJS 8T/sQyTOxP+fkuL4BR8jTOy1dkDgHxDMhQayGgNgvyGIBl7TI1WwdJ/GXJyg/XQQpTgw F52lxFhkx6wMEJ2Y1QECY/7uLqCEagYHlFy+JIVsh8qvuJumuSoDsx3OS1wFdMhO9vs6 +PdQ==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=J6fngq1A; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77093-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77093-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [139.178.88.99]) by mx.google.com with ESMTPS id gq23-20020a17090b105700b0029589234aa5si10646125pjb.150.2024.02.22.10.24.41 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Feb 2024 10:24:41 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-77093-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) client-ip=139.178.88.99; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=J6fngq1A; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77093-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77093-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sv.mirrors.kernel.org (Postfix) with ESMTPS id B7DEF285037 for ; Thu, 22 Feb 2024 18:24:41 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 1B8F36E5EA; Thu, 22 Feb 2024 18:15:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="J6fngq1A" Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CEECA13BACA; Thu, 22 Feb 2024 18:15:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708625710; cv=none; b=gJ4Z/i1Xs/rcvRos6GcK2XjhmgMSOTuvC9yGfr5FPSn5PKF1dz31a8I2SHZQ9KYMfAo0+fGhzv2rhcJKmPxKlbqndhVpjcTRTxfiwuytBofYjUmHj+hMKKUjjxZGmbqeoDoBVafyTD4BWXczxxg7bVRqkzg9crcfarcKFki2tnY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708625710; c=relaxed/simple; bh=aMsc7DdFYwurA9KgzS5h4e6qDwulzTropP6PF1/SZF4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=dtogYjzDIRsx/kCZ4LpyKlfoZ9rkvOv0cvTpCLB+/n+O4kHx6C8yEa5XEAdqsCiQIFJs5cCwv9mZJm0gmA6ZcsagTNqb45ahyL3XCSAOfh361c5Dow5/FkAqv7mAlcsJZ5rk4clQWTAv6mJIZOGf7uhRp8JxnowzwXZzYGk6CZ4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=J6fngq1A; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 524A2C433F1; Thu, 22 Feb 2024 18:15:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1708625710; bh=aMsc7DdFYwurA9KgzS5h4e6qDwulzTropP6PF1/SZF4=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=J6fngq1AbjSrcpH0KSddtC11tu8hWtlXwsgy7la4yxHKjSEW7SBGDGYfUbc8ZdzsD VixyiJ/+DLrcPPfZwU4wVHjJf4RbsigYHXtzBxqOCKrL28zEROL4UqbjtIney0EJ5V 4IUYvBgQbvX3MOtdTR/bR7JYxzyDS3E7sjF1LadvaGAyNlvds1COBBpDU+phe/Ge6v ueT5iDm0sldCDjsKXTB6LAYEDj4ic7nazR2voKDG3JnpX5Bd9asFIDLTRUjwQkQxjv yh8PQuySNfICttg/30j4mNSfUhroSvlZlYZC2HwwJsBS70SMMcTgJ7xi2kR/T57Bqp onJX00DCAB0ug== From: Maxime Ripard Date: Thu, 22 Feb 2024 19:14:01 +0100 Subject: [PATCH v7 15/36] drm/connector: hdmi: Calculate TMDS character rate Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240222-kms-hdmi-connector-state-v7-15-8f4af575fce2@kernel.org> References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , Sebastian Wick , =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= , dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-sunxi@lists.linux.dev, Maxime Ripard , Dave Stevenson X-Mailer: b4 0.12.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=5168; i=mripard@kernel.org; h=from:subject:message-id; bh=aMsc7DdFYwurA9KgzS5h4e6qDwulzTropP6PF1/SZF4=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKnX+z4d1eW3m3RkpZiDT0QHL9tbX+dmzt96LOaXzyze1 5PoyRXaUcrCIMbFICumyBIjbL4k7tSs151sfPNg5rAygQxh4OIUgIk8WsfIcOCEWPSajxeZdj33 n3TC4+hOh7TDS253PVlw3llnmfGthOMMf6XZyv3m9vFtNflnlJK3/+FyhzVFLQLz5YUSU4z1BBU 5+QA= X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791624511725033800 X-GMAIL-MSGID: 1791624511725033800 Most HDMI drivers have some code to calculate the TMDS character rate, usually to adjust an internal clock to match what the mode requires. Since the TMDS character rates mostly depends on the resolution, whether we need to repeat pixels or not, the bpc count and the format, we can now derive it from the HDMI connector state that stores all those infos and remove the duplication from drivers. Reviewed-by: Dave Stevenson Signed-off-by: Maxime Ripard --- drivers/gpu/drm/drm_atomic.c | 1 + drivers/gpu/drm/drm_atomic_state_helper.c | 66 ++++++++++++++++++++++ .../gpu/drm/tests/drm_atomic_state_helper_test.c | 3 + include/drm/drm_connector.h | 5 ++ 4 files changed, 75 insertions(+) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 8730137baa86..26f9e525c0a0 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -1148,6 +1148,7 @@ static void drm_atomic_connector_print_state(struct drm_printer *p, drm_printf(p, "\toutput_bpc=%u\n", state->hdmi.output_bpc); drm_printf(p, "\toutput_format=%s\n", drm_hdmi_connector_get_output_format_name(state->hdmi.output_format)); + drm_printf(p, "\ttmds_char_rate=%llu\n", state->hdmi.tmds_char_rate); } if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK) diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c index ae99765c45de..63a96c691460 100644 --- a/drivers/gpu/drm/drm_atomic_state_helper.c +++ b/drivers/gpu/drm/drm_atomic_state_helper.c @@ -640,6 +640,63 @@ int drm_atomic_helper_connector_tv_check(struct drm_connector *connector, } EXPORT_SYMBOL(drm_atomic_helper_connector_tv_check); +static const struct drm_display_mode * +connector_state_get_mode(const struct drm_connector_state *conn_state) +{ + struct drm_atomic_state *state; + struct drm_crtc_state *crtc_state; + struct drm_crtc *crtc; + + state = conn_state->state; + if (!state) + return NULL; + + crtc = conn_state->crtc; + if (!crtc) + return NULL; + + crtc_state = drm_atomic_get_new_crtc_state(state, crtc); + if (!crtc_state) + return NULL; + + return &crtc_state->mode; +} + +static enum drm_mode_status +hdmi_clock_valid(const struct drm_connector *connector, + const struct drm_display_mode *mode, + unsigned long long clock) +{ + const struct drm_display_info *info = &connector->display_info; + + if (info->max_tmds_clock && clock > info->max_tmds_clock * 1000) + return MODE_CLOCK_HIGH; + + return MODE_OK; +} + +static int +hdmi_compute_clock(const struct drm_connector *connector, + struct drm_connector_state *state, + const struct drm_display_mode *mode, + unsigned int bpc, enum hdmi_colorspace fmt) +{ + enum drm_mode_status status; + unsigned long long clock; + + clock = drm_connector_hdmi_compute_mode_clock(mode, bpc, fmt); + if (!clock) + return -EINVAL; + + status = hdmi_clock_valid(connector, mode, clock); + if (status != MODE_OK) + return -EINVAL; + + state->hdmi.tmds_char_rate = clock; + + return 0; +} + /** * drm_atomic_helper_connector_hdmi_check() - Helper to check HDMI connector atomic state * @connector: DRM Connector @@ -659,6 +716,15 @@ int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector, drm_atomic_get_old_connector_state(state, connector); struct drm_connector_state *new_state = drm_atomic_get_new_connector_state(state, connector); + const struct drm_display_mode *mode = + connector_state_get_mode(new_state); + int ret; + + ret = hdmi_compute_clock(connector, new_state, mode, + new_state->hdmi.output_bpc, + new_state->hdmi.output_format); + if (ret) + return ret; if (old_state->hdmi.output_bpc != new_state->hdmi.output_bpc || old_state->hdmi.output_format != new_state->hdmi.output_format) { diff --git a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c index 1c3dd8a98fb0..f2acbd4c216c 100644 --- a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c +++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c @@ -70,6 +70,9 @@ static int light_up_connector(struct kunit *test, conn_state = drm_atomic_get_connector_state(state, connector); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state); + conn_state->hdmi.output_bpc = connector->max_bpc; + conn_state->hdmi.output_format = HDMI_COLORSPACE_RGB; + ret = drm_atomic_set_crtc_for_connector(conn_state, crtc); KUNIT_EXPECT_EQ(test, ret, 0); diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index a859ad7ee04b..e3917ea93986 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -1050,6 +1050,11 @@ struct drm_connector_state { * @output_format: Pixel format to output in. */ enum hdmi_colorspace output_format; + + /** + * @tmds_char_rate: TMDS Character Rate, in Hz. + */ + unsigned long long tmds_char_rate; } hdmi; }; From patchwork Thu Feb 22 18:14: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: 204961 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:a81b:b0:108:e6aa:91d0 with SMTP id bq27csp127609dyb; Thu, 22 Feb 2024 10:25:27 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCU1u+5PG+PxPSM9WZFB+Z/fxQdVzBU4HEQi/Sn4XOWOV7Dinr640ok26ZBusrbqmioQ6Ouo9+2HUQ+gUXb8j91ZTzN+YQ== X-Google-Smtp-Source: AGHT+IH//Le0C6uyinjLMDPqtT0vkm1qRfCM9RVMCc47UvV/M1jOR4NDyqpliR920tsUaT41/fmQ X-Received: by 2002:a05:6e02:1849:b0:365:3010:14b1 with SMTP id b9-20020a056e02184900b00365301014b1mr16539499ilv.10.1708626327686; Thu, 22 Feb 2024 10:25:27 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708626327; cv=pass; d=google.com; s=arc-20160816; b=gAMj+/FCQsB0HLGtOcmMjI36ZuDL9M2c4Z0ywVITlGRGJZNHcPsAphCo9XI1NYC900 nLNJ5glADN5drXJrBketfSWL3h1nil99HLNR/uk1NfC4zrwwPcp7znZxMJE6Ijxw/BwR gc4DggSzYLAdggUpH2rW7VrRoQ/KY8pTkPGak3k9J/kIAkWhBqtHQx2F4ePydxAgeMT/ MdTrEAZ758ZJz7KJo7PbWrW+3yUQj4x3oFBmpIPBuRPx095/4lMYx2s3ZILzI1awmIz5 Ou5Ym8fcT5haNaNDfXVZOWlxCKYGkzKg1IGHshh3EkF00/3I+rAwVMadzyp5diJgt5Hz j06Q== 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=HaXkttK8PWztwtH1tPnNQ93F1DPODN7o8zftaEqtf+c=; fh=8wcoxKk21hICD+6obVirG13fsSSMhKa/pufykSf87d0=; b=lE7Kz3csL8tagVP9KJorHn+5nD+dvqTgNoeNTeAJzl915nHf3SmHh4W2vLtsn8rjLY 8s891wbT+PXAaEl1s9+TL8vbHuQMYtZfd+bZ1Td+BgWuRwlp6N2aMF7SFleQ79VLZULh x6HzJPSmn+5Iwz0ehHW93x5wCVwbo9Wi2tJwy6d3CoXmQwot4TOqSOQP0ZSZGurVlbdX YC6BzXcLFYU4aD/WwfsW5vemUd/Qr5unLBEvp4Yuqrz9KjGpT8sLruRF2a0qxQhtVXCe KoGcEtA25NlVT+c0U4YcHSGwMT+mY3IOvp1pdg4fn4AlZfiBms4OPPDXzxqZ+UK6vtvw e6ig==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=piTXap+3; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77094-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77094-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [139.178.88.99]) by mx.google.com with ESMTPS id z1-20020a63ac41000000b005ceef6e1c1csi10655924pgn.708.2024.02.22.10.25.27 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Feb 2024 10:25:27 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-77094-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=piTXap+3; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77094-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77094-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 1DBB9286196 for ; Thu, 22 Feb 2024 18:25:18 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 873A3159565; Thu, 22 Feb 2024 18:15:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="piTXap+3" 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 14B966E5E8; Thu, 22 Feb 2024 18:15: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=1708625714; cv=none; b=s8SQDodq9rgwNNElEtiQeiYdVS4FtM+zwwlK0ZAboBL3fyl6P7CABzEzfikhGMg06etS+Y2zBaY/KP/VRdzReWLWf1KNpcRMOPIwl4GWTPQBtBimqJ3Iw/m1t+xJSKXFZjOZMq+BgtGuA+IPeptaLadBbYVvVof7zH3YYKh4ZAc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708625714; c=relaxed/simple; bh=/sAWVXEpGi9VGgQIgpW4fMha6z9ZtWIF8phv5/yhbrw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=JFLsnA+5hCYqNlOyXvCu0qCpkZLnqmSwlNZdswnclZoEQU7cFHiNWRGPaKOFlqw201Ek6b6hh0BJTpcpAoaguRDG1Iu/C7Vs9tc+kddQjyDwQa0nT986rktCdcCrZwoz8Pg+Nxxa5IgQ3+Qwu9xOEQjT2H28985tooRqfyLZxYw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=piTXap+3; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3B8C1C43399; Thu, 22 Feb 2024 18:15:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1708625713; bh=/sAWVXEpGi9VGgQIgpW4fMha6z9ZtWIF8phv5/yhbrw=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=piTXap+3V6UbFttB/9oxfhlda51sG/yMsuJR71IEXs6YTkJAJSJpg5HLGnkGGafH9 iJJTV++O0tv5qlXJC5XbxPQjARbIxwbfPODB91Xta4WnMBN6C8hxHWSSvIYEDrc/o5 pMuvTUG1ZAnmjPN2r16aUquRWtWgRS6u0EKFBVspk7vleF6cF5C/v8VxeGnBKsLp9K 547YgZx83IjQu3Dqj3hJY9a2cIs/FMnLMZC1ob265umghKdPPKHEqPb3NTeKdI93vy jYthw2AE4+fVgzI/3g4zGZsh7uFx+nLfD8DBZhjGM6cvn0RL0o/ORO1KKtC4HMYs2s nuMFTgVGNMruQ== From: Maxime Ripard Date: Thu, 22 Feb 2024 19:14:02 +0100 Subject: [PATCH v7 16/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: <20240222-kms-hdmi-connector-state-v7-16-8f4af575fce2@kernel.org> References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , Sebastian Wick , =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= , dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-sunxi@lists.linux.dev, Maxime Ripard , Dave Stevenson X-Mailer: b4 0.12.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=17444; i=mripard@kernel.org; h=from:subject:message-id; bh=/sAWVXEpGi9VGgQIgpW4fMha6z9ZtWIF8phv5/yhbrw=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKnX+z4L84hb7X3jf3RJRHpKbXSC+cuVYQ8s9sf7sjtNa k5Y2CjWUcrCIMbFICumyBIjbL4k7tSs151sfPNg5rAygQxh4OIUgIkIvmL4Z2OhMOPlno23Dle/ Lns7syuv+njLceMJvsyxc7QM77t2fmRkOHnufmu1wYTVhTbXk11cRJ6r9qxhvNirIVXhyBHypW0 WNwA= X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791624560262549156 X-GMAIL-MSGID: 1791624560262549156 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 f2acbd4c216c..dfed45b250a5 100644 --- a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c +++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c @@ -347,9 +347,152 @@ 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_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 @@ -461,11 +604,34 @@ 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_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 Thu Feb 22 18:14: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: 204989 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:a81b:b0:108:e6aa:91d0 with SMTP id bq27csp133519dyb; Thu, 22 Feb 2024 10:35:41 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCUB7QWALkeJeZhqjejkPEmDO8Fu4z7WaxUSU20v0F8lyHgWZUuASMCcR/6sNxKy4sMSkHK6WVBNdVBkzylIMmrGRMhDng== X-Google-Smtp-Source: AGHT+IEnDgdBNtnPE+AuaD/G8gNx8WdjDiqf9BxsbDBhwDSpgS/QIBmtimxz5c280AskP02gs/+I X-Received: by 2002:a05:6a20:d49a:b0:1a0:56c9:60ab with SMTP id im26-20020a056a20d49a00b001a056c960abmr23946893pzb.44.1708626941111; Thu, 22 Feb 2024 10:35:41 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708626941; cv=pass; d=google.com; s=arc-20160816; b=q8AUMwTv9a8Gy0QPhfBiFbyTuwqTey7Lqy9Gtz4MKC/UblUgN63O53vTtzb3WyTJyL qsd+OJC5WYitGVAjHM8ee+JQNGw8VshpfyPC+tGJ5vPqInxV5/xYyEpy4ShKj1vo+2gl TKNHgtxMlW2/NKaTzyhW+TTQtZRqZsl0pdfKMyLPHl5kXStOztjdPbqVkPjxulMGP1Eb JkrxVTHzbhsXgD/nPg9OnTzBe5cK1t26Hl9YiTvkHMNEl6v96LWWXEfTMp7mjRCCe/qb eq5sDyi/ALSG8+fFjtvAQ+YBL7y1/suv9nL1fM3P1diGobh5+lMx14lG2wfRH9vWNQgz Vwvw== 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=mc6mqohrVGeS+Ulnx8GLGLMz16l/eFMkWbBXS6LS1LQ=; fh=8wcoxKk21hICD+6obVirG13fsSSMhKa/pufykSf87d0=; b=AAknJ1jthuLVBZwkCKODPzocvuetrRicRzF1YHBtTeiN/sxhpTYMTcctrHDSofRKGf De5jxNnVt0QLk1SMm6+D3yK73QAP/P4ywBW4TWlMMOe2ueetpszYybMyGvs/pj7jcWxt FJzEooakG/cgl+Bo7s6zk1s0BnVYLMS6fYMhc3W1/SfgJCHqityaF6K/lwyivDaTkTQ5 urHyBj82QSjRDvYreDruMpQ6XVOkFIHFdxcuCWcgFyMQVkOCgbRdtRSB8a43ei5lFLmy LWnq/BQCZut/g3suRHk2hD4Eln67wsuzcE6rHj359hgyJydfeQmwW/vs6rrfqfCMatyg QvaA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=JVygD9Mn; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77095-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77095-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from sy.mirrors.kernel.org (sy.mirrors.kernel.org. [147.75.48.161]) by mx.google.com with ESMTPS id v10-20020a056a00148a00b006e3f39ecbf6si9338223pfu.54.2024.02.22.10.35.40 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Feb 2024 10:35:41 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-77095-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=JVygD9Mn; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77095-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77095-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 20D68B261D1 for ; Thu, 22 Feb 2024 18:25:34 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id BB5EF140E3B; Thu, 22 Feb 2024 18:15:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="JVygD9Mn" 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 B7AE86E5F0; Thu, 22 Feb 2024 18:15: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=1708625716; cv=none; b=P0YUgC44Q0p1T5z5RQS1KPktWS23EeyN/ewSsomhMP3zMKZyuN6OfLRylOsZShn0j6tci9/sl27F/QJtflwk6+0GYKuEotMXoyKK2kD+/qt/DfQzzCe3ADVrrwhQ7QQfbqZHKyZDlvNRRAIaoK+q3M2KzfgFLFMbVqQmC2LiEL4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708625716; c=relaxed/simple; bh=Nt2VIdXgQ6yHIy600gnsz7R43r+JMRxEty0mQ9gtv1I=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=NIHnKrk8UAG680mlEN/YCipUugVeLQItcssdr9RVThf59YK7nKwD7HOSO/m62jaXLarlB3VTAKX3chPcrkTrjuxFk0it3AQ7ijJGR0TDlBDI4sweo48okenqfjztBgUzXdHILpAhtGJL+958XNshfRSbheBoWAiwv/dGcWxgFYA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=JVygD9Mn; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id E7DB8C433C7; Thu, 22 Feb 2024 18:15:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1708625716; bh=Nt2VIdXgQ6yHIy600gnsz7R43r+JMRxEty0mQ9gtv1I=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=JVygD9Mn83OnObyjPklDK+LjVfaA4t8ZIrGgtKOU0MiURSlyfZjoEgQubTLZVdnCM +vsN7t9ethnWJRXuxjansKCXc/pYNZTpF+uLBxm406KCbv2UDE9HSabBCMCQz1iASv A9H+M4tHzDgDVNOFqNIoXKTvwTFSj9fcYH7jpxXzefW6my6lkCyEPNv+pFHb2gcY1Y 7pSClwEX/5eRYwRDPHyhBHuWBbp2nWfhuemy9MiJ5dT7dSEs2yDFzwf2SwjlyRROdK YMpqu2PtrSZXNMYGX/51vSce3fNoXhCz/f8h3nhyMNUDcEZaiAsmuLz6cj62iQrUDA O0O9uw4txQNUg== From: Maxime Ripard Date: Thu, 22 Feb 2024 19:14:03 +0100 Subject: [PATCH v7 17/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: <20240222-kms-hdmi-connector-state-v7-17-8f4af575fce2@kernel.org> References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , Sebastian Wick , =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= , dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-sunxi@lists.linux.dev, Maxime Ripard , Dave Stevenson X-Mailer: b4 0.12.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=9943; i=mripard@kernel.org; h=from:subject:message-id; bh=Nt2VIdXgQ6yHIy600gnsz7R43r+JMRxEty0mQ9gtv1I=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKnX+z7/CI6QYTPs6duXIqL7b/IeiTaGL0ezp9QwZy5SK 13v7p/cUcrCIMbFICumyBIjbL4k7tSs151sfPNg5rAygQxh4OIUgInUhjIyrL1cNmlZ3hJ3NpFj WhZ3GLa7+9Rv7j3svfv4u2fnonWlFBkZmq8lPT60munZZFNpRY3GlQ0P9t17H154ceYRv7Znt4/ u5AYA X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791625203591259620 X-GMAIL-MSGID: 1791625203591259620 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 | 14 ++++++++++ include/drm/drm_connector.h | 30 ++++++++++++++++++++++ 5 files changed, 61 insertions(+) diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c index 63a96c691460..448b4a73d1c8 100644 --- a/drivers/gpu/drm/drm_atomic_state_helper.c +++ b/drivers/gpu/drm/drm_atomic_state_helper.c @@ -667,11 +667,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 8cc1332f11c2..591d2d500f61 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 dfed45b250a5..989661ad3aee 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 882b9269148e..732c59a1d4d5 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), diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index e3917ea93986..8cda902934cd 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -1058,6 +1058,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 * @@ -1926,6 +1950,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; }; @@ -1948,6 +1977,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 Thu Feb 22 18:14: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: 204962 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:a81b:b0:108:e6aa:91d0 with SMTP id bq27csp127977dyb; Thu, 22 Feb 2024 10:26:10 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCXCluUFSIWz8L4Af3QRREie6Sl6wcluQ1MxA8odq6m724NGq2obyv7XHQW8L2TI/8+zAhKWfxsigS6BzG2yn7P0L+MC2A== X-Google-Smtp-Source: AGHT+IEPnJjoPrHsCFRiTJ8BGjHvfGf5Tb6KERls9ECgskiW2gejvSoz0e/tCNEZTn9w+oJvcKlS X-Received: by 2002:a67:f487:0:b0:470:5ecb:137c with SMTP id o7-20020a67f487000000b004705ecb137cmr10735727vsn.32.1708626370439; Thu, 22 Feb 2024 10:26:10 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708626370; cv=pass; d=google.com; s=arc-20160816; b=Szo15Pe7qrBAdNG7pEzRa0ByuWwwVnw88gUwHLSbXUQ4FHcg3VTmsDuUxU/7vfQWMp CtOfXUP+p/atJGmiTT0Bad7xkAtFQXLtuExopbcP59p14U3jljPWkWGTY3v7I+hPMB6Y ZCZGfpVEQN4KJccNm2O96BTlX3nImIrl2DGO+HZc293s8RxWIVvQxa0kvTrObl00RXPr CUjfAOC1Bq7LwYPxhby1Uzmm5YkR1omMYe3VqkqQGQbZ6FEa7JP/ugqtnGOdKYLUHmT0 IQe2KjCJjBv0KKvZkhtEfUKJ4ZvJEjZGfYsILQvGmdyHEtHlJjLAzRDmD2AE+FmJz4SI rMmg== 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=+CfYZQEVraT4X2gg1xR8EAcmPd0EFZuGekryB126tk8=; fh=8wcoxKk21hICD+6obVirG13fsSSMhKa/pufykSf87d0=; b=AuXhuC3db6dAkHIQUu3+GcCujOJFiAB1pEy8Aqwxef0Jy06ukagAPsdXpqhl73m2Mc 0qGeUmUc3AuHi1wk1urCa1yzMpBbXUI2zb+7pcLdvu9QHpAnjuuEnf0uuXtYVTGzmlrL JCA7OiQU4cGzLha4Yg1wBUE//IB0c+Cfe+zuW1s/U8j6D2E+3AZJNvQnWl8DxNbiQmqi aKv067cJ/Cc48etHRrsrKpKc34wPQbnbmsHbsab9yOW4UlG+TYZBJecWx0Jfmw5GsZcT qnK9bnNNYuD/mI36p5+LaXZ2YO1Gwxvkj3BfGZgJVQKdDXOVsi+IUUgYmGDJuOTUutHH 3eUQ==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=t6IImUp7; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77096-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77096-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [147.75.199.223]) by mx.google.com with ESMTPS id k12-20020ac8478c000000b0042c472bc5c1si13003748qtq.484.2024.02.22.10.26.10 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Feb 2024 10:26:10 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-77096-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=t6IImUp7; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77096-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77096-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 7A80A1C255DD for ; Thu, 22 Feb 2024 18:25:45 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 431F8140E56; Thu, 22 Feb 2024 18:15:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="t6IImUp7" 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 65D87159561; Thu, 22 Feb 2024 18:15: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=1708625719; cv=none; b=ah9N4rGaUpE8WwCD/GOYYnLu7OK9Pg0De7ez6oa5LBoJm7YBJ8P+vv6gGcZap4RCGueAIuEnrNeFTm6GGpIc4ouxt9L80g4LgKesGK5RcQDf9kKQlcdXmNUnNfUdjoKWB4zLwqMolUMjgXVjyv8hMsTytW7qVNdfEK0kpllJcyQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708625719; c=relaxed/simple; bh=/bnaT0uAZ4rOmQ62HDTgavxdwTBZFeEC9ReuYp1t42E=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=fLXp8Bh5lF1RVvlPtzf2zm0I9YE8GBDzbrBoymTwQkt4G4d/5s9KewyyPXXBY1gKwPOCBnJT5bJWMGW+vTChwTCKWBbvLeFmrwxVV98JItO+xipr8T4y8R0H2S95jUMGnH9lO4plKwGjcE65svIJCq/6iCb8S0vWj9FUvxKtVmc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=t6IImUp7; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id A12FDC433F1; Thu, 22 Feb 2024 18:15:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1708625719; bh=/bnaT0uAZ4rOmQ62HDTgavxdwTBZFeEC9ReuYp1t42E=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=t6IImUp7q0+jBz/SYYudGd3z8bkRy7KOdLICaxviN3T5A6qujoHDkB3svwy8jKvba EO4g7EsK0/wq9E81KsIjJD6tY0FW+xG+7I3IIiCxrWInxhZSaL2odT/1SX1ctza/yk KjDRKvkjwnvK0GCHXsxiI2eTKftyIPvo6bM7v+3ypQey1sgoqt5ecJsH3AOyx3aJnF vkcDwMBAfl65cOi0pIpWEeKdit9oN1kdLZ7J2IYhv+VFTnONocIvtv/pyrFbHl6/LB jlUGIgZMj3RyK87GfLSYSRJIu61fBrX86dNLW7tJXICQoyGv1Pro1QEFx+SZXHqUBa 6Qx7t+1lIl2/g== From: Maxime Ripard Date: Thu, 22 Feb 2024 19:14:04 +0100 Subject: [PATCH v7 18/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: <20240222-kms-hdmi-connector-state-v7-18-8f4af575fce2@kernel.org> References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , Sebastian Wick , =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= , dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-sunxi@lists.linux.dev, Maxime Ripard , Dave Stevenson X-Mailer: b4 0.12.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=3581; i=mripard@kernel.org; h=from:subject:message-id; bh=/bnaT0uAZ4rOmQ62HDTgavxdwTBZFeEC9ReuYp1t42E=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKnX+77UGFwumVh/4vL3kHuPQz6/Xrzw0Pc7x5e2/Jme3 pa0vpU9pqOUhUGMi0FWTJElRth8SdypWa872fjmwcxhZQIZwsDFKQAT6bjPyNCdaeNRutYo3LSJ 9f43P6c/+0z/thyvDv/8vkBKdX5mZQHD/9DN70U2PzKWNFu0rH3Wl/AbP7fqrBKy370oc8E2dvU pz1kA X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791624605089442543 X-GMAIL-MSGID: 1791624605089442543 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 989661ad3aee..5a8750153510 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 = @@ -491,7 +503,60 @@ 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_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 Thu Feb 22 18:14: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: 204963 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:a81b:b0:108:e6aa:91d0 with SMTP id bq27csp127974dyb; Thu, 22 Feb 2024 10:26:10 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCW9TZiIBdQgyuxtrZ0QpZw+Ssfb0Mwh1L1gMxQx9G3LHfPv8PA1M4fWX10TGzjFU2emQqtLUgDX4j35/he4jsGkrjchNQ== X-Google-Smtp-Source: AGHT+IE+JkkEyoexWzcqQlARYwegPBrprvW5pd5swlsw9ESIH9GdwmmWSzTcLdJ5KsAAUUM3mAan X-Received: by 2002:a17:906:1854:b0:a3e:73c8:cd27 with SMTP id w20-20020a170906185400b00a3e73c8cd27mr8525674eje.73.1708626370245; Thu, 22 Feb 2024 10:26:10 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708626370; cv=pass; d=google.com; s=arc-20160816; b=SsdXhuAmaBP/RhyIjA3HslVqLAVjBCJCsMmftMEFuz9glcHnr5oKaoZDsX55ZqtvUN QeWA83NahUnq3wAQBa2FmffoSMKWQ4hBlxCy3LiJ8z/z+jPt4OWTCBTQRNRVPLJ7I0XF tHmJnKBSfQS93XakKkG8Km//oLZ8wDvABkOU2Nbua8ITzaxmFczo9TF4TVWms8kzBsbR RjwlvIYYxy+cn6fUR4WmR38RBjnpVmIBr6w2yRuwYIfT3YxrAufamr9zi7ytnRQrnDG6 jeHwHi6D9Zg9EHi4m7eDbiw/oHG0d37CdmEChgtOmn5CU7b08n0X/d4VlQNX8WP7QsqT 6n4Q== 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=dJA9hXIAQdZWmaya6ewJnPeyog4PuOMhqCQdKzv5EiY=; fh=7mnR4/DMo6zaWtUGaVI9DND4TR+QGflpVaaXOChu5h0=; b=wM4/mlsY1crh032jZqKFQHdi/v2UM8zDeYsgoCRBdjaWkPypC8S8tk/eVtbv2R0qsH AVGj2mt+o3PeRWxjVxmsJUgiaSUmJZBCFqPNMGix5ZzBlC4DCwSzllP+tafAL0oGqGuz vr/jMJrjanNYFlkvwEgXxsJRUa2JoeJQM6nTQ/wJZ3wQ8kjV8HjITHCOhxPJUOSKmNHK zgxI7H1wx5RRgKwtET12dVLUPuP0DFBMpd1kfGMqSIbH/fMB03dZGf87MdeTeYL5vVaU 4vpDEjaN+3RRTMLD/FbeG82foy7To1uhXL7+m2ZyBVRqZIZ2kcVynozDDwzVqkTIWgnQ ndrA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=RjU+3Y0Q; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77097-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77097-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [147.75.80.249]) by mx.google.com with ESMTPS id e18-20020a170906315200b00a3e7eb17124si4123052eje.447.2024.02.22.10.26.10 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Feb 2024 10:26:10 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-77097-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=RjU+3Y0Q; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77097-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77097-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 7BDE81F220FB for ; Thu, 22 Feb 2024 18:26:09 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id EB748142639; Thu, 22 Feb 2024 18:15:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="RjU+3Y0Q" 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 DD565140E4C; Thu, 22 Feb 2024 18:15:21 +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=1708625722; cv=none; b=SzvzK7BRMQudOf+IXoaCIzjq5WKHMDlcLDcXUS94s/qQ/kbrxGMtzMtAjV/n+z9pocHZISUl/AmmarQ3Rh2bTAi/N6/qZzOc6Ye/bCKKsJEmn3zLQZXdyD8I02ev1YeqsOUxgHx9BJaxQkJAj0C0Ns2COr3tGLlyrVZz8DCgAf4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708625722; c=relaxed/simple; bh=EaHy6j+3RjBAOh9evmI3+WZxOll+3PxO3So+9Nmr8uU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=jegnbB8cXVlzVmd84BskGMRQFvMs/dIuu72PXvXK/HJVAWEGIejwDn55TWeAFdF8l4qsr9vfMfFSIhz9R3jDtAjxpq/BppuTOdGVhYhEGs1AhRUJTkSIB7Cmn+aQntMwoEItinhKCaBWCc4NVbr6ZNGZuMKMjVfpT0rOgA1oMvI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=RjU+3Y0Q; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 68C94C433C7; Thu, 22 Feb 2024 18:15:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1708625721; bh=EaHy6j+3RjBAOh9evmI3+WZxOll+3PxO3So+9Nmr8uU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=RjU+3Y0Qp97jEPnuwAWu+BVqwe3nBGiVfnsb3fmScLt0ALTTS7tb7tiFH4wV5EDag E3vB/U6lMRdIi4HMkaaKCOL+vI8HHQKNZVZ8LT5y8LCCB8Y3H1tH8yUHKulIp7KFw5 n99mXESPM9SY+waLgOqXT+6h4HV83u7Ov/OAw6xQnSSY7jIAfZ7OeCH38aTqbtii6W EXlgSoGmgukuEfYa81IrCc+vcxuZv5RJ/aWeFM4SLL2Cgw+gtXIS7eiundvcqt48Ax OGBtjWsBDXKz3Nh9CVoQOWniyNvnD1A3PMjBo37aQqTRybghDYqB7Zhv6frloL7Yj3 kqSQrNXjm0/Yg== From: Maxime Ripard Date: Thu, 22 Feb 2024 19:14:05 +0100 Subject: [PATCH v7 19/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: <20240222-kms-hdmi-connector-state-v7-19-8f4af575fce2@kernel.org> References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , Sebastian Wick , =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= , dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-sunxi@lists.linux.dev, Maxime Ripard X-Mailer: b4 0.12.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=9869; i=mripard@kernel.org; h=from:subject:message-id; bh=EaHy6j+3RjBAOh9evmI3+WZxOll+3PxO3So+9Nmr8uU=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKnX+76WG+1qX+3iLbfI5ee/v0ujGXtr93stk/3C/f7wf J27U7+c6ChlYRDjYpAVU2SJETZfEndq1utONr55MHNYmUCGMHBxCsBESg4y/LN70d5X9tV76wH7 DQeXrPR1uPya8fTPaK8td/dGfn6otf49I8O5S+f85DxE7j2R//ll9dL3y/byZgbJpV0N264edfC R0Wp+AA== X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791624604826359351 X-GMAIL-MSGID: 1791624604826359351 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 | 184 ++++++++++++++++++++- .../gpu/drm/tests/drm_atomic_state_helper_test.c | 25 ++- 2 files changed, 197 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c index 448b4a73d1c8..9f517599f117 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 @@ -662,6 +663,96 @@ connector_state_get_mode(const struct drm_connector_state *conn_state) return &crtc_state->mode; } +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, @@ -706,6 +797,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 @@ -729,9 +909,7 @@ int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector, connector_state_get_mode(new_state); int ret; - ret = hdmi_compute_clock(connector, new_state, mode, - new_state->hdmi.output_bpc, - new_state->hdmi.output_format); + 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 5a8750153510..f010fde0eb69 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); @@ -251,10 +248,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); @@ -272,11 +274,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); @@ -320,10 +322,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); @@ -670,7 +677,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 Thu Feb 22 18:14: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: 204965 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:a81b:b0:108:e6aa:91d0 with SMTP id bq27csp128275dyb; Thu, 22 Feb 2024 10:26:46 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCXA+koaeBkzpUTsqyIeBHMMEr66OVHl1nEmCHRdZ/tioXu9hGOdoi3M/fRjVFcm2/TWBk0Hm5pMmGScoB6qwYoecttGOw== X-Google-Smtp-Source: AGHT+IFq+zPztw3N6o2o+4XFMNwdY7kefh746oLGKSFHh9Z5mU+kJiWgR/K43qZJVkRqS7Vma3hx X-Received: by 2002:a05:6102:804:b0:470:50ff:d99d with SMTP id g4-20020a056102080400b0047050ffd99dmr10456284vsb.9.1708626406696; Thu, 22 Feb 2024 10:26:46 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708626406; cv=pass; d=google.com; s=arc-20160816; b=lgcPWsggHlLsdXXuUyQZ4VIZosO4H0aaHxn5ifGsmhG3onnLJMFCyLMYtEp6Xp8j6C YqwC646UT3+wUOpbFRCct5/Yg2NHL9Fbr1r5EYlb+Dt/sjJVWViyh1ANwYwuI+nIAdnU 3BA/EqhUPwcsmo3LsUltFa8PixwT79uU+S22BhAFCv3yOEu7VgMv12BFwsz9zpFP1b48 t2NZM7sGidq8WIAPEipnPuKsp7bRkkVDEU/p0S4BMvPFUsmUOmAeavqN8Qn7SMsKCPYh /n3iy7y+vWvjaFK5XOkUZlCCBS8AydNjjURU7B3UatbwiuFZVx+qyljlbnsOjRxba7cr 3FCA== 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=mWeCCN5S8S7vT8583bJKjGoOeLt9ZQ17DJ0BjuT8QGs=; fh=7mnR4/DMo6zaWtUGaVI9DND4TR+QGflpVaaXOChu5h0=; b=GeCjHv3rnx1qSp7GkiOOKfTqP6cfOJrVWd28gZhrexFaNrBLnLvN5zAaqvHgokXivD y6HIbnJO2mmOyBPTrpWRVZFu/cmlSgw+lzeSNvXrNILK4HMsbxq9BQqneTn3vjHYt2q5 vSfO/SaE2kAaBDS79XeraqPhgFbfgTprcQn9hnxWAAurJqs4ZagAn+Hp8VU/R6EIMH6S QNrw7HHl/mmpzCeuRYkyZquOE0cgewOnhknnV1H1rP2X5/F8NgQSQ84LXlyJPSk4rG4C UDVFa3foiY6amn3pxRVb5m23u0ailH4PzBLXGL8s7d2Y3XPtofTga1pTll03hazc+w1p ByeA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=up9s1MFY; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77098-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77098-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id e13-20020ab0168d000000b007da146821a5si595890uaf.75.2024.02.22.10.26.46 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Feb 2024 10:26:46 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-77098-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) client-ip=2604:1380:45d1:ec00::1; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=up9s1MFY; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77098-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77098-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 68A3B1C21845 for ; Thu, 22 Feb 2024 18:26:46 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 0702B143C4F; Thu, 22 Feb 2024 18:15:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="up9s1MFY" 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 D8A49142627; Thu, 22 Feb 2024 18:15:24 +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=1708625725; cv=none; b=vBdmI9+8xnuoKNzMJXOyfdpC03/9JO5kuoNWcNlpuOq36p9L0r7yDRENMrNrxoqcp/TWNUbXzN0d/JOVNib3/v/IsuXJmE8CGW74o3nB6J7VPNq+Kka2l1xLOEeimSfyaiFdj47lCGRTw08MV6gosSZ11Mx2x/13y2TTn2RaW9I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708625725; c=relaxed/simple; bh=h5rstC2WYwvm7YMXkakCAfnI4fHUDT3WB0p5AXm+6vM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=mp2OVLknfH/+cDpdZ5IGa4dvZXmk17/73LfUb9vJx1mpEpLfjWHGVToRTF4WRIP9QTAdVztLsYlhnUtDq5BuULOU7gf284me2fiV6yPfavwcfuV0sxgdRrA4qZuw02IUX6N/bY6uvpNxIvnjMfeNRW1HHVpKBI0P9kzi/1YOrE0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=up9s1MFY; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3F65EC43142; Thu, 22 Feb 2024 18:15:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1708625724; bh=h5rstC2WYwvm7YMXkakCAfnI4fHUDT3WB0p5AXm+6vM=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=up9s1MFYSyLlWXJy+F5QHCGaV6BE0DP6g0W2FFFLeAKUQ9ScHdp2EqUoiZr72kw8O KxBiCaO/BVQUckMLLVP8pzO7Urq7UMKKaJo1aBlloHGfVgMcg2N31Kec15WIurPn7w P1Uu29GEci27EdwesMg8TSsvYsi7iE29ss1cklFp0SeWfG8iBYNP8mAU0yRGpU0kSk jkZ/m+4uT3l2k60AOfYMGr+yk6xjgxMcr+HwT5wWhuDEo8uUNWCZnhN3VQ585DKnwq wnBpKr2EhUeCIYmcgnGsF288BkX7DgMVTo2vPImLU0QGTPK1txvZqeygBJAGds5Md/ Lhmdtnr6pS+XQ== From: Maxime Ripard Date: Thu, 22 Feb 2024 19:14:06 +0100 Subject: [PATCH v7 20/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: <20240222-kms-hdmi-connector-state-v7-20-8f4af575fce2@kernel.org> References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , Sebastian Wick , =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= , dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-sunxi@lists.linux.dev, Maxime Ripard X-Mailer: b4 0.12.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=26655; i=mripard@kernel.org; h=from:subject:message-id; bh=h5rstC2WYwvm7YMXkakCAfnI4fHUDT3WB0p5AXm+6vM=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKnX+766Skwwc2ee+dtq1rvXivl++hd7pSembonedXHS5 efT37KbdJSyMIhxMciKKbLECJsviTs163UnG988mDmsTCBDGLg4BWAir3oZ/nv35/XulokUz02d 8rV0i25k/cbv87d/CIvamnHuhbxHyVdGhl8rM+TeXnwxjW+12aLAKw4/VB5N1St8wP4rJfHM0/n NObwA X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791624642725050350 X-GMAIL-MSGID: 1791624642725050350 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 f010fde0eb69..c0f26422e925 100644 --- a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c +++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c @@ -370,6 +370,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 @@ -562,10 +612,464 @@ 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_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 Thu Feb 22 18:14:07 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 204966 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:a81b:b0:108:e6aa:91d0 with SMTP id bq27csp128292dyb; Thu, 22 Feb 2024 10:26:48 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCXXbCFGlVxDyym8lwTNWlW07Vsb/KXmURrJtQUc/9HoOXwHtRdWUrGxTugtgg63jIF3kaa7IeLJ0aS+fPs6L9JuSQM1rw== X-Google-Smtp-Source: AGHT+IHsqFQ41ceWEmrsTFDjCBzhdCR+etu/NxFic/TXoOBEASFh8C5hDUBX1NiZ0lFOQzjSEpZs X-Received: by 2002:a05:6a20:2d14:b0:1a0:de5d:170e with SMTP id g20-20020a056a202d1400b001a0de5d170emr487539pzl.12.1708626408557; Thu, 22 Feb 2024 10:26:48 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708626408; cv=pass; d=google.com; s=arc-20160816; b=me9MtJKOYjcD9HyJmidsORwSJ5Qti92SB/15JxfGBRJkFDXTJkKE+7PuVh373UwDpE S9INe6+5rXRL14r79f/DoI0vpWybpbVZmwqQPgeChoaPi5Bo8fml6N3X/NUse6d7kG24 jeXSo16qVXoSIs9tw1l8F+8GD+/1PngyCnMfvvpjoLMkhKUIEB0Dp7xC9GZcANLaMOZg h0nY2EcMglDo+BKWeBq87wXWquj4ZuAU5UW0KE+1I8k2MXyy0X4eK3S3OSOh9G11iysu QhPLDpSOLSGX9ur7jQ8TYDk/yRkDhUGenzrFnb3LfWWE4SCV+IMb38rxIhhFdfkHjZmc OPCQ== 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=p35DDIqxBDNeGcZUdFqqR5WYFKoudC+BNwdxZQgsJDo=; fh=8wcoxKk21hICD+6obVirG13fsSSMhKa/pufykSf87d0=; b=MYxpett2xSOKT+RZ31VpiSgckDf9cHTrDulHTDx17FxYXtySHzaR8TsJ4V1ka1kyW2 tWNL6z+2V4A8aU9Al1d1454asxw/TFc/WKM043Ksov677RHPU8AeRuG8naWIZzYz8tXO V1/KfkpBIXOgytwIj9NLeXLMAr20dFBZ99+RyKTqNCvA3EyImjE3/Me7KSgCvCeTPtQa iCbQCdSObv8vB+x8Vt88Z0KHXaLr9hwpOEK5zySW4lcLIFev5aLAFWcfVFcNFcfXPA8Q Oukuvr8bjVj3GkLvGL1VcnFPGmG2UphjFvIkugsKtIZamfF6fkLSl8kSSx529x4Dr0/I Ht7g==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=d7kwM96y; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77099-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77099-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [139.178.88.99]) by mx.google.com with ESMTPS id q19-20020a632a13000000b005ceb19326e3si10841857pgq.251.2024.02.22.10.26.48 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Feb 2024 10:26:48 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-77099-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=d7kwM96y; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77099-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77099-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 594F02858F1 for ; Thu, 22 Feb 2024 18:26:48 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 7237F143C52; Thu, 22 Feb 2024 18:15:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="d7kwM96y" 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 D41CB142649; Thu, 22 Feb 2024 18:15: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=1708625728; cv=none; b=qIvWuGZV49o0V03RvaWflDVJimXC9sVGrjlSNMTjkN9ueSk4msxtFGPH0kp8hme+iTaHwdwrecQKEiq/jqfNuG6f0OWywWkmQ5Kr7SEaup74oprbFs7UVcj9eOPpp8WosdaxALxffNrkS9rq2DPv59CWp0K0fKTRwPTS45I9Geg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708625728; c=relaxed/simple; bh=MTMvp3BqXkLMq3RJiTP9TnR6f7lFYScdyGPSAB1FsQY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=CMFJaWwh4Njl13AuQ6luCNmwJ2/srzFmJcLbAAJszEKjHnxBPTefMh7IAMES4eKmmdUlLI/gx7kHridrbevKSPRLs1MXuqpjEBPNVQQkzkQVekUZXN3S4bEyxJLFNP4ph3UVGaImqNmtIGtFEElcFWXHKSSSpGlujWw0U13KLpc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=d7kwM96y; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 284BDC43390; Thu, 22 Feb 2024 18:15:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1708625727; bh=MTMvp3BqXkLMq3RJiTP9TnR6f7lFYScdyGPSAB1FsQY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=d7kwM96y/LZskxh7/afLKuKzIQZc+vTRvmZMrstB+f4q/6smLVJx6NruIfaYURBcx uWlxSBK7P1T+FDehjcD3YUA78IzrgRYkumMpk4iJStVh+VYZ9WIHhvV4I/yDlVwHYa 5/GTXtdCqoZYQLRGer5R4UiEUgdxUO+2oDN9jQz3OsIDwYgalD8hQ65ZWEMUdAIOkS qc+mB8J2JZiA+SSC3avgQKmLke2Dcvo9RQW4GqOXeueEBPyIdo3U6MiRGqgzYiLX9W 2PbeQ0uEsyu3ireQhYljeFcM0hKgGNbdNwfY9xU3xXC/BRvZDQtv7bTQqhMXNIk0ah NAyDVTiuWhWiw== From: Maxime Ripard Date: Thu, 22 Feb 2024 19:14:07 +0100 Subject: [PATCH v7 21/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: <20240222-kms-hdmi-connector-state-v7-21-8f4af575fce2@kernel.org> References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , Sebastian Wick , =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= , dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-sunxi@lists.linux.dev, Maxime Ripard , Dave Stevenson X-Mailer: b4 0.12.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=11940; i=mripard@kernel.org; h=from:subject:message-id; bh=MTMvp3BqXkLMq3RJiTP9TnR6f7lFYScdyGPSAB1FsQY=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKnX+769ZVAO8Ayakvzv+NSvhlt12bZseN3tXsF7WGbxp APVU4Q9OkpZGMS4GGTFFFlihM2XxJ2a9bqTjW8ezBxWJpAhDFycAjCRyzcYGab2zXy0ZOI5+djd l358PCJqv0ljSbjSaTnHRzOcTbMFTpky/PfKmeNYZn+6od0080t9uNb7mldamRclp2zbMZtbfH9 1BgcA X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791624645089463263 X-GMAIL-MSGID: 1791624645089463263 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 Reviewed-by: Sebastian Wick --- Documentation/gpu/kms-properties.csv | 1 - drivers/gpu/drm/drm_atomic.c | 2 + drivers/gpu/drm/drm_atomic_state_helper.c | 4 +- drivers/gpu/drm/drm_atomic_uapi.c | 4 ++ drivers/gpu/drm/drm_connector.c | 89 +++++++++++++++++++++++++++++++ include/drm/drm_connector.h | 36 +++++++++++++ 6 files changed, 134 insertions(+), 2 deletions(-) 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 26f9e525c0a0..3e57d98d8418 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -1145,6 +1145,8 @@ static void drm_atomic_connector_print_state(struct drm_printer *p, if (connector->connector_type == DRM_MODE_CONNECTOR_HDMIA || connector->connector_type == DRM_MODE_CONNECTOR_HDMIB) { + drm_printf(p, "\tbroadcast_rgb=%s\n", + drm_hdmi_connector_get_broadcast_rgb_name(state->hdmi.broadcast_rgb)); 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)); diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c index 9f517599f117..0e8fb653965a 100644 --- a/drivers/gpu/drm/drm_atomic_state_helper.c +++ b/drivers/gpu/drm/drm_atomic_state_helper.c @@ -589,6 +589,7 @@ void __drm_atomic_helper_connector_hdmi_reset(struct drm_connector *connector, 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); @@ -913,7 +914,8 @@ int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector, if (ret) return ret; - if (old_state->hdmi.output_bpc != new_state->hdmi.output_bpc || + 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) { struct drm_crtc *crtc = new_state->crtc; struct drm_crtc_state *crtc_state; 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 591d2d500f61..6ffe59d01698 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -1212,6 +1212,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); + static const char * const output_format_str[] = { [HDMI_COLORSPACE_RGB] = "RGB", [HDMI_COLORSPACE_YUV420] = "YUV 4:2:0", @@ -1708,6 +1731,39 @@ 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. + * + * This property is only relevant if the HDMI output format is RGB. If + * it's one of the YCbCr variant, it will be ignored and the output will + * use a limited quantization range. + * + * 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 @@ -2570,6 +2626,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 8cda902934cd..bb6b6a36ade3 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -369,6 +369,29 @@ 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); const char * drm_hdmi_connector_get_output_format_name(enum hdmi_colorspace fmt); @@ -1041,6 +1064,12 @@ 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; + /** * @output_bpc: Bits per color channel to output. */ @@ -1753,6 +1782,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) @@ -2092,6 +2127,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 Thu Feb 22 18:14: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: 204991 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:a81b:b0:108:e6aa:91d0 with SMTP id bq27csp135156dyb; Thu, 22 Feb 2024 10:38:55 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCXpcbe/C+snz4l/sQoKeLdDcu149/rV8w4btSO0kOpfb/P2xqIVs/MTwFWI2bkwbhMH1SbRpzqVI/ma4BYKSuxXQnR64g== X-Google-Smtp-Source: AGHT+IHnvC8tBMZ+4YxIwXpKwNs14NnCuaKgq9M3mHADrf/m0I1+50hpnQf4zDwnSFtFppIR9LrF X-Received: by 2002:a17:902:ce85:b0:1db:d120:5cda with SMTP id f5-20020a170902ce8500b001dbd1205cdamr17271095plg.11.1708627134960; Thu, 22 Feb 2024 10:38:54 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708627134; cv=pass; d=google.com; s=arc-20160816; b=pN9SB0Dusc49Pc3KBP8g2I+lrFy1jDnNOuXBaTlmSgf+p0eU60msppuNjIZkJuvXu1 Ie3U3RF+jwWyxvW7+ABYWalTDk0o9gw9sltOHOMyQkpX0CNHFQLGzbT2cTl8oBcZ2EFM Y1IctL8hPw9mNZ/1HEJ/upF8+Hg4x/zXWOCNQZLIu3Ghb2mn9LLXlp6G8SQaksdt20Gg DCCsJgF1M7uksiv3pIRz9FD7AqbghYU/pzFyhRcw7u7tclJOsMcDVBxgMOFOBtQnxPvx Ion3/DITCywVDLFodNQfez/VyG4ynRCRQeOvhJN0zzbpgCQ4qMTEt9phdgONYujGIit2 8Jug== 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=M8c3Auu59Ipi9AzkvKm/WW0A07XkhRITDY5Gd3+5sks=; fh=8wcoxKk21hICD+6obVirG13fsSSMhKa/pufykSf87d0=; b=l3Z8DhsPSWcZwz9YyjybgcmkwhuVhd9hGZ1EcBJkTs3luoyEU3PZJms8XOKJhLmIYw DyLM1osoavOSEJhdL4Egjq2XFlzDlDp2jdmnIN/Shv+tFq0yBU2uTvOhbi45C5KglLfo iP/z8zjhDS4gyHdk6McwLMi+IY3DTzACKQlLMRnJYirjAKoIi2hPDw06QwTmvlADa238 csB856R1wvPd5xvKdaNeX0AhXIIYu6SYXLGMLHEjtu8BbConVOZw/qKDdZ6XIL14R4Wa FuIE1goDOaulSxBBdndpTWWDwRwzpA2BVi1d0dG69z3Zu/e1Tg2l1adNV5It7ZY5m02C J6rg==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=PpLGYfkq; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77100-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:40f1:3f00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77100-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from sy.mirrors.kernel.org (sy.mirrors.kernel.org. [2604:1380:40f1:3f00::1]) by mx.google.com with ESMTPS id w30-20020a63af1e000000b005dc9365a903si10979416pge.704.2024.02.22.10.38.54 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Feb 2024 10:38:54 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-77100-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=PpLGYfkq; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77100-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:40f1:3f00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77100-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 9E40CB24D01 for ; Thu, 22 Feb 2024 18:27:12 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 19DD415957C; Thu, 22 Feb 2024 18:15:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="PpLGYfkq" 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 879EB14265B; Thu, 22 Feb 2024 18:15: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=1708625730; cv=none; b=ZwuVpGOB4VVtHGcAvpk1Gt926N1Au60V6iQD7URE0rO/aoapdzSbUqy27i4hqVRUogE5ojShTv/jw7FcPd/ImPZwcUdrY5TsEuwVjbkzQRaabj9r+jEqXNhUtEtjLznCjOg0aDAfJhgyQFgg/5550mvpspZAOEbHlkr4t8+/0EY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708625730; c=relaxed/simple; bh=MnAMc9YgC+tVs4lR8Oy+j36YZ/eTfxmPaM/u8EgA1Lk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=AGhWAnOPyEAyVy8Y0NExEFYrYtqcwJEtYC4tDDYpDFHPYvqdfvqJDtKdwXjJ0yUS415h4Y/8GXMTOFiirp6QtEAvcqtj+P2z2G32jTBG8WBgHPkplSsHzzOhJjiAFucdbCmFujFZqnW/EIQecUXbHj5Kj+IzMw4J050j0r08kuU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=PpLGYfkq; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id CAA34C433F1; Thu, 22 Feb 2024 18:15:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1708625730; bh=MnAMc9YgC+tVs4lR8Oy+j36YZ/eTfxmPaM/u8EgA1Lk=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=PpLGYfkqxdHMeTQuIpb2DqL95MY87gbeqfnkerIu2eo6Od9UHcEOSs57rD1G0UMzn 1wUVnOF57i4Ytv+Q4DgyizBecakP7hI0a8dO1+E39gyjOaeKfyNNMAuS5xjTrSoIW+ 1YLkfBtr3NL65JKqoWjW3GKo+K5e0diXVYFvJgOqP5FOj+YcRVKS0oq7+5pxHq6g/f eIr4dZaAsXLCw/x7X5eqzSFQNj9xi+FIUES/NA7YK1YDFOApxPHxmjaDEPT5KW8mxD VderxLkVaE/2MNl+sR36BKckv6KWPZ7EaAAm4/Ett7NFCqG+2t97EVzUQh+k+iDdAA 8XUxTGT9Ft1cA== From: Maxime Ripard Date: Thu, 22 Feb 2024 19:14:08 +0100 Subject: [PATCH v7 22/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: <20240222-kms-hdmi-connector-state-v7-22-8f4af575fce2@kernel.org> References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , Sebastian Wick , =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= , dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-sunxi@lists.linux.dev, Maxime Ripard , Dave Stevenson X-Mailer: b4 0.12.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=12623; i=mripard@kernel.org; h=from:subject:message-id; bh=MnAMc9YgC+tVs4lR8Oy+j36YZ/eTfxmPaM/u8EgA1Lk=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKnX+767TZa4HtQTkubrO+fpddOSvV/Fwg6r/uSU9S7uC +NwOczdUcrCIMbFICumyBIjbL4k7tSs151sfPNg5rAygQxh4OIUgInsbWD4zWL5NfqW+4T7Wziy XtxcJ7hk9YYN8iemsHjab4y3nhSdIMHwP/yPx0GGA2G3UoqnvXq6TZ7n7sK/jwSTmpndY0NFnPZ P5QAA X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791625406595810422 X-GMAIL-MSGID: 1791625406595810422 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 --- .../gpu/drm/tests/drm_atomic_state_helper_test.c | 151 +++++++++++++++++++++ drivers/gpu/drm/tests/drm_connector_test.c | 116 ++++++++++++++++ 2 files changed, 267 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 c0f26422e925..3de15cec2f5f 100644 --- a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c +++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c @@ -224,6 +224,134 @@ drm_atomic_helper_connector_hdmi_init(struct kunit *test, 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, + 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); + + 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, + 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); + + 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); +} + /* * 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 @@ -1059,6 +1187,8 @@ static void drm_test_check_output_bpc_format_display_8bpc_only(struct kunit *tes } 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), @@ -1090,6 +1220,26 @@ static struct kunit_suite drm_atomic_helper_connector_hdmi_check_test_suite = { .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, + BIT(HDMI_COLORSPACE_RGB), + 8); + 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); +} + /* * 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 @@ -1207,6 +1357,7 @@ static void drm_test_check_tmds_char_value(struct kunit *test) } 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 732c59a1d4d5..6a3651b08c81 100644 --- a/drivers/gpu/drm/tests/drm_connector_test.c +++ b/drivers/gpu/drm/tests/drm_connector_test.c @@ -564,6 +564,63 @@ 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, +}; + struct drm_hdmi_connector_get_output_format_name_test { unsigned int kind; const char *expected_name; @@ -622,6 +679,63 @@ static struct kunit_suite drm_hdmi_connector_get_output_format_name_test_suite = .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; + 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, + &dummy_hdmi_funcs, + DRM_MODE_CONNECTOR_HDMIA, + &priv->ddc, + BIT(HDMI_COLORSPACE_RGB), + 8); + 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, +}; + /* * Test that for a given mode, with 8bpc and an RGB output the TMDS * character rate is equal to the mode pixel clock. @@ -945,8 +1059,10 @@ static struct kunit_suite drm_connector_hdmi_compute_mode_clock_test_suite = { 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 Thu Feb 22 18:14: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: 204967 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:a81b:b0:108:e6aa:91d0 with SMTP id bq27csp128569dyb; Thu, 22 Feb 2024 10:27:22 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCW3S3M2BTHAAnYGoyegmnJayGFy0hz4XOeWuah3BT0aAh4JqmYGMRtXLNcfN0+5bnLhbTVmFf9HgB6ei8qqHjFALsxKgA== X-Google-Smtp-Source: AGHT+IGWDj4jozw5/pzt8HwFXpWGw7d0lI126fx+YUPDrr/YbBGuF2c/VDLNpEE51hnv1SfH3oeX X-Received: by 2002:a67:fc58:0:b0:470:4e67:3b38 with SMTP id p24-20020a67fc58000000b004704e673b38mr14727171vsq.14.1708626441927; Thu, 22 Feb 2024 10:27:21 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708626441; cv=pass; d=google.com; s=arc-20160816; b=TV4nEIfRVOMj/rB1KRGUa6rQiSamPrI+FYAchymziZWD+HCzet1DRt7bL11ZrEU5nL oHaltqtX7aSqia7zjRYpSFcq69hz7mbl2KKJuQ1HESk2FN++z2vC25V6C7opGCliBfnF nV2qwGmDvt1foyRbHSaziGpHQzZ1a6+ropOpytemAhNSewqh4oRxbANaX30UpLLt+jvD 3KsYaCgT2ea8TGwk6VZrUTicV0J/NtemdMP1EdEdcthcI1sSm4w8bfJv1n3hhuTMma13 kTDX6RkdNZv2BnewIAYSbHnd0hTPqiVv776JaD3j+UZAIiofZIxHYjYL2uPSEkw5UxY5 6wvQ== 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=OtP/yhynBf24PtYb1Fz/R2A7ZkG4Dlj3xglDToGp4vI=; fh=8wcoxKk21hICD+6obVirG13fsSSMhKa/pufykSf87d0=; b=mWlH0fTyS/hOxEXTFgcaIE6UMq42Vi0+GabSxYBT7ybg0IDl+8tVIZmOvRIwaUS2vV K9wRKmkwibEXa6QmYmLMbgC3D8hq8NTVE+kBtq7G7XbgGae2cYKD4WsSojpJmVUaai6e 0at1BqNyWhnaRrUDf/Jcm/dC4tu1oi7c+0q5hQW2yW2TKppM5zLks8Y3G4EMzNTp+pCa qjtA7pdY+k2xvOCvvhV0qI+bRYVexJHUpgzM8by0ic+ROp1i5VofvcKoD6C9v1xcxKoO 5d5hVxuSeiLD1oJGD07X1Z6GjUM5ib0uLtv+jIP8+9IrjxYs8/pZnFyj4Gpzifc9oAMP CMMQ==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=kQs8PYuK; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77101-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77101-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id a19-20020a05610222d300b004707a5017d5si868249vsh.661.2024.02.22.10.27.21 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Feb 2024 10:27:21 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-77101-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) client-ip=2604:1380:45d1:ec00::1; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=kQs8PYuK; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77101-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77101-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 AC0861C20E62 for ; Thu, 22 Feb 2024 18:27:21 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 4A9871448D4; Thu, 22 Feb 2024 18:15:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="kQs8PYuK" 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 5FAAE143C61; Thu, 22 Feb 2024 18:15: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=1708625733; cv=none; b=bLkDclKO+92TFSxzvu+jaHLFOqwd1RsRW9uO2if2GIkaGVDga1S6R2tcEAWCe8Qr0ZX8/sa3jmXbXcPSnN3y/8JvNIDoAFFDQvoqGhhBdrY/9Ds4l402BuqIQrPof7coRNxy5yEim4S2kkdXJTlbrCuJ3UN2+Ce7kNmfa9gP8Dw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708625733; c=relaxed/simple; bh=1I2pPlxI3vCCE9moTWhTTQHMRZBIhOmA5gBHqcZ2PGQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=nE3WXd0ljd8H0uNqLO0h5zhCdKvIO/AEo3+78UcGYHzgoUnqMv2FF6WdUbHxkEHwKbiXHSDg8PxdypLuL/wc5onc6yYTqa1DS/2SEQg5MzutAq42J37ablxHWaNyhjjzeORT7tCd4xUFrN1mZFQVDMMHB08klpzYcXH1RmwjF6g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=kQs8PYuK; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 88EF0C433F1; Thu, 22 Feb 2024 18:15:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1708625732; bh=1I2pPlxI3vCCE9moTWhTTQHMRZBIhOmA5gBHqcZ2PGQ=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=kQs8PYuKf2BOoFOideBCM2lSWzNAzIt4JW4S48egW54sW8bSaH7i+HoZ3sw7JXLzR oVNrchSGET6wc+/X1s2PU0aHysK3vuvBBStPoOqx8VJjxkollvwLGOb2hgF3t0AQ2+ kgCzosB3yrbGBlz8RkNUx8sMgvxSOYrf0RCKdyrEtf49sSprjerDXV0HLExiz4rmzs PDNVf18oA/TVuGDwvwsgFyTOJyB64H6uc6UElcGk5h5LPPgJ1pM0iKS+aB77dn/f7V rPwDdrHo6VQMiIhiRfZfLbqbbcr+Kc9npYUhSdD+N8498pVYjRCfY1cLne3XG1mWga f4GkNkUyiz9YQ== From: Maxime Ripard Date: Thu, 22 Feb 2024 19:14:09 +0100 Subject: [PATCH v7 23/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: <20240222-kms-hdmi-connector-state-v7-23-8f4af575fce2@kernel.org> References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , Sebastian Wick , =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= , dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-sunxi@lists.linux.dev, Maxime Ripard , Dave Stevenson X-Mailer: b4 0.12.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=3455; i=mripard@kernel.org; h=from:subject:message-id; bh=1I2pPlxI3vCCE9moTWhTTQHMRZBIhOmA5gBHqcZ2PGQ=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKnX+77fEvb6/ly444irUtcEwZxFuzWexthlX7f0yPpzV 6CgSLazo5SFQYyLQVZMkSVG2HxJ3KlZrzvZ+ObBzGFlAhnCwMUpABNp+snIsD+C52nM8eWRz4Mf FJm8/6j1zu+NgVUns52pr5x2z+tX2xn+eyWXlh3g/9lpeayQicN859aZrHk5n+qDow5XK3t2zmB lBQA= X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791624679767465831 X-GMAIL-MSGID: 1791624679767465831 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 | 1 + drivers/gpu/drm/drm_atomic_state_helper.c | 29 +++++++++++++++++++++++++++++ include/drm/drm_connector.h | 6 ++++++ 3 files changed, 36 insertions(+) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 3e57d98d8418..ec6c6beda5c9 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -1147,6 +1147,7 @@ static void drm_atomic_connector_print_state(struct drm_printer *p, 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'); 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)); diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c index 0e8fb653965a..e66272c0d006 100644 --- a/drivers/gpu/drm/drm_atomic_state_helper.c +++ b/drivers/gpu/drm/drm_atomic_state_helper.c @@ -664,6 +664,33 @@ connector_state_get_mode(const struct drm_connector_state *conn_state) 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); + + /* + * The Broadcast RGB property only applies to RGB format, and + * i915 just assumes limited range for YCbCr output, so let's + * just do the same. + */ + if (state->hdmi.output_format != HDMI_COLORSPACE_RGB) + return false; + + 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; +} + static bool sink_supports_format_bpc(const struct drm_connector *connector, const struct drm_display_info *info, @@ -910,6 +937,8 @@ int drm_atomic_helper_connector_hdmi_check(struct drm_connector *connector, connector_state_get_mode(new_state); int ret; + new_state->hdmi.is_full_range = hdmi_is_full_range(connector, new_state); + ret = hdmi_compute_config(connector, new_state, mode); if (ret) return ret; diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index bb6b6a36ade3..3eaf4d54364d 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -1070,6 +1070,12 @@ struct drm_connector_state { */ 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; + /** * @output_bpc: Bits per color channel to output. */ From patchwork Thu Feb 22 18:14: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: 204968 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:a81b:b0:108:e6aa:91d0 with SMTP id bq27csp128979dyb; Thu, 22 Feb 2024 10:28:08 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCXyBFe2tB7k2mGM7HOInATDjFU6wxTy9n0lnebIsDRlCau+G8k1wZFtg8w+M2ngWbhBS+CapkfTYJjqtVJnPO4PlHREVQ== X-Google-Smtp-Source: AGHT+IE4P2XBPbAnUn5MQnyAlP5Or2dTDEAvtxx5CWQu2vSf73kq+BypbKg2LH1StyTacR80lbJf X-Received: by 2002:a1f:de41:0:b0:4c9:98f8:83ce with SMTP id v62-20020a1fde41000000b004c998f883cemr2815701vkg.6.1708626488595; Thu, 22 Feb 2024 10:28:08 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708626488; cv=pass; d=google.com; s=arc-20160816; b=I3WE6vTKh0x/qLNU9sJw9MzEv3Fe6bpel5ZNLkYdyWlJNE8eMU9H4FIjubX42pctcL 6xmkmea8Wp7W71GNmTYf107geK9uYdjr6PUcu82iMfhsBviHxXrSs68LI8odBIz4HqoI ZvOysWgEPxxUX4iMKlT2LoXRe+MR/e/YVMMXb8AnoeNzGfT1n6/HWb4vMmYUJvOgGvkh VuRYzFGjx21ajWKoFBm1NE8ByCkYpnGIUqv4zK81LJvFlynXAQkQoNecuCLjmatfFQSY Cqp9DWCoRZdWOOzLhPG/y41VNvBSxaoaj0NONAHDseXlabvJ35vkWSUVZJU+1MBsE9E+ /vbQ== 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=bMYndd5DSUKyUWC69sDsCO76971rw57VNMeyVCanWWQ=; fh=8wcoxKk21hICD+6obVirG13fsSSMhKa/pufykSf87d0=; b=Xzqcn5iKFNgR9waNILgd0V6pm82Hy5HZl7CfTwcFrUm0ELeWJxIc621oSHG6PQYGoD aPU99ZIphIpjDHYjZ9e/O0UN3UpiKUSHX1VuSNyAOrAr+hxwQMNFo11uSEpXI7pOpVD/ 4KcGyk3fQ00pwh4cVLkVv5h9L4LkECGrEy4s6L/PJ+bi6IsjisyON2e6rgAUwPXw7sMF mp0SL530OouRTqd8cRC7reZFq2MHzscRv9CqgEs4MP+2Z1vvcBvnux5hU9pNZ/3/1MPy +JogJkB7pdeYoW+7Kqg3L9Myd4AcZkTN3NSqBPg/niaghwaGG6xM6s3rGEpHdiFNIG2B /SOg==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=iWx54QBi; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77102-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77102-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id l17-20020ac5c351000000b004c8524b9811si1798906vkk.215.2024.02.22.10.28.08 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Feb 2024 10:28:08 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-77102-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) client-ip=2604:1380:45d1:ec00::1; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=iWx54QBi; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77102-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77102-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 487031C21246 for ; Thu, 22 Feb 2024 18:28:08 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 20AC9146E81; Thu, 22 Feb 2024 18:15:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="iWx54QBi" 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 B81A11448C1; Thu, 22 Feb 2024 18:15:35 +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=1708625735; cv=none; b=pzIeQdnm/mA0cIJABcB+gG68Fp2uPLbsIyW6Hx94G3PVlGn/wZ9sDIuglEJIGiGXoahTa/Za6LTvcY4r0RYvVlI6c9IfZOfcBt1tYQJu2HKhOykx1ShKKIlkAOvhuorI4X4SGEq+P8JkCObucC4+N1ajW1SgHF1Nl8cYtTL/+p4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708625735; c=relaxed/simple; bh=HYoEKDS8TyIrg0NCnbh0Iz88vyQKRz81a5SMV/XOgjY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=SagTQzgptNAiNVwdth0QOYkkh6e3mh/fxJVOeqnNoOdKj0a6ibjmNc26UDvmACGCFVd4csWJe42zDjoiYj2kvQhGflD7XuLAOAzWmtdtDZ8qaB8nwoZQlnyZTEJdh5mxWAgfscjr41pPgsBxWoaOB60ZthaPAcqE1t/Xqraiscs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=iWx54QBi; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 44F60C433B2; Thu, 22 Feb 2024 18:15:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1708625735; bh=HYoEKDS8TyIrg0NCnbh0Iz88vyQKRz81a5SMV/XOgjY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=iWx54QBiNi/61fkCY9kWEcGmmNbOpL71mR0oRYltUy/sFBUa7Aoe6jEO+UmvT/GSv YDpRc4rmUuc8+0Y/7CEgZMVnaL7fdRoPMx31/MXh7PXQukJo+cc4xkoH5CfgjtnPdc dSF+ZZ8HilqjeGLpXo4PV0gZzzLciLwmEflJvD0a82xXxRfCo1rUGmsL135GemfqKr Is1GbHS7eDIXDvqmm35927M/Yjj9S3uqpG6QakEC3+svhlKyDrHPmQRJS+akzz9pGb XqEygD6NmtKwZtDeO77VFzbI7qNSA5GafEIN0+z9+3V1HCqpQJDuyZbrjC4E0SGOWN Z1aFggFn7hLsg== From: Maxime Ripard Date: Thu, 22 Feb 2024 19:14:10 +0100 Subject: [PATCH v7 24/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: <20240222-kms-hdmi-connector-state-v7-24-8f4af575fce2@kernel.org> References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , Sebastian Wick , =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= , dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-sunxi@lists.linux.dev, Maxime Ripard , Dave Stevenson X-Mailer: b4 0.12.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=20542; i=mripard@kernel.org; h=from:subject:message-id; bh=HYoEKDS8TyIrg0NCnbh0Iz88vyQKRz81a5SMV/XOgjY=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKnX+348f+JZaFvRPTHrkGb+SuOnBXP+BLrLn7jCLralz dlzjSFPRykLgxgXg6yYIkuMsPmSuFOzXney8c2DmcPKBDKEgYtTACai18zwv9BkSupSAYNpgbOF FjP2q9fvvxC66AG7axDf6lfioSqX+xj+mWnk3Zn/e8q8p0Gzb9mtEBKuUbmXqd4X4RLkmfzrhI0 IDwA= X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791624728624318428 X-GMAIL-MSGID: 1791624728624318428 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 | 563 +++++++++++++++++++++ 1 file changed, 563 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 3de15cec2f5f..dcc0f7486f49 100644 --- a/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c +++ b/drivers/gpu/drm/tests/drm_atomic_state_helper_test.c @@ -352,6 +352,560 @@ 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, + BIT(HDMI_COLORSPACE_RGB), + 8); + 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, + BIT(HDMI_COLORSPACE_RGB), + 8); + 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, + BIT(HDMI_COLORSPACE_RGB), + 8); + 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, + BIT(HDMI_COLORSPACE_RGB), + 8); + 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, + BIT(HDMI_COLORSPACE_RGB), + 8); + 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, + BIT(HDMI_COLORSPACE_RGB), + 8); + 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); +} + +/* + * Test that if we have an HDMI connector that would use a YUV output, + * we always get a limited quantization range with the Broadcast RGB + * property set to auto. + */ +static void drm_test_check_broadcast_rgb_auto_yuv(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_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), + 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); + + 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_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_ASSERT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_YUV422); + KUNIT_EXPECT_FALSE(test, conn_state->hdmi.is_full_range); +} + +/* + * Test that if we have an HDMI connector that would use a YUV output, + * we always get a limited quantization range even if we have the + * Broadcast RGB property set to full. + */ +static void drm_test_check_broadcast_rgb_full_yuv(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_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), + 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); + + 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.output_format, HDMI_COLORSPACE_YUV422); + KUNIT_EXPECT_FALSE(test, conn_state->hdmi.is_full_range); +} + +/* + * Test that if we have an HDMI connector that would use a YUV output, + * we always get a limited quantization range even if we have the + * Broadcast RGB property set to full. + */ +static void drm_test_check_broadcast_rgb_limited_yuv(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_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), + 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); + + 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.output_format, HDMI_COLORSPACE_YUV422); + 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 @@ -1187,6 +1741,15 @@ static void drm_test_check_output_bpc_format_display_8bpc_only(struct kunit *tes } 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_auto_yuv), + 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_full_yuv), + 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_limited_yuv), 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), From patchwork Thu Feb 22 18:14: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: 204971 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:a81b:b0:108:e6aa:91d0 with SMTP id bq27csp129315dyb; Thu, 22 Feb 2024 10:28:40 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCVhVdmHSJLzC7pj1thcdcKjg8wwag95D6hG4acE4EPdBtITtwdge0A4Dp/g8AcaFmm+mZXrBhP26eleDk+XK9bY0zdNDg== X-Google-Smtp-Source: AGHT+IHLo4C2I/JqPcHw9sXDa3Gd1FnuHphFqa4tDvO/WBSHJknxWVsYHiwgRK/fqarWoLRpvuu4 X-Received: by 2002:a17:906:3499:b0:a3e:d7fe:4c4d with SMTP id g25-20020a170906349900b00a3ed7fe4c4dmr7417383ejb.57.1708626520130; Thu, 22 Feb 2024 10:28:40 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708626520; cv=pass; d=google.com; s=arc-20160816; b=A0D94bI9ukFjv2QFbtUpirzt5giIMAnW/tc/3yXXlfj59e5Iv09+pqjYyruIePhD1h qz1vLblensRq3ExPbG4OY6XISLFU5kJwo9F/ORusIM/io9Zbw43wHAyB6xRDvNNrv9vi jFZqq4XRS/01Jl/1l9yDieLThHSETCAuDP0dLtPqVWkp39TQunYn+VSPmO6ElgORdShM DYjJQM8HGLlsyOoCDr4IpKnHV/alMJrVFDl/I/NSMRgmjaizm7BHEHMmEzgoJ8lCOq3e UCeX5SgTOpMfp4DxlHiw+QaOGQh7ZuPJB6uMb3GxvofpSSutJuAU/TWmoqq4g4T0mmRc E2xw== 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=Cb7Ovx8YfbM92Zhjd7X6zKbwtYgONJkrx9bRYIbmJc8=; fh=7mnR4/DMo6zaWtUGaVI9DND4TR+QGflpVaaXOChu5h0=; b=J/TOWC5VIZBY0Y54+/N0pGv76ot6MhWJqbKrYGYznzyLi25z4rgGKg0u89/3biclZo M7DKm5624E+Zv06OhbAwaTHWzwJYzwpyBKHYa0GHoxcPEjvHDBFPhcP9KbjiBB8CUoiD 1WjO4/qyJMTA2AWHbHMuY1i4+belSZzqNojlVBTilEPSHDFfJxNQUzUq4pBcmMdANh0/ 4UNIrqvHmRQsHzP6d6E7P9uFg4vLC/EzvsXwHH/ltnmzEnn5eMjkcIX8PV1PZ68W4L4c yKBVqHPiPsft3CzTpYeyrjI51O1hPJ++WpzvD7K/FW24kpSsjviPKcECnNB8yRI6Njx9 AxDQ==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=Z1l+8MnX; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77104-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77104-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [147.75.80.249]) by mx.google.com with ESMTPS id rs14-20020a170907036e00b00a3e9671aafasi3885252ejb.259.2024.02.22.10.28.39 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Feb 2024 10:28:40 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-77104-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=Z1l+8MnX; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77104-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77104-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 8F8DB1F21788 for ; Thu, 22 Feb 2024 18:28:39 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 6701E149393; Thu, 22 Feb 2024 18:15:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Z1l+8MnX" 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 AF8561448EC; Thu, 22 Feb 2024 18:15:38 +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=1708625738; cv=none; b=gLcK1xH7OuANnNptWMBtdfSNbY8+u22fMvc9Z3XENbn11l+sGjUQu4kHv6WywQdPUCFnZUHVq6D/ZRtHyGyWqVP8qQEolEY2ftvdapvrGZQa/zOSymwdMYki2c8kYKEYGK83FGToVadmHmklid+hT/swCdSKkeidyspZ67rlShg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708625738; c=relaxed/simple; bh=Sv952kUg35w8ohzZt1Mz4pW9NhuYU38kQhpxszfneXg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=NG7fqT/uKTGeeahDsao8KAI0yBsUAW2RGr50RUR9FmTvi0dUe2BkCVmp96ERgTDHrDNw4gzIMQBtqXWtJr33t7sAbn4hX+O6r7+XyYAtmDWYatXkxsvN6OROBkjK/IJRyVKb8yFAyd0hIOwfP5S2nv0luNP1kP1auktBUnIJyIc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Z1l+8MnX; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0DA9BC433F1; Thu, 22 Feb 2024 18:15:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1708625738; bh=Sv952kUg35w8ohzZt1Mz4pW9NhuYU38kQhpxszfneXg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Z1l+8MnXlzxJR8qS45HAn7AiZ4XD11vaTbbGJbs/KmC+Agbpx7JRD50Rm5ww/LwJ+ ZzOo0Y3Fbxjm7AzpIi3P547D+nMYN1CohnkqpuwWMHw6VoJ6+/e2hb/V1xsWpCoXIt gaGjufF9aDeEcLxe/Rk7e8lcYUH9DqmfiR5Iwer4hrjKFgIzGAzflAmMj2B5RcB9K9 wlEzM+XtTcgxifMddI9OY9ioMqw7NPoGwcwUyAT3eTJ2JgB4Q57qc/E87fy2zVA7K2 AkXaW34OK0ynrm5P7uLB634tVRkxRaUSS7Jd4O7szihXrWMJ4KNCGX4SUMvkoQ2pkk 5y+jGRms0tnyA== From: Maxime Ripard Date: Thu, 22 Feb 2024 19:14:11 +0100 Subject: [PATCH v7 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: <20240222-kms-hdmi-connector-state-v7-25-8f4af575fce2@kernel.org> References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , Sebastian Wick , =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= , dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-sunxi@lists.linux.dev, Maxime Ripard 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=Sv952kUg35w8ohzZt1Mz4pW9NhuYU38kQhpxszfneXg=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKnX+376eF+/yzNl6skvk75dfPVqHuNdxgtNWnXO7h+/l QdfN3QR6ShlYRDjYpAVU2SJETZfEndq1utONr55MHNYmUCGMHBxCsBEHBYy/K8Ru3L0c+KuP0dt nIzKt8sJhfpWueScnHx/793HtwyYomsZGb5UZG6fbpV3UVC87l8nw6Y3rS79pavqWF8d6/P//uZ 9MA8A X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791624762307595620 X-GMAIL-MSGID: 1791624762307595620 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 e66272c0d006..46d9fd2ea8fa 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 @@ -914,6 +916,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 @@ -943,6 +1081,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) { @@ -960,6 +1102,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 6ffe59d01698..6cfc301096ef 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 dcc0f7486f49..b28409fe65dd 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 Thu Feb 22 18:14: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: 204970 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:a81b:b0:108:e6aa:91d0 with SMTP id bq27csp129277dyb; Thu, 22 Feb 2024 10:28:36 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCUpEKBzaben4X78gi5dtJUe857FClkhjWUPgHUfy5AhmY3Yig4xlVYirxDLibP8TebO2SBRSh6mznUyAg8uS1cOtqE9Dg== X-Google-Smtp-Source: AGHT+IHF1iTysBxBD3+JxavDPNe3uyZ/rFoSOAGITqgPlH+SBtWvoPAUZhHO5yejJos/1q8rzkPP X-Received: by 2002:a05:6a20:d38f:b0:19e:a1ae:944e with SMTP id iq15-20020a056a20d38f00b0019ea1ae944emr22408466pzb.37.1708626516433; Thu, 22 Feb 2024 10:28:36 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708626516; cv=pass; d=google.com; s=arc-20160816; b=YOsOs+X+Tk+0W1jHsvXSFBcHS1h1G0LUQVBAVimYfdYIk8m/iE53qgdNb46cZKWu3k Ogu7Asy2Z3jDyyUFHfchpi8arZ/crCTcMjM6liitmhu1cMfDRfIqceYaSQinzWak/hXa oQntzqmMFh+PWYZNKMCWkmm86m16R9AhP+lI1mNPh/e5hX29/ENLXAfCHBQ/KKe5X7YR a2axLugR9uBkJQlYHF1JZs3E82gYCuVglJ7Qc6cDvPu0CaoBRC6sgTD7l2lNK8pH53zR JcdaWgKVbwkQQuhU7tWk9+8QnOYPjYM2xUGQQztyeTLuX4a/mUPht9TZSzM8NvHKEb8Z L64w== 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=iajxwvmyn/5YUrB81JkKtJsYw1tIlBTuFlWMZ4U4DDM=; fh=7mnR4/DMo6zaWtUGaVI9DND4TR+QGflpVaaXOChu5h0=; b=C5gVMcEn261xS5f+M5Lz42zYjdaIzyqUAWi62p6PRwa6fEFA+otPONkxos9CoxUeOw pOu/bYUQKjc46VVDH9JABfXkwq1oxaGhTHb/DOBYNzT5Y4yTLhSPBnmUo8GSI+Gj/kAV ySadjTDDHMaZoJKoGPgQTVIiThoKAmicwx3JkZZ0jVNulBXt9TMeq6AxStBhzu6JbvII o0jGU35lXYUuQIczIJqAD6/4LerrElVkPJfpr3UxJSBaHnYKsWSwooO64EZk8/gSW7g2 ZXxarTTdb/dWz/aOubENWFozA9a3e1W5p2qzJ/E6RIs9fKU/D36qDG6ty7DLSXvHPvTE ivGA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=mTSHWqR1; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77105-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77105-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [139.178.88.99]) by mx.google.com with ESMTPS id h18-20020a056a00001200b006e48c3d7947si3977251pfk.57.2024.02.22.10.28.36 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Feb 2024 10:28:36 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-77105-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=mTSHWqR1; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77105-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77105-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 3F134286196 for ; Thu, 22 Feb 2024 18:28:36 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 53AB6149392; Thu, 22 Feb 2024 18:15:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="mTSHWqR1" 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 78270146E6D; Thu, 22 Feb 2024 18:15:41 +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=1708625741; cv=none; b=oTUpnUZkxWwiK8COOTfOwV5zVsY06inZB8qkgscw2DjqiFpHa467Y2DwQVRsDeq+CUxlTXconcliDp8GLhUbpypfeXNVL0os5Cl/5Ic5177B41/12X9b+wcmBR975zfhMd7tWZxgvl4d9ZK0YfxCBaXcShrb22CS0EdcZrRsg8M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708625741; c=relaxed/simple; bh=FToiCTeWI9VwQwoCsKkGAFwvO2aDbYDuSZipU8NTJaA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=H71zPIA+atc6vbvigwYMvThO+mdgBmssElrSVCVNyErQxl5lHieluoaOwqKmC+WzV8fKbvoE58635zI+q2L0jgmwHWDTd3/oAtdU11sI9VOqRFCSwFh13lzJeO9cIlQrm4hOs97+scm9aKmi0lh4VGXTejGqOL++IakxtSR5tKE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=mTSHWqR1; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 00A3DC43390; Thu, 22 Feb 2024 18:15:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1708625741; bh=FToiCTeWI9VwQwoCsKkGAFwvO2aDbYDuSZipU8NTJaA=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=mTSHWqR10ebW0iYXmHiNjwiOlWTjXZdomazVXqGPdXmH0FT42aa3uH12WDKYtIw5l luHtwROfuOqVJ92yi6+a7/wC8ZALUz7D4d0ny4mK/OWxtostW8afuHJFCtHVxN07xF lie1/d+XxpGe+Nt/Nmogm6XKMIScDORBiYs4moUa8SoNivpRWIoDl1tM/C555ghEvh 1uPmnToaDngOXkbkoJXY0NNUom8ucan7VQQMcKUONKokrEiz9gz42iyulRc1ngSkN5 tN5DeSQoZU+1ZuT2I6dQ02h3oE3NvqpH/V7520oJJw6jgaZZM5xRmCmJYrr/GxMn5J HgphwXmemucyw== From: Maxime Ripard Date: Thu, 22 Feb 2024 19:14:12 +0100 Subject: [PATCH v7 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: <20240222-kms-hdmi-connector-state-v7-26-8f4af575fce2@kernel.org> References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , Sebastian Wick , =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= , dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-sunxi@lists.linux.dev, Maxime Ripard 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=FToiCTeWI9VwQwoCsKkGAFwvO2aDbYDuSZipU8NTJaA=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKnX+376ip07NfvGz0cTX0R81Hgmuy8055ZR8IrghuXPo +W8Hh9r6ihlYRDjYpAVU2SJETZfEndq1utONr55MHNYmUCGMHBxCsBEYjgZ/tlv3P/Z3KvG7bjs pA3tucpH+tleiWS5rxa/uKuY48Chv2cY/lef/yMeua4nOGJDg1HUPfHmffxTNyxawRqps6umZcv rvywA X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791624757689356257 X-GMAIL-MSGID: 1791624757689356257 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 Thu Feb 22 18:14: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: 204972 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:a81b:b0:108:e6aa:91d0 with SMTP id bq27csp129393dyb; Thu, 22 Feb 2024 10:28:50 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCUD7Rfhcz3XyeOSBX6pC6cKDH2zqzgMGuPRKWIvgDCbUirZ60e+kYvjPVPv2z7wZ/VD+N+PacKRUSWAyjzn6crMj06+zQ== X-Google-Smtp-Source: AGHT+IHPk+iifXcQce6oNYxWSvZkMlFo6GatIyLrU48UfaVp31cZGA7FoQ7tTYH3Bbfb0+247VOt X-Received: by 2002:a67:f54a:0:b0:470:394e:a9da with SMTP id z10-20020a67f54a000000b00470394ea9damr15266704vsn.1.1708626530732; Thu, 22 Feb 2024 10:28:50 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708626530; cv=pass; d=google.com; s=arc-20160816; b=shqsC4FtmjqsxZyksfmIE2AqOYLhZ9Y+cmfWpRZxoQFTigFsDcbaWJBpUo9+gn680B 74KrsKhYgd1NlQKJ8FTTTv04Acda7JBRpxrC47Us+YFdZmasOpap1vXsIaDDCNbicOoB YDcoUe/7lqaR27VCOFARoORU4qnbVwvVXHhelRUQswgISzkSEOrsOh/aJ1/eJIxKcG13 yNQJdA+motUAD0olb8YVdQvOzfcUtKkk/ACnqEfnCQ901H1egLPdlzfj33Cm0tU5Rl22 sbzgv0gV9990PNvpVd0mNJxC8cKDkd8i9m7KYkSc/tSVasKE47BppUk8ll9t0ExU7khh 2Clw== 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=Cf09Iq4HiZ3EOyznZSUk/exgMTxGJiIsCE+GxsVCLEU=; fh=7mnR4/DMo6zaWtUGaVI9DND4TR+QGflpVaaXOChu5h0=; b=BSZhYxSOU8gfSetfkVVGsUUrO3sAENOdekqtZa544rsO8sNWapXAD8uc6Sn0c/LBNv Jro1Qf2qbFtB23FC2hXMSuBLMRRlCm2YgqMLtcfzxQy37T2GgPT2NhYUmu0gN/5demcr pkJfErGU71peLsT6NmmiObJlf5Qkk8L8JkFXS57qHvzTu10GNaW7GScGy9J5SstR/HrS JT2dLgP8SpbUDHigd/8NEuoPk/+/fb3nC7Nk4tWMJKTGhU5Pspn2q8VbzGjKvXUoL/j9 TUvwYQe2ISaiNKanYEUXNcO/Zv7kFtgaG6VAY8DLwOnli+VydoyicaRlleXPV062yDWN qBSg==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=Ar769At6; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77106-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77106-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id bu12-20020a056102524c00b00470575ec043si1419247vsb.552.2024.02.22.10.28.50 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Feb 2024 10:28:50 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-77106-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) client-ip=2604:1380:45d1:ec00::1; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=Ar769At6; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77106-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77106-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 72ED71C2265B for ; Thu, 22 Feb 2024 18:28:50 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 463CE1493AF; Thu, 22 Feb 2024 18:15:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Ar769At6" 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 3DE98143C7A; Thu, 22 Feb 2024 18:15:44 +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=1708625744; cv=none; b=Wssel2ml61TvhhSWq5SYvtfcAZP/HlUAyUhgpyR2IxaP/PHbuPJfpqI/TPJ5u+/4zWykFdy9jQivn0FtUE2NoilXZODjbgKH/l/NrcsPIEgAOTxoIy4Oy2/NQBkamjXlfrd3yJKGyqLXaTYQBYga+Eo5Vz4CqdD6+K1HCFCEoK0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708625744; c=relaxed/simple; bh=17MI7dQ+HBQcuA6TivP0AEo+xZ/MsQzhUdSykOh5KZ8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=L/xsU72jXqd0GyE1+I2vHm4/tKUltLpiKe1i8y8TM8hXMLVlzrUf+ZwzcU3KB4OtmWft24BmTcldorGCHxSGa3MYTtMBNxDV5nzizmbJmi9SfGJy6AW3OFj4Xp7iEFKYwvk0ZJTWDg6hfcMCUmcnIhcOW4NAXr/rfF43EmoNr7U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Ar769At6; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id BC992C433C7; Thu, 22 Feb 2024 18:15:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1708625744; bh=17MI7dQ+HBQcuA6TivP0AEo+xZ/MsQzhUdSykOh5KZ8=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Ar769At6wc/cUyEx3NLI78/IZ+lvnKjMdfYHO32ToD2YhPbI69AuSCFCaBHLRGiC2 J9DMIbirDcyMLjidUpzMTl+tulYhHyALWgig3imTvPAVtCEEynUQtbfnJGOm6iiHYq FyIvLZb/suBrqlGfgK1EQkZx4IGnNPev6WxWKBQr9veW5KL+kv10vG6QgDL9yO1WHA arqcINQoq9xeNTwFc8OrO72Wr0MXMXO9ROk7NffpP0AhJchhsMBEHT3u3BH19xiF0w zx96UiRWdXNgj09hQcyy5jMhXwts/sfW4hcGxQAo9Rwd33l10lDh+xL4lyD/g5FaWf wJjPDwDZq6luA== From: Maxime Ripard Date: Thu, 22 Feb 2024 19:14:13 +0100 Subject: [PATCH v7 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: <20240222-kms-hdmi-connector-state-v7-27-8f4af575fce2@kernel.org> References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , Sebastian Wick , =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= , dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-sunxi@lists.linux.dev, Maxime Ripard 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=17MI7dQ+HBQcuA6TivP0AEo+xZ/MsQzhUdSykOh5KZ8=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKnX+36xFpzweVVlbvQnKCrJdqr7Qo7UO2mfH4u9/tolY PuIoSyho5SFQYyLQVZMkSVG2HxJ3KlZrzvZ+ObBzGFlAhnCwMUpABO5lcrwzzbFs3nSo2iJSafM j5x8ov6+I1md9U/z/huqf/iLZjst9WJkmHcq3stBL/GmbOkWs4vCrDEzdhjMjVzB/dz33swZ5w6 cYAIA X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791624773091852864 X-GMAIL-MSGID: 1791624773091852864 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 Thu Feb 22 18:14: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: 204975 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:a81b:b0:108:e6aa:91d0 with SMTP id bq27csp129992dyb; Thu, 22 Feb 2024 10:29:53 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCWXKimSvgW8paqnlhOQIzwVRAfYWORHzlxl3ljB+jE3t1kQpSbxOcm7A3S+9jziOAImws7mmKhvU+/+C8tUd42ixR3U8Q== X-Google-Smtp-Source: AGHT+IEx9tazCxuC34TRnelD0oClUkcXlnZQndxPYLh8n8F98YuRXjRrzVA9cxpN5P1iAJAL91c/ X-Received: by 2002:a05:6102:1904:b0:471:bb0c:e0f0 with SMTP id jk4-20020a056102190400b00471bb0ce0f0mr2662365vsb.27.1708626593029; Thu, 22 Feb 2024 10:29:53 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708626593; cv=pass; d=google.com; s=arc-20160816; b=XVfsGdxNegbULZzPpquwMhRvE/RIEOBVD2/AiZHYwNf1GMO5aXkDI7TV9Q1sN68MKz 2heaiXxPPrDoetfhdces/LozIuNm98+fdNfP3Xc1Z8qTumdLdEvaEpYDiR9p7caVhuLj wt/S+LCUNF89iceu18H1hHnuBDzP5t2G9/agcLC8UayGDW5VqDF+K3PS3+gdcxC05mGg QmFPrL7G2F+T5xcIwGjAcgwX793bZXbSr6wtrAboGvFK28k7h2shQpzHPxiH5AIP5ysl 1ShNopdf7mULNYkrVIoaGXVanNWErgcVxHEBvq0o43MYdH+CA5ZZLT8GCVMLGAfurmxB gIKg== 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=yk/0OyxOxSYTcYbrE4+jbYUyrXYdgTwhjoaaNZORh0o=; fh=7mnR4/DMo6zaWtUGaVI9DND4TR+QGflpVaaXOChu5h0=; b=z6K1cRg6Hzv3dnJ8FMxjB6oaKz+xZfairryl7hmqNA7TsNQTnLN8M8FADG6LrSS47x Ve9//owZceH4RsjnoUfjmJcjqSlE0/RreEQTBaNYe0nfzF4uOD6IHfYNcFy9plgFRJxP BEAi6SvoUUTUhx+0C3ruspg9Wz4Vzp9aRfVJUt8dLcyhMte6I9p/OeG/a82R0fkrcUdc ajiQb1MA6ocu9KLxh1sOUZAp4OhJKtaQEZ5B3jEftd69jngucXlBLA0H/u4f5DzGeF3p nBRmxZ8u8wE+xxNWEq02aM4GenrAM1c/bEawXRmrGuKPiF2/n9/2ZJfGVKWtrdEG7Lak m7Hg==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=MTQXpWDi; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77107-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77107-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id q7-20020a056130028700b007d6a3e3ed75si2369462uac.2.2024.02.22.10.29.52 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Feb 2024 10:29:53 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-77107-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) client-ip=2604:1380:45d1:ec00::1; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=MTQXpWDi; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77107-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77107-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 7F3021C23947 for ; Thu, 22 Feb 2024 18:29:52 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id C11CD14CAB7; Thu, 22 Feb 2024 18:15:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="MTQXpWDi" 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 303541493AD; Thu, 22 Feb 2024 18:15:47 +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=1708625747; cv=none; b=uqZMMIozTjI1dPvZAg7QES0GCc76UOABjNcuF0SZ97Ia4WFXKgmD99fl0zhz8g3kzlDocm6YjgPck8po2lIoytCbdjP3R1m/TMOKpLre4xXIR4wdocPl9B+6z3QO5qkMM+oCDtFTlsx6lRxMzrrvKfYiI6q2ktSEWZTVrDoIT8A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708625747; c=relaxed/simple; bh=YwpSM33eYZ8fThP4XDRsVvxMHPDfo2uoV5jBe3jaHpg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=IVE/Pl3e4giiS0KptEoCg4AZ8yj9Pa+h+6S2NzIR+xecgdtURHXnwMRA/+bdZDnAP16YTt4D4GO7WDLfFrDM12/hZYdrl3iPB8oxQkEO2GVgAw81Nls+WISyWXknZ7Vo4BllMDB7+LoM9pPiG8u1/TK5gSgNC5M+5oCuz+Z+Iio= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=MTQXpWDi; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 86DCBC433C7; Thu, 22 Feb 2024 18:15:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1708625747; bh=YwpSM33eYZ8fThP4XDRsVvxMHPDfo2uoV5jBe3jaHpg=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=MTQXpWDiww87sdR7KHiuZRTiIfv4C/bStyh0mOTesoCih05pBuAoB/jxt9XCteIu0 J2KOs8c0YQ6y6ZU5E5skfHsLp/T+a1RFLnzAQ/HZ/ZMJeiAMvbwOXm1dfo9+kIFUDx 8kGsKoMExJ0bRvq8Bq5JMlKdv1riLwBWuYxbEIT5IeEGbRk+d4ah39LUjYU+z2Ym7x sT0siHEKUDXVrICFt+hj+5PrJGJJ0V3n+M7W4/EVDbIoXCRJbNcIBq6D7J0Flm7J/t N7I+gzmLlmJ4Cg6QzC8PRVBhlCKAxQW+yePpE3HzKc/REOmMMsmYvX89v04EMqVcQ0 VHux73u+Vrhsg== From: Maxime Ripard Date: Thu, 22 Feb 2024 19:14:14 +0100 Subject: [PATCH v7 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: <20240222-kms-hdmi-connector-state-v7-28-8f4af575fce2@kernel.org> References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , Sebastian Wick , =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= , dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-sunxi@lists.linux.dev, Maxime Ripard 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=YwpSM33eYZ8fThP4XDRsVvxMHPDfo2uoV5jBe3jaHpg=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKnX+34dP7z5W/v5bLe80POZgvPiUq1c2R1ST+Rm28YdO yW8nu1DRykLgxgXg6yYIkuMsPmSuFOzXney8c2DmcPKBDKEgYtTACay5y/D/9qTH9Udphpfm2Rw quTL0UKeqORlIq53bByD2e4tuxtQ68fwv+L+/v8NJ61Ffe8vjLiadq6msPYxf5r9D6cHHG1Tg3L /MAEA X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791624838231907427 X-GMAIL-MSGID: 1791624838231907427 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 Thu Feb 22 18:14:15 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 204973 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:a81b:b0:108:e6aa:91d0 with SMTP id bq27csp129673dyb; Thu, 22 Feb 2024 10:29:19 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCUpi7KEgyTVzQncRWtgwWGOqHCwCX32sQt7gdUGFleSVOjYWArxKeVfPSA7knwuc4ECu4QfyUe+C2oY7HR4GO4E6Dgmcg== X-Google-Smtp-Source: AGHT+IGqAEt54v//hhl/r9WlneqXMdI5lpBcV4VxOcCo/dk1E0ITTikf0qMqVl2/CYEB3qhh6Mes X-Received: by 2002:a05:6102:21ba:b0:46d:2d23:f500 with SMTP id i26-20020a05610221ba00b0046d2d23f500mr17587356vsb.18.1708626559202; Thu, 22 Feb 2024 10:29:19 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708626559; cv=pass; d=google.com; s=arc-20160816; b=CKsvVFw/Wf8X+XI4zFb0qJoLcTmnsrpATeZI3kD3VETAYV7W9FIdmpw7rytGvCVrpb Z+V9gjoVgc6bIGlRDldG6cC76KodDkXFpMRnrI7kSn1nHSy0yVVk1fTZWp8VKNJ4BuSB L/jK30exdIRd7N7VPpfYrUzjSlIRynVLLAiT5RqKtPhu+K+s4nOXFYxjYylRKhIWL9re MjlD2pJuY2vknxT96qtYzvcgC/a/jzejqFLbFybnJKDNb8LDZf7eZPcyloG6R2MTPz2f llToxpz2oGQEg9hify/3DaxF+S5QjPzYSjtWe59TLhaP2hZPiurqd79ukLmOo0vbV57k c2FQ== 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=iE0M3K0dKqmF4t8VfCIP4HjbDJgrfjTnQJZcOKPhQag=; fh=7mnR4/DMo6zaWtUGaVI9DND4TR+QGflpVaaXOChu5h0=; b=X47IYx93cIbrbmLbwVVZhj/C6HPjEyvpAsyi1p2pP+5AB5ZVmONvrzZFfF1ZRTiONM //ceRG1mxfqEH0xzAHEdIevUoQvAyn6Zbt7RW7mk09Hqil8sNgF2LZUa0UIMjFJeCJoC Ttb1ogBIG8VtCLrHJ7QaXhJmN3a/cjF+ggeyNw9xKwh31qmWvOVmyJjtsWcqQwwjTzxt eWe/UBNDDvseuyjCz0ORaTSp8L9nenLHNMs0Xs7+pmtBNsW5Jd531eOClv6B2k8f845/ C8se05NiWUUElBFpRw6u35zjwFlBhhYUhgGn9SVtunn1yGeKSzy5ov1/cuIxm/4k33fP 6H1g==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=EeLRUhX1; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77108-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77108-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id bu12-20020a056102524c00b00470575ec043si1419247vsb.552.2024.02.22.10.29.19 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Feb 2024 10:29:19 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-77108-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) client-ip=2604:1380:45d1:ec00::1; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=EeLRUhX1; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77108-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77108-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 E71281C22A90 for ; Thu, 22 Feb 2024 18:29:18 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id B80AC14037D; Thu, 22 Feb 2024 18:15:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="EeLRUhX1" 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 E275E6E5EB; Thu, 22 Feb 2024 18:15: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=1708625750; cv=none; b=p/kQXzQ9Ftfptu/o7VOIXadLBZgeUF5KtEENt9e/MFfQN4RH8v46eWymR9UTUAaYJM4Pui3MVwoZQey3uATvcCqpdYRnzeqLx6YMkMrbLqd7fqhdo4UAgEThM1NvctyVrLgEUqh+wYIIYXxTgXSsjbb1KZAvibVc+GNBStGPNGo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708625750; c=relaxed/simple; bh=mEyVDQhhKVyw3edURYriU45qe55YIRK057j8zDEIx38=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=hKmSatEi5+Fo68C5cJtpQmwLEu9/5GrnZzPCQpwRvsKIyeblrnvkQMpAVR/BBYtPrMN6A5CIl11SXigKbrL0+NALlKjABwzmCgNME+g6Ic6kXdMiN20P2LaLJTpX+7bYuQ94QSpCtn6MoaKTpz/yDdNIfUhJQVAQ1FMG7XLFqJs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=EeLRUhX1; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7126CC433C7; Thu, 22 Feb 2024 18:15:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1708625749; bh=mEyVDQhhKVyw3edURYriU45qe55YIRK057j8zDEIx38=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=EeLRUhX1irC9WINz5LLmJoriChNAd1/BD3YjjxNGBgvSHuWaFOAk/5XFZbFrktSHg YfJgHs1YCK+7DRufwDSZ+GqUCTQAIbLOE4Lkwc/Qt5FA625mI0setcbhqxROlD1VTC 1nIN80Flz7/a4FMBnjhgTnS7O3cyjyYfpkiL0M/vWuFA+j2VF77kryKHO+fjlls/FY kQ9nBGX8VseRakyQyDSV/NiIvBJ3OLM1L1Mga/RX0llq8EgTuzAGblp2Gn14HE3ngr /yCj1a3TZSp3495bqhV1RQjB91MG7150m23m46fSZ5PAg6fbY2zuH1R+dOhM2P4nY8 BC6Di6X9PjZlg== From: Maxime Ripard Date: Thu, 22 Feb 2024 19:14:15 +0100 Subject: [PATCH v7 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: <20240222-kms-hdmi-connector-state-v7-29-8f4af575fce2@kernel.org> References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , Sebastian Wick , =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= , dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-sunxi@lists.linux.dev, Maxime Ripard 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=mEyVDQhhKVyw3edURYriU45qe55YIRK057j8zDEIx38=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKnX+34f/6mY1LbiW4qRWf+5bb84Gc/MfCe4Zqa++uXXA XJrJ4XzdpSyMIhxMciKKbLECJsviTs163UnG988mDmsTCBDGLg4BWAiBnYM/8MrGnfd2Vi52GDK 5kjJhsN+Gsq3HpgLbPh2Wnad7KPn2tEM/wvmiF1ZPbtGX3smH+fU8D0NFvVim9hMBLam9L9KeMt kxg4A X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791624802932225575 X-GMAIL-MSGID: 1791624802932225575 The vc4_dummy_plane structure is an exact equivalent to vc4_plane, so we don't need it. Signed-off-by: Maxime Ripard Reviewed-by: Maíra Canal --- 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 Thu Feb 22 18:14:16 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 204974 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:a81b:b0:108:e6aa:91d0 with SMTP id bq27csp129834dyb; Thu, 22 Feb 2024 10:29:39 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCUm/0cvwvPGav9esRnNNdENnW6GEDG0+gZhJrqqAcHQ8i+8+qDRRo28OWccYVSkAM0PQOr6N0MjTpFysyasGnVdXdYeJA== X-Google-Smtp-Source: AGHT+IHWTxqonHMzsM8/r2rzn1Z8JYBvyhDF2ZwRsHMt2uhf54UGAIu0JgrZbncL1V51QGwx20LG X-Received: by 2002:a05:6a20:8f20:b0:1a0:de5c:aabd with SMTP id b32-20020a056a208f2000b001a0de5caabdmr455408pzk.22.1708626579198; Thu, 22 Feb 2024 10:29:39 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708626579; cv=pass; d=google.com; s=arc-20160816; b=OuxQ46KUKfZ4Z+pDOIRxMgnLHN56L2kcN/6ynW4bplbjqkYII+gpYSeaOaRoZGgi0S nt4vMfynJIaYN/drAf46pM9MtUlIYQ8M5mCG+ZYSrDrjLktRjrtZncucT3lNPC1Pn9T5 sbYL7QVVBP3HNDYSHSZOYICLoWcgA6+tabp0vosp+ki7ix/PMHdXaAVap38u8p7jidJP hSMLrIuxs88Kp1psfi3xnh4xcmm/V6H0Gr2BvgUe4mVpjv7GyBR+38/QqY3MirjcprjI NlWUpAwFGpB7ERooWUdLrlH/FlSULaHzqVeRNfnRxtMwfrwVZPhhBSTUGBg7Pg3HIR1Y xgzQ== 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=GcpVXsJcy60zS9t2ACfwVyym7WjKVKCydaA9dFZHyko=; fh=7mnR4/DMo6zaWtUGaVI9DND4TR+QGflpVaaXOChu5h0=; b=pIfsf6DtAJ1VkoOO0WMO/IWwetGj1YPyBzCoE7V440TNHtVelhBN/OZDFT0n2doTLv mc3HxCde55ypdUh3TrCm5ABNXrFdBtDYsYNVBCY66UJIBnjj7o5fjR161FT6B9onmqdK dD+wy47PXti3Y02koaMpI8Ia5ammHZOjAPXF1ViAGazd9PfONEm5sfGjUY3VDfBTOMEK CO5yj1kXcPZtKxo31eIFJY50PPhkNjA7Ht45Ffg1pAU0WBkND+erZK02qGKxH2Ez1kEB wzUH2+5QIo9YPCYpTki70APR+s2Zx8Aj36wvO3Q7KTexI+ovKDFkxvzB0PfdcY1iGOKe nkdw==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=QR1hMWSI; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77109-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77109-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [139.178.88.99]) by mx.google.com with ESMTPS id p3-20020a170902780300b001dc4adf9a63si1789050pll.512.2024.02.22.10.29.39 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Feb 2024 10:29:39 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-77109-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=QR1hMWSI; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77109-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77109-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 0A2352862E3 for ; Thu, 22 Feb 2024 18:29:39 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 5C41A140387; Thu, 22 Feb 2024 18:15:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="QR1hMWSI" 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 97B5A140366; Thu, 22 Feb 2024 18:15: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=1708625752; cv=none; b=ivpiZmSf2U/OKS8Nx6mdBtLS5ZY2QRQZgXvFXwyz44SjKRzOTCc3PdPqVwowDhTZw16OHJ2lDHKf6p8MHRvR6BfNNyfLWxThtTKVUXTSQaPau10aWpzeth09MvRBQ5LL3wvNW8s4VvGhPv/X/wB9QuBITlxvw6UPW+j3qBfB+L0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708625752; c=relaxed/simple; bh=8tamAetoSgHQ1OcsRskLkqCtZqUknTtgTwiDjxhENTo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=CG3k+xSMsGSuoDDrClcq2TXpIOpTlBQroLusB5ZafLi2NLBsL60EPugEPjbqFPKaRH+oCPR5JlaV3yea8zrr7WThbaJ+/czFwyvxeaD7hYm1jI4Fl2hFMSR1Vm0DqduhH3YNJOrwjel/VPacIRflPeVuWSmPsAMCD8ZcGSqq7Wg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=QR1hMWSI; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 25C59C433C7; Thu, 22 Feb 2024 18:15:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1708625752; bh=8tamAetoSgHQ1OcsRskLkqCtZqUknTtgTwiDjxhENTo=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=QR1hMWSIWiLieEB07vaDhgJeHXTdXha3tjaZH33S3sg362WRN1ZZmhTXdIBRJ2RIf kx5G6BVDwCFO2Pw8zKk3fB2XvclUOSpITaHM3lqqvIkXIYzyl96eagH3ajpktkHGz1 RqnIoyB6FYqgD63xmGjdZdw+smV+y0a//JDUBtaa+JlqvGSJ2DeBCP3hVa6WBFe0BC QQE2Ify7Tb7bNNr9u3aY2UU5ba24WpD/o0QL6ND+9jauSeUtCls8QxG/nLoBrbfgrr cLgiQYtjjkcwsJFjqul27/k+DKr/TkF29jBqwh7bwT7BBxywGsC8TgpXk8O5R0haLC ksyfoNvuab6Pw== From: Maxime Ripard Date: Thu, 22 Feb 2024 19:14:16 +0100 Subject: [PATCH v7 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: <20240222-kms-hdmi-connector-state-v7-30-8f4af575fce2@kernel.org> References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , Sebastian Wick , =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= , dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-sunxi@lists.linux.dev, Maxime Ripard 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=8tamAetoSgHQ1OcsRskLkqCtZqUknTtgTwiDjxhENTo=; b=kA0DAAoW4+8Nb2cYUcUByyZiAGXXjvyhaRrBDlWjl3LMUICDVFNoGLYbz56S+cfYlsUBjdB/8 4h1BAAWCgAdFiEEXBM3pF7KmuuJBg6e4+8Nb2cYUcUFAmXXjvwACgkQ4+8Nb2cYUcX6lQD+LVKq N8MxTOTivfG8G6auJjmW4gY0MqC1O3/UbUDHPsgBAL3lPa49s3q5gr6HBNPRtQL4Ct9vghvk+cx KHDnHkGQN X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791624823924071606 X-GMAIL-MSGID: 1791624823924071606 Now that we have a plane create helper for kunit mocked drivers, let's convert to it in vc4. Signed-off-by: Maxime Ripard Reviewed-by: Maíra Canal --- 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 Thu Feb 22 18:14: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: 204977 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:a81b:b0:108:e6aa:91d0 with SMTP id bq27csp130201dyb; Thu, 22 Feb 2024 10:30:14 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCV03UwFSGzmycEZwWVfYhAf3FPpwVbVN0Yuv61F0RgoaWLEtEth0qaSjcVaS4NdqHhB/ZdtwciAIap7J3mnQt/CKZxqsg== X-Google-Smtp-Source: AGHT+IE7M2J90OZBEwln+ZYBFVk5piky/msoCn3vdNtFvD6Th0wVq5ypPfBrZb0i9DqUbtA3drBe X-Received: by 2002:a17:906:2ddb:b0:a3f:5c49:f487 with SMTP id h27-20020a1709062ddb00b00a3f5c49f487mr2796456eji.35.1708626613884; Thu, 22 Feb 2024 10:30:13 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708626613; cv=pass; d=google.com; s=arc-20160816; b=H5I6DL8jCMSKaALcoSHmpAFTlciGJo6ILiTuU0vj1W/qD5ABTe80I2qitoYQ8RJB2J 1ulK9yVl1WgPZNd/pzkUjZilT4gq0cuGj1cDkpoauE6I05LdIaM+ffC74bC8pS8OlJNg EVgrersf6DsuFaRKs6hCl2aFVp0DlE1KgK7r2ayx/eExPffRQALYNbZUv0xLZII68N/I kO88zHBFFm0EwlYofr3D5Kgdjc91x5Tvkd6YCcwVaZkYumb+WJquyge6bxng1IVkBAPT HXIZNBvPoq1LaRpAwfOe0+qQ/mene4Hz08JTDl6tkgsL4pqF0us7x6z6nR7U0qG4b6pU 9VeQ== 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=S3T2c5csZudEKiPLBAmVK2rYU9+46a6ieJPm/Az+zkg=; fh=7mnR4/DMo6zaWtUGaVI9DND4TR+QGflpVaaXOChu5h0=; b=wfeQPFoh21TZ2UjCuPWHrh558MYK4wSf+RpRkZZ/hVbOPuOc/Sck7iTKzyLassjAkc 7XnhKQWiF3atiR2r4oQqTVF4/q/+WPjtccUFTG4zfty/Ueh8+g//Nmy5P/GfJ4AW3NBJ Fm1r4eOGgaeszR4hfcHDR5VsXMfix6lIgKqAHTF/HnXueyFc1T4IXhyLjmxD7+xPLdDL TPPH0EBsro2WVw/DX8AMOpvem4aYVjPktO43caIo79Wo05AIscywqXFwwYlEIeL6HTwH WbG4dkl2VrJSFk7NUXl580WocOcuP96TyxRV8rL/iy7oyKBj6La+osLUmM2eBg0rY+Gz igMA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=LyXbPRYH; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77110-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77110-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [147.75.80.249]) by mx.google.com with ESMTPS id m3-20020a170906580300b00a3e4576b234si4663983ejq.388.2024.02.22.10.30.13 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Feb 2024 10:30:13 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-77110-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=LyXbPRYH; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77110-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77110-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 24B971F232F6 for ; Thu, 22 Feb 2024 18:30:13 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 90014140390; Thu, 22 Feb 2024 18:15:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="LyXbPRYH" 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 5A022140385; Thu, 22 Feb 2024 18:15:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708625755; cv=none; b=Hi+3eqwNjWC98F5N4PsZFSZYkpY5+k2vJHBKWRdUBY24TrW8XWfCAxc1LuwPvrwy8tfm9Y0XpMav8v+qZiYEkr3SD00D9EVonoKLBnNlMiYx+XFGcaizqJC8/BNLaBEHumffRTWE3PqJsCbhR0+lu/nvQiHtDWEu4EpI4OZmK6g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708625755; c=relaxed/simple; bh=DqZZ+b+mj8mcOmdAL/nGf3tA/KUQeXc7kvO51t7IdCU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=VhGlJ1Y8k2JJayrveC3BA2sR2WaVcrG0hdjAcG5p1oUrHJ0tFCc14d7RTx3H0rJyf8JuD8MLHpE6FxvM+CyXVfszZb1t0IQlKTp6SARlN21ObGUStUveuRmPUY6fF0ZdpJfjgy2k3exIIwLRaDJl6FklzkXgn0nmluRyVsjKRYQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=LyXbPRYH; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id DD83AC433C7; Thu, 22 Feb 2024 18:15:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1708625755; bh=DqZZ+b+mj8mcOmdAL/nGf3tA/KUQeXc7kvO51t7IdCU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=LyXbPRYHZZpqLIB0/HhT3EDTRUZ9hPYNuWO7o6kBzgDsaKpb9M6ZnuKfnMP/5zPC4 r/+Ca8VE6T3hqZG5UEe9/iSKoziOcY1rvAlmeXWYBVgdCH70/QnL8x2OHXTH3uX+tn h8eXVhly3+CJ6oZAGAPpfXz0T6vWFNzsM04BNASbFjNgb+EFo1g/ryqFBuj+BhjLeb UjLaVbviuxiLJNFVKe4SuCoMm0iEhgae/wAcTt2sHvVtbzUwiDCvYngY5uJ3BYmYQg oni7Rf28b5e7UOFdNbEPII3ynHIm5dPHVWy3z5EcyPQtf72QWfD1UERwsp7zRKthLj ALwfZCcC1ggaw== From: Maxime Ripard Date: Thu, 22 Feb 2024 19:14:17 +0100 Subject: [PATCH v7 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: <20240222-kms-hdmi-connector-state-v7-31-8f4af575fce2@kernel.org> References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , Sebastian Wick , =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= , dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-sunxi@lists.linux.dev, Maxime Ripard 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=DqZZ+b+mj8mcOmdAL/nGf3tA/KUQeXc7kvO51t7IdCU=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKnX+/4EvE4xL/R8xuje/3nmrc+eIWdaky60hS9Y9vP1e ckox187OkpZGMS4GGTFFFlihM2XxJ2a9bqTjW8ezBxWJpAhDFycAjCRpihGho3/ztrGnvuodrR3 07otiuxS7lrVX884xEzjdZe0jLLx1WZk2BS6me3b2jtbzypl1gu0nL6uvz7jsNzZ8we2BZQnhpd kcAEA X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791624860189376722 X-GMAIL-MSGID: 1791624860189376722 The new HDMI connector infrastructure allows to remove some boilerplate, especially to generate infoframes. Let's switch to it. Signed-off-by: Maxime Ripard Reviewed-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 Thu Feb 22 18:14: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: 204978 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:a81b:b0:108:e6aa:91d0 with SMTP id bq27csp130344dyb; Thu, 22 Feb 2024 10:30:27 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCXQVszwENrM2X5i3sSTkUi+JWLaiphCxCWLUnChKV4NDYo3uL2VIdzI5me8AU2QPdwzTz20MzxYst3UtTMyiDM4xTqYsA== X-Google-Smtp-Source: AGHT+IFhy7VBTFdPqCflXJHq9MNS5LPl9GR7bWhZytpGrlOXLXZrxCxIUuKA7dI6Ccc9qP8WsF97 X-Received: by 2002:a05:6808:1b07:b0:3c1:78a7:9935 with SMTP id bx7-20020a0568081b0700b003c178a79935mr3430956oib.39.1708626627714; Thu, 22 Feb 2024 10:30:27 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708626627; cv=pass; d=google.com; s=arc-20160816; b=zUeiJsmmSCXLQ/HJKfY3dJIpEVU2TOR+kSGEPQAI3RW8wav7nllcibZMvO6v1qsnpM bel2GbZ1kbaOz5GC2Q/jCX59LYAuhkuSnGlxUoZBcmA7mjYRWQqCFMCejEpsuOVxIMYH l4ahOEJfevaEINy3RE+iv3j8CVZcdvwHXqaYmZd1F1aKXnV/dfUE/qB4rpihQAdHDcOh njGZDBeHC4+pbDIfK9QDIQRGfvXd8eaQe/I6mt2DQ3sdHKtYW8uAF+R09EgQ0XLPwjrK 5mBkA1mKKnui4CAsu7X4gw2TVOOregu+irzO4As+xpq2BVgLU6xvMlNkP2tf8jUCO0v/ GqQQ== 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=MTnUbfrhclbgZ2tzIZVZD82l9kS0u0j0Zhzjq8Q5sGw=; fh=jHlABrYnApVt5KJlrthitgyo0hqpWWrdlN0oFT+yLLg=; b=1Fzph6Nlm7E8UkYPdSxonGLjxDd+j5f3++n658awJ34O28OxgizayaRSYglvVg40oW oQuMBoZ/D73jn2tpFzmP4Kk5M05sV3nKYylnRdLIYtvOhR423IZjrQrJO9X2sPQmiumj zdF3wwNOc9DmIJ3k+6PB7aBZ4jFkpc8/WZD6wIsRGliJeSGjGLTn+KCDbUizLSV9UBOo VNs2O/swwUWApTQZL98YFjDU0d6A3NeCS/6oi8LVRf7JH3AzC9Uz6TBdga+m7MDBEYY/ FTAvNpQ6VyGCd8n/MYSocSV4URpwm5EYbNw4OfuiTVrfYt5WyFnnOkuo4PieVdqrYOAb 4Byg==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b="qmT/rE2r"; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77111-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77111-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [147.75.199.223]) by mx.google.com with ESMTPS id v12-20020ac8728c000000b0042e088b2789si9570183qto.544.2024.02.22.10.30.27 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Feb 2024 10:30:27 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-77111-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="qmT/rE2r"; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77111-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77111-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 C1FDF1C2300B for ; Thu, 22 Feb 2024 18:30:20 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id DB8F1140385; Thu, 22 Feb 2024 18:16:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="qmT/rE2r" 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 2101A14CABF; Thu, 22 Feb 2024 18:15:58 +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=1708625758; cv=none; b=eqdLA7E/d55GE68pWZHmFm6EHiKq82z6DZDX9Bhl9GJOA5ubh02otCAK5iP5wEvFrJJOLkSLWUqGJYLPubWLLzp/mYQLDjMZ60SD8G1/qK+OluddHaXf1v7TWBZISB+t+KGsFpdBifXR4+QtHgQlGN4Jo/WNJz4TZeLyLFvY2rQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708625758; c=relaxed/simple; bh=HwA8pHzZqVdQyHV/A0cE4sshsUXIMq0spgAC4b0SoHc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=N38usgn8fj4X/uf119U+0RkM3xQIrrRlLDs+m4HCLCGgfqGGKMvqjGCeVAv6hBPMNooL7Yp/7rTtzXyFqf7+DJrxBBHXPKfFzB+B6imovBQbJHjJSN6HMRRMQc7B3KksW4qY+VVTAqhAFx+Ny/xdfLDe0OERGf0QwFxwE7JzL3k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=qmT/rE2r; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id A1E27C433F1; Thu, 22 Feb 2024 18:15:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1708625758; bh=HwA8pHzZqVdQyHV/A0cE4sshsUXIMq0spgAC4b0SoHc=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=qmT/rE2rhMFDIHrJCGBxP+N9iYDNev4YbiCdQ1llWH1TWCYk+Ial8qXGuWGm3zEZp h/SDvGDs+mp9KiSkdkvqRyY4ns6TBhMn00Z7IFt+qn/ty2LbBLnw2hmPzdUJ8so7to hFK7qgI2FGauNYfYYMtOG/bbGd5GwIhw5bVx8OJFgcYoA073Klg2IfL6a+CgHQhgwV VJDGd6KRhc2OgM/YD3y/ePUSkEFxJ4NprmsVwNmn6Jkc6z/mKcRptQtv7UUGCRChhl j1aKoXCAdPo9Ks/vBSuU8eJKdg1bJqpH2a37Cb1Eyr2ae6+MslxwiHuyoYZ0v75r2I vThmaF4lzrdqw== From: Maxime Ripard Date: Thu, 22 Feb 2024 19:14:18 +0100 Subject: [PATCH v7 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: <20240222-kms-hdmi-connector-state-v7-32-8f4af575fce2@kernel.org> References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , Sebastian Wick , =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= , dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-sunxi@lists.linux.dev, Maxime Ripard , 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=HwA8pHzZqVdQyHV/A0cE4sshsUXIMq0spgAC4b0SoHc=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKnX+/5e5Ev7lbvnxKZUft0ONiGLa4p+WsJN3fEVjf8dt aPUHn3vKGVhEONikBVTZIkRNl8Sd2rW6042vnkwc1iZQIYwcHEKwETW2DAyvFW67JV4+cM3dvn9 n48pzH5/KWOy18UPFzoErJ84XfVes5Thr/gBXvZl29JP3dK4srGK7+q8DdaHV8cuVBKfMneGocQ FGRYA X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791624875174518386 X-GMAIL-MSGID: 1791624875174518386 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 Reviewed-by: Jernej Skrabec --- 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 Thu Feb 22 18:14: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: 204996 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:a81b:b0:108:e6aa:91d0 with SMTP id bq27csp139132dyb; Thu, 22 Feb 2024 10:46:37 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCWPGmru/nxezWJUaNSBB54YETemUn5MKRCAPdtVp5+tJshi1/h9CQI4SxsBvbSUvTRES6iuiFE3W3FmG45n4afUtMR2Mw== X-Google-Smtp-Source: AGHT+IGY2kvzSoD4urBziDSv00Lg4Ka7mjUVZzuHUr3jcMUzmNXC+wienqImvsmBY6d9oKDhnYEQ X-Received: by 2002:a17:902:650c:b0:1dc:26a1:d1da with SMTP id b12-20020a170902650c00b001dc26a1d1damr5631108plk.13.1708627597678; Thu, 22 Feb 2024 10:46:37 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708627597; cv=pass; d=google.com; s=arc-20160816; b=RCDzhWiVyN+GgveHO4j06ebehX2vWuQ+dqdGBFKzcr2c1tmjbLSthmr2Zfg3W0doON VykQNiB6S2PYcmK5t0aWtIiOXGY/GC86nYFYUJM/V3o/G3gows7S1HAra0gP+0K1IFv0 5OdsC5RXHZ1akugCZgBhJghq5kKAyFEOZDDSMqfn6bZgNzFM1ZEn0X+kO9m3/iEYEvpk 5rqMmgDF6O9TokzoWdVy2X0TEu/iiRfGixkBRx6RGBc9l86ttExQoSd5awA4J3VCb2t5 s0tOXesG9sneJCQUhug8dLBQGKGHjG4tUyeJ9MLvSIm9LmvYTHwzevtqR4/D/spfm5u5 FkJg== 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=nX6MiQJkkAEZl/HPfoeELHO6SyEOrvctmQOjhIz8+Rs=; fh=jHlABrYnApVt5KJlrthitgyo0hqpWWrdlN0oFT+yLLg=; b=jo1MxKV3/8gPmtZrww0u8JtmLZtfCiiWzYNuo26IHlyk6DDw9kpAXjUQ8NmJ6R0cfc NrahEks8+uY+ammQxEe5v5Na0OrI/uxTQqqIHMdKYH2QcOphS97Ss6E1fYS1bS+b91MU bIO+JG45RV8apxYK8j1gu2x9hPTJcZuRhC/mWG254knKrZaA3KX7etCTlDAtpAj6NNtC eGLUxmHmcdIJT0L/FjOE76bjPop3MfAw36YVU7ZFf2aeaZZLkmg6ePqp7BssRckXNFWB 04mOsYEODLc97Eqyi23Oct0OXKZFhZjLRZXpP//38XnvNkjTPapQBshjyY9knEuqTDN6 cXsQ==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b="o/2jN3Oc"; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77113-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77113-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from sy.mirrors.kernel.org (sy.mirrors.kernel.org. [147.75.48.161]) by mx.google.com with ESMTPS id u11-20020a170903124b00b001db616f6ebfsi10865553plh.89.2024.02.22.10.46.37 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Feb 2024 10:46:37 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-77113-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="o/2jN3Oc"; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77113-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77113-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 98B5CB21BDD for ; Thu, 22 Feb 2024 18:30:59 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 3B63314EFD6; Thu, 22 Feb 2024 18:16:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="o/2jN3Oc" 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 4B9C514DFD0; Thu, 22 Feb 2024 18:16: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=1708625761; cv=none; b=ELRTK8Qz6ra7ARlXK3JscKGmJvuvCxOpej5WJoUctVDeGfm3UxVUP//f8FJOrKj4smr+Enb7xN3b1Pws3V3HyJOXVzoElpDOj12jOIlolUK8cubrDd6R74soHFm7jzLJ8cseTe/d5CgYcmysaxPWICrFFT2LtZo/DP3KXvQhFvA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708625761; c=relaxed/simple; bh=06Y9bTrXk/Zk/AbVbMU7GmJ4QmvebUl1g2EB4tW+8+Y=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=UwYC0LQx4HD5LSO+Q3iIQDRPHgOFCKOQzP2vVlLqGTBZjxxise3mD2VjD2KE1lclU6zrk8Z0H4qBHAecA6CqUh9DYH6TDiQfK49gxtP/ULIAwRX1cjXH2meZP/LiOVkDR1XQtmABX6XX4NBiKb6xmvcXmxdUcDe0BO+iBcGKZg0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=o/2jN3Oc; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7DAB7C433F1; Thu, 22 Feb 2024 18:16:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1708625760; bh=06Y9bTrXk/Zk/AbVbMU7GmJ4QmvebUl1g2EB4tW+8+Y=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=o/2jN3OcW2EHEuhgApfFwexvsxu24F6mDo3xTlm5P5n0dYYsGhwUtDPI8hrjXhRBQ v0X2n88pj2d7iB7OVwpYNybk546AvqFvCTIe6uvKxYSDSudW3MzkIH6giFRsqEtehe 9wJXC/RFsRwp2s1hHm4/vz5zakhx540MBvwpSdmWdHLL4YLqW0BPR7QufjJ04Ipeme SHV98ayR1euxJvpLnerk5O4wsbEgTXNSTgLfbxbR/kcL2RCkRkW8RtKqR8gbQmab2O 2euu17XWbEgn3L4iekLP6XfFkXUw9eA2S2wKA/dLBQoQRcZtsS6iQE9o2Ghwt31VpD m3LiNucktuV2Q== From: Maxime Ripard Date: Thu, 22 Feb 2024 19:14:19 +0100 Subject: [PATCH v7 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: <20240222-kms-hdmi-connector-state-v7-33-8f4af575fce2@kernel.org> References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , Sebastian Wick , =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= , dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-sunxi@lists.linux.dev, Maxime Ripard , 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=06Y9bTrXk/Zk/AbVbMU7GmJ4QmvebUl1g2EB4tW+8+Y=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKnX+/4933Hnf92ptXcjNhkouzH3NuQwhs9/YmSuVxqwc PGjc+e7OkpZGMS4GGTFFFlihM2XxJ2a9bqTjW8ezBxWJpAhDFycAjCRFE5GhmXXxGSSfV2OzZ4f 6nS4zjV8Tumb2Tfe97KGtl8977ewfBfDP4vVfHcfXU9XPBU088R+vs9XX1eu61p5KeN4pB3Tvs1 f9zADAA== X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791625891696665505 X-GMAIL-MSGID: 1791625891696665505 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 Reviewed-by: Jernej Skrabec --- 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 Thu Feb 22 18:14:20 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 204980 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:a81b:b0:108:e6aa:91d0 with SMTP id bq27csp130914dyb; Thu, 22 Feb 2024 10:31:18 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCWGU/td0F+L2REPHKAv1L2SoZt/h8n0ekEyfZff4xW46VvL4MhrBgW3CEthQum1FlSp9PLxwyFTD9F889mzMAv3UdldJw== X-Google-Smtp-Source: AGHT+IHvalISAspqYEObKIeEF/Ll2OygCX8k4Wq5FICSEfgyBgbfYobaEYcZWiT7j+GgFVevjbSC X-Received: by 2002:a05:6402:1497:b0:564:a53b:b8ce with SMTP id e23-20020a056402149700b00564a53bb8cemr7296814edv.13.1708626677898; Thu, 22 Feb 2024 10:31:17 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708626677; cv=pass; d=google.com; s=arc-20160816; b=gRUJr578Q23XXZ8YRhwGsx5Kgo4elTH9T5PMRaosXbWW1nnuwdhVZSOjvcaxcfcHWX Se0e4ihjalmg5QUBZH4P5UlLiOV04orQP+Eov0lhw6plWT8dfbVJQ66K3pH7G1o4pfEH yOZXmEPBIuPoY3gRloqrNWjRnkvm3xSjueQxUatl0rsI0Ro6orH+SUGXNDWqlbbaeHla FxzRaFgRjvTpGIuEroDhAKjly/bFgoxhqpzS0uySPgDEakI0HtjD0v/Skc5Pre25PgLw gM0HgcW2BtaeOqiYEtko3gUWDXthLEcLgybKfqeFYexfmoqH+rqYEQFJlmmoheUQ3sS5 IzEA== 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=QIST/Uzol5i65SE3NJG6Cz7GwzPANcUlEWG/IP/5F4A=; fh=jHlABrYnApVt5KJlrthitgyo0hqpWWrdlN0oFT+yLLg=; b=lSPzVNOBAiy1UPAlgO0RwcOIa0wAkF5geQwGRbMjy9kOqChDlKVW0eer+VV65fshVp TC/BHQY9kyjV7Bry+WfLLBwc8GFEFJpDtO4w0Q74DS01TF5bEOy2UOL5XOgDeQHe7TP+ uCSYCuHIYr/QFwjLKRCdKK6GfVzfkb4Ld6wNvjSBCDvyU4+3RQC1oLUlOkfh1sE0dbYx f8Flr7ue4qdnY+rjZpppuDJJ3Snc9spcQ1JQ8hCCXV3Eu8xgI/0WVYo7G7l+g3NWIbEq JEdDvAImI3Zeu6ZRFYgzm7OU8SZrunaPvLAArPBxkjY0/TOG5ipkI/YvlnE780//GXVq miWw==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=Jmup7ZtY; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77114-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77114-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [2604:1380:4601:e00::3]) by mx.google.com with ESMTPS id bl11-20020a056402210b00b0056446be4293si4852208edb.645.2024.02.22.10.31.17 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Feb 2024 10:31:17 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-77114-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=Jmup7ZtY; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77114-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77114-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 812241F22BBE for ; Thu, 22 Feb 2024 18:31:17 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 5996014EFF9; Thu, 22 Feb 2024 18:16:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Jmup7ZtY" 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 B3F8B14EFC6; Thu, 22 Feb 2024 18:16: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=1708625763; cv=none; b=DqyQzVmeWwZ4C3L66Xaw1QNwmf4GvhX1IoWbY3Bw3mkEQ3jELAnmRcIMZHfko0a/8EH272mA2AzBA8/d0FxdjkV5cfS9o5NVvJQLA6wwIZlDA4Tyzpewvi2XAQC8iNLpx81QEvYxxLZQgrGU0mMX0uWY0ZzR4KCwmZO2laKueZI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708625763; c=relaxed/simple; bh=BTZIvRqcuCTEKcvLPQKN0PrMjRjf9kk4vsMhE/kOVtY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=PhqH7PUrvqAwTWtButs8uHMIRr46q4LobAIwdXiOrI+TY2MAB95OzKDiWErPy59tAPW6QIoh2NOwPtt/OXxJZUQ8NpGFcp+xxbMLrY1Dy50hf+VvArHhhJO+UBCMxZRDfqk3L9M+x2mFjTQDTSDqAezUfYHxf3PiLxcfpHHlcJk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Jmup7ZtY; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 42413C43399; Thu, 22 Feb 2024 18:16:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1708625763; bh=BTZIvRqcuCTEKcvLPQKN0PrMjRjf9kk4vsMhE/kOVtY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Jmup7ZtY0PC+Ppu5C9ix3hOqqK5wEZ+noUiy7APcEAVG25bVpcSHzOT3QYUEWPg38 vnn4IWUvYJxk0rsjc/ulwqwwMM0SUuBWZ+W51mnhum9GoapU+0A2X1HB7caJRJ/CVd 6QxUKYzJujnEoj4nY906EdIxGaCGNjVSe8yjduq3cOcR3Z9T2stK4Zqv9eUyWu/Erq i0GfhITXuFwGCFBn8Q7XeAhLGwpl3V/zfHEVZblpqKzKKuR9UwiEckxcrnQSde6Ue3 JXjHWcBEN+d556PrpEKnPaRksE9yZKPSvQcNDURhngA6f66MCIzVFCG4n1PMSj83vS f0fzYZ4fejIrw== From: Maxime Ripard Date: Thu, 22 Feb 2024 19:14:20 +0100 Subject: [PATCH v7 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: <20240222-kms-hdmi-connector-state-v7-34-8f4af575fce2@kernel.org> References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , Sebastian Wick , =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= , dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-sunxi@lists.linux.dev, Maxime Ripard , 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=BTZIvRqcuCTEKcvLPQKN0PrMjRjf9kk4vsMhE/kOVtY=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKnX+/69f2n8caKoQub+F69/+e2KY3v54bKK+SHvnykL9 me/4wzt6ihlYRDjYpAVU2SJETZfEndq1utONr55MHNYmUCGMHBxCsBEOOwYGW5MTL44peuu6wL+ f5aCIedmyan++RhyZeIKdiFl2Znn9vYz/A+ak310c+ZsyZfhR0Ul1TeK2r3+57NoRdPiCzFbJp7 xucAOAA== X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791624927795147745 X-GMAIL-MSGID: 1791624927795147745 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 Reviewed-by: Jernej Skrabec --- 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 Thu Feb 22 18:14:21 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 204982 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:a81b:b0:108:e6aa:91d0 with SMTP id bq27csp131239dyb; Thu, 22 Feb 2024 10:31:46 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCVo1Pc1L8XQTWSx89PUEJ6MdCY39zHvcbpNb/gzqAImmnuC5+Dwgs4QqNT7ymrD1AZSSMKHW+HO3Z1ElIN1V0uX9QFdbQ== X-Google-Smtp-Source: AGHT+IE0FADmYdn+xs8pc/II5/Klq6Q7xGgB9O73rcnm380LvDSMou23tpeXi3g0lSbvkK0KQKYO X-Received: by 2002:a05:6358:5e85:b0:17b:5c4c:7895 with SMTP id z5-20020a0563585e8500b0017b5c4c7895mr6682510rwn.22.1708626706415; Thu, 22 Feb 2024 10:31:46 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708626706; cv=pass; d=google.com; s=arc-20160816; b=xZi9HZrItbTsVWepOBh5u+Ko1ZJhVsyDDrvzsJ2MJ830Gt8OpluYgR6Bsxqd7H5P9O bSWtiQhrXqkDMTh+IeYAEJrgQ/vwa1iSIhRGrDyj8PmoiNwNl/10CnVzkqoyZ4gWRauy RvP/1EZK/iSWxjidnhXSbJqlNOW14K8eaywb3+j7ZPzTMnnrRSn3i8rbf36OjB+FVKXD nhkvn5MlQwHGoHlCp0TCXmUttutTVcBc7X4GoKpLiyLk9KJtSvZVvkR/ku3pSvSOQplu iVMXjK1BQ5DYtzYSPuuxt81Wamwm4KG1aTYswk8u89oycoaniGPM2t601JTswhpZ6p9J B8Sg== 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=59bBfPtSUCGvNMcSTdpjSCDzJRpQrgjnv9vA94G1rY0=; fh=jHlABrYnApVt5KJlrthitgyo0hqpWWrdlN0oFT+yLLg=; b=vOnrZmYIWGmqHfuXnE6x6EJY2bRU+31DEUKAtvbaX5DmHtEReKkhRX1acZvSQk1R8V 3Yz3PHLeRCZjhajgJBOT0X6yN9pHkm6Y1TA4B2xhTjMR9/luEW1ovG+qchioA1v2YMu7 UzSe4S5B4K2073pTZYFmb/9GGxxWopF6AbPzhjYwuaPhHNEmpYmfkSi5CI0Q4iyVx1l5 DfXHdRvDwTJmn9jqH1iqNzWLv9/vfHgSHylaSSG62udq+unWNtlDqtjoyM1kGlDjthbZ NIL1jtaQqWnwq1eeYmPdKDChBuBKz6xJ6yvemzpyceLegB6mM5GA2JqlSV9JMWHxzjbT 0lTg==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=e0NBs1SQ; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77115-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77115-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [139.178.88.99]) by mx.google.com with ESMTPS id e15-20020a63744f000000b005dc8834047esi10448291pgn.422.2024.02.22.10.31.46 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Feb 2024 10:31:46 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-77115-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=e0NBs1SQ; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77115-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77115-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 3552A283953 for ; Thu, 22 Feb 2024 18:31:36 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 73A4F14F96E; Thu, 22 Feb 2024 18:16:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="e0NBs1SQ" 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 7FC8A14EFFB; Thu, 22 Feb 2024 18:16:06 +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=1708625766; cv=none; b=bSCVsfet0q7g0Iw951aK7FM9f8Na5uAbyZTSPHei9VrCIFatuv3zMTZUlkzMTsTx0twEs3C2paSUMEL9gp9FyFRULu9Pjl2+hHfBQxm+nSl/ijDPApv5FcIOZmfmwfQGL5AeTgjIt7wMmltjKQVAh+xVoPNWf7D/5CGKVvN5zNM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708625766; c=relaxed/simple; bh=T+Mwu+EH8KKp7SKPsP5xhhewnkamDcEqVw1vxC33JeM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=GNosw6wEF/5Qc9Biob+O65u0vosXRFo0CEtRAFWTdnxbSXm7UKiEnj9OXcHKU+7EAGYd0KLeOeGPHRvwPzNxLyiYbS7hP/K6ltNzRIzSFHbazIuEstbcMliQvZFYWO8VIz7KVE/x/uVLAEIW4cCwxvKvjMiIsJNzPO50+siFQAg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=e0NBs1SQ; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 047AEC433F1; Thu, 22 Feb 2024 18:16:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1708625766; bh=T+Mwu+EH8KKp7SKPsP5xhhewnkamDcEqVw1vxC33JeM=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=e0NBs1SQK24/CJ6wPapKpX3i/K65QEnaHjdddDM0lnaMo1WqBIMwjvYDgghLy069h DcxpGwEHv90/ZDwYP3EJw3ze23GA5Jd4gOvDS4c/NnDIdQDIAmfJ5HcyfTWXHSYyj/ 34ZFrNj9fIdaxy/EpGuLsJnJDgk9zYP+i0sDF7HM5idpNHN96r2lxa4hWYCttdNStY HbfgSKORdKnYqk7tMLEtle3fQTK65+D+CWaZgBdVsC0gu7CNgejddL6JqCqUNfDkxT qtu+X236s+8/mPmg5HfBrYUOcyWJrX26xgtf2MxpI71w4T/6GsUTQQZLWX5V6g+pvi JFJ+VvIQwX7ig== From: Maxime Ripard Date: Thu, 22 Feb 2024 19:14:21 +0100 Subject: [PATCH v7 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: <20240222-kms-hdmi-connector-state-v7-35-8f4af575fce2@kernel.org> References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , Sebastian Wick , =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= , dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-sunxi@lists.linux.dev, Maxime Ripard , 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=T+Mwu+EH8KKp7SKPsP5xhhewnkamDcEqVw1vxC33JeM=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKnX+/4nvJn7iXPDwx83j1tOMPO3WD27Lad3PdePqgrfX pN7D/9Wd5SyMIhxMciKKbLECJsviTs163UnG988mDmsTCBDGLg4BWAiM9kZGa6+uHcz8iajdM+n 1yz3q1f/DbtRuWVe7AnNc4t2GKss5ddh+F+lLhZy3mS2SOB7m2e7S+5qqb6olti+7PUck9BnMyU WmzMAAA== X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791624956995894336 X-GMAIL-MSGID: 1791624956995894336 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 Reviewed-by: Jernej Skrabec --- 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 Thu Feb 22 18:14:22 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 204983 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:a81b:b0:108:e6aa:91d0 with SMTP id bq27csp131357dyb; Thu, 22 Feb 2024 10:31:56 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCVVvoq2SOpzvDAfQTWDTIsgOIKCpZy/O5nfVVqp7ne7AblhoAk/B6IwQUIs0NAmZAid4m6bHJMJSwfri/EeogVzViMCYA== X-Google-Smtp-Source: AGHT+IGbYqw1JONOICiaBJF+uwpfqrieaGBgKEy8TyGnkFem8KFP7cQDpKiZs27nXcR+a2MvV3uK X-Received: by 2002:a05:6808:1296:b0:3c1:3659:1e9e with SMTP id a22-20020a056808129600b003c136591e9emr30504410oiw.1.1708626716722; Thu, 22 Feb 2024 10:31:56 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708626716; cv=pass; d=google.com; s=arc-20160816; b=fh80L5NSBNpRRgVPdJU09lUX2v3RfRg/NB3SFwQOmCMV2Z3nbz8B7iqrueLelfID97 7y9Ty/N9kikbfifcP4WJ1TBq3/BiD0yWqourgkvjhu8Ri25modKrCkd+eBkQoZDPzDXY p1iKmsNWtempVymwcf8CbgOqCOL7GKTXlbcBk8HSTZJAQlPqDEfY1bUTK9Bu9yiVzCnV 7tWB9TrN4/1NZVBeBcXJg4keWhv/uDOwRnJ02UcfgbZotInDEwma7y4z3wL1AFWbZuEc /W0pWRIY6ucC8KZAPnwGewbcXBTY8Jo3vle08GPOyKGIg9HuoPxqhbgBJf7Ef+8u/nmq RnOQ== 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=iCVlZ9Qpr1LuGjfWSAeKdcRtTEyvNEtLLqt7tzyaHBs=; fh=7mnR4/DMo6zaWtUGaVI9DND4TR+QGflpVaaXOChu5h0=; b=DeWF/YhRyYzMSK13DG6+k9xAieX+iYxAOsKSbRLd2vOyrIvyM71585rfVoUd4XfCj/ baF11qJKRORoKGB2RX4zwJ11ia4DdF1XPWA7BQc67400uKpHZDOhWagJXPIkoxageuD0 a/5gbxJELoeLFsF2tyzMHJix/KMggfhecSJ1QiphhuF/MjoS18XBdXVb9ejPxdkU2k4h RkG5xA+MXCM+4B/gXRgrmxAC+1C8uXWNbZAi8zHm8BdUg9dJp7qNqkXuwU6ZVpCT3KOM fhNiikvo7hWnlJv91DjrDKtm+bizNcy3MplfZ8FV9OS4et/7hWrodJklVPjn70YrMWgs lw1g==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=lePtnIN0; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77116-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77116-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [147.75.199.223]) by mx.google.com with ESMTPS id u4-20020a05620a022400b0078725bf52b5si13586636qkm.347.2024.02.22.10.31.56 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Feb 2024 10:31:56 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-77116-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=lePtnIN0; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-77116-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-77116-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 565D71C22480 for ; Thu, 22 Feb 2024 18:31:56 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id B71BE14F997; Thu, 22 Feb 2024 18:16:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="lePtnIN0" 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 86A4E14F976; Thu, 22 Feb 2024 18:16:09 +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=1708625770; cv=none; b=kFSN7JYyt4iKZdRUTDFYzjZkoRNW51Yrbap12XXsklXcTWkV4oidJXUuOgFQGypsLr91neAiLXnyMuk8L4WpwK3obCh9jKSszW13adxO4eXRY//9HZ/Odrpa20OZqbqjHVD9B/S7RumkXNVPTgWn7MQq3NKrRA/n0GP4L9+OLd4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708625770; c=relaxed/simple; bh=me+TC+MJwDNsQY674FZNF6/iuJyXullN9d+BLYm0P5M=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=N22C1k233hUH38/UgfYdUSniEOA+GH1m4v7aTEFzXhOb5uMp5zXpsP77MYSnWwnMtCHsE9IJ4skq+5JhYfxIVjwR7MnOuLCEaswTM52JiNF+gZ9nJT1OjFxGv/gmoXPo/4qIWv4ajNaEWV9xBT5uShxMCNhcogkgNq6+LPWblb8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=lePtnIN0; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id C28B7C433C7; Thu, 22 Feb 2024 18:16:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1708625769; bh=me+TC+MJwDNsQY674FZNF6/iuJyXullN9d+BLYm0P5M=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=lePtnIN0M+MEaJxjLvH8xN46aaX/pz3nKDjcIdAl45MtnOmkuaDm17MPU6n3w5bIT BUfKXhbbYBgipl0YzFznRNNzij7A6Xfj8bLXVolnSmONCh7gi43/f9LjklDfIBbsRG pX7hXS/1M05M9co/X+Xk3O8Go7DKEtZEOg/PF9IYW6hPPws0QG3+0/HSoL/Q0ECFgP RESoKfPEb/NeDczRjDYG2kXYe134M7WpznM2/atXH9MYKJ12tJPaJGS0Ijg4xSi/NJ ya2/b9mtu3dkNCK5tkF8JVNVHNGjtVMTbACp6jzJA50jVegovxWw7dfFEj82YZrXkn OzYsrdQCfzMJA== From: Maxime Ripard Date: Thu, 22 Feb 2024 19:14:22 +0100 Subject: [PATCH v7 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: <20240222-kms-hdmi-connector-state-v7-36-8f4af575fce2@kernel.org> References: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> In-Reply-To: <20240222-kms-hdmi-connector-state-v7-0-8f4af575fce2@kernel.org> To: Maarten Lankhorst , Thomas Zimmermann , David Airlie , Daniel Vetter , Jonathan Corbet , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland Cc: Hans Verkuil , Sebastian Wick , =?utf-8?b?VmlsbGUgU3lyasOkbMOk?= , dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-sunxi@lists.linux.dev, Maxime Ripard 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=me+TC+MJwDNsQY674FZNF6/iuJyXullN9d+BLYm0P5M=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDKnX+xn2psVcOfSrb7OthJX8Wp2Xx0zdXbZZblggaX/k6 6Ufs9NvdZSwMIhxMciKKbLECJsviTs163UnG988mDmsTCBDGLg4BWAiFpMYGdbH8ildumKZY5lX 1Pmn49y7S9yzZJc7T5EvU1aZGPdYKpfhx+ZZnN9C4/5yRF38ofnsw0e+67NuWoeI33cNfvVt/sp V/AA= X-Developer-Key: i=mripard@kernel.org; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791624968363243259 X-GMAIL-MSGID: 1791624968363243259 The new HDMI connector infrastructure allows to remove some boilerplate, especially to generate infoframes. Let's switch to it. Signed-off-by: Maxime Ripard Reviewed-by: Jernej Skrabec Acked-by: Sui Jingfeng --- 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");