From patchwork Mon Nov 7 14:16:42 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 13034458 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 55C78C4332F for ; Mon, 7 Nov 2022 14:18:51 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 6037A10E353; Mon, 7 Nov 2022 14:18:10 +0000 (UTC) Received: from wnew2-smtp.messagingengine.com (wnew2-smtp.messagingengine.com [64.147.123.27]) by gabe.freedesktop.org (Postfix) with ESMTPS id 7801210E34F; Mon, 7 Nov 2022 14:17:57 +0000 (UTC) Received: from compute2.internal (compute2.nyi.internal [10.202.2.46]) by mailnew.west.internal (Postfix) with ESMTP id 7A9102B06703; Mon, 7 Nov 2022 09:17:54 -0500 (EST) Received: from mailfrontend2 ([10.202.2.163]) by compute2.internal (MEProxy); Mon, 07 Nov 2022 09:17:56 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cerno.tech; h=cc :cc:content-transfer-encoding:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:sender:subject:subject:to:to; s=fm2; t=1667830674; x= 1667837874; bh=0oKN06VO67RLG+n7WmkLW6tgiE6KcW8ogpBlG4slTm0=; b=T SZThQoOfOpadCSXuXBXf3hL1SnCUUyO5UPZy82pOMnHuHbWtL0hqLEl1vm/GWOGT 6vhfXQhfjfaqeO4/KrPZXUnkBVLtYY4hnIXxi7f3kVSxeHKBgGyp0QjuJ8UI1sVa arH0J4MzxoTzWTZddv00B4lheSbSBnLn2Zop9ZXW+OUdj+ilpzqElLVZ8MEgcRUy N4w6h8NYD/2s5/y4AYeuL9vadYVYANncnCPsHHU5KRxUGRNLgqTBRkja90BZqfYI 5f32jU/C+amqpezMaZX18LuJQQuDmrysU1msAVImTSI0W7Y/1IAM6+HX7VUb0/zy //oGBPUiNVjJzOdvtDQ+g== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:sender:subject:subject:to:to:x-me-proxy:x-me-proxy :x-me-sender:x-me-sender:x-sasl-enc; s=fm1; t=1667830674; x= 1667837874; bh=0oKN06VO67RLG+n7WmkLW6tgiE6KcW8ogpBlG4slTm0=; b=A 8TDYdyE2TOP1awAkhdEVsUPJGeeUskMBXPdwatW90dAbuE9spju4cWHJlu5p2jGL Ga0xcinVdvdc0DJ6Wq9F9+hMAoEuZpvwrUwx8MBt/km++qyZDK6Me6RCBNVDwYxI 6Z1woIJ7RaRrsiu0+6t3LcU5/FmY5yqWy5sVDsKHjy09lsQSPmmbZ+Cf6Lskqv28 cjbfc9P9rld7pA85Z9Z+OJrUGE7HpYiCuFuz3L6NQFTlxj89kHY2JBbtBBSqO7eF 6PuHElGl/3ZDFIhGzcpVjJ/zA9bgMMXRPGjTcb45GUJk33MeiS1kjxrwuAr/XjWf QDAzyce6B1LfUdtxuJfag== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvgedrvdekgdeiudcutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpefhfffuggfgtgfkfhgjvfevofesthekredtredtjeenucfhrhhomhepofgrgihi mhgvucftihhprghrugcuoehmrgigihhmvgestggvrhhnohdrthgvtghhqeenucggtffrrg htthgvrhhnpedvgfevjefhtdetveevhfelieeuueetgfdvgeevkeegudejffegfffgtedt leelhfenucevlhhushhtvghrufhiiigvpedvnecurfgrrhgrmhepmhgrihhlfhhrohhmpe hmrgigihhmvgestggvrhhnohdrthgvtghh X-ME-Proxy: Feedback-ID: i8771445c:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 7 Nov 2022 09:17:53 -0500 (EST) From: Maxime Ripard Date: Mon, 07 Nov 2022 15:16:42 +0100 Subject: [PATCH v7 16/23] drm/probe-helper: Provide a TV get_modes helper MIME-Version: 1.0 Message-Id: <20220728-rpi-analog-tv-properties-v7-16-7072a478c6b3@cerno.tech> References: <20220728-rpi-analog-tv-properties-v7-0-7072a478c6b3@cerno.tech> In-Reply-To: <20220728-rpi-analog-tv-properties-v7-0-7072a478c6b3@cerno.tech> To: Jani Nikula , Joonas Lahtinen , Tvrtko Ursulin , Ben Skeggs , Rodrigo Vivi , Maxime Ripard , Samuel Holland , Jernej Skrabec , Maarten Lankhorst , Emma Anholt , Karol Herbst , Daniel Vetter , Chen-Yu Tsai , Lyude Paul , Thomas Zimmermann , David Airlie X-Mailer: b4 0.11.0-dev-99e3a X-Developer-Signature: v=1; a=openpgp-sha256; l=4733; i=maxime@cerno.tech; h=from:subject:message-id; bh=KsSg3MkYNbvBUDSlVgBJTS6Fc0RFsDQehn1uu8plmuo=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDMmZwg75uftfNhpoLL5SIWid7Ho/0sLOsXfVtPgA449flL0f H0vrKGVhEONikBVTZIkRNl8Sd2rW6042vnkwc1iZQIYwcHEKwEQq/RkZ3s3/9H2VZL/egyvFFe919C +IqRr6MtzZ+zV1OUu2/j+3bkaGczxhLvt5vA3Kaib4Hng65X3CDJlfJ2eKzKv2Dk17ZFLMDQA= X-Developer-Key: i=maxime@cerno.tech; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?unknown-8bit?q?Dom_Cobley_=3Cdom=40raspberrypi=2Ecom=3E=2C_Dave_Steven?= =?unknown-8bit?q?son_=3Cdave=2Estevenson=40raspberrypi=2Ecom=3E=2C_nouveau?= =?unknown-8bit?q?=40lists=2Efreedesktop=2Eorg=2C_intel-gfx=40lists=2Efreede?= =?unknown-8bit?q?sktop=2Eorg=2C_linux-kernel=40vger=2Ekernel=2Eorg=2C_dri-d?= =?unknown-8bit?q?evel=40lists=2Efreedesktop=2Eorg=2C_Phil_Elwell_=3Cphil=40?= =?unknown-8bit?q?raspberrypi=2Ecom=3E=2C_Hans_de_Goede_=3Chdegoede=40redhat?= =?unknown-8bit?q?=2Ecom=3E=2C_Noralf_Tr=C3=B8nnes_=3Cnoralf=40tronnes=2Eorg?= =?unknown-8bit?q?=3E=2C_Geert_Uytterhoeven_=3Cgeert=40linux-m68k=2Eorg=3E?= =?unknown-8bit?q?=2C_Maxime_Ripard_=3Cmaxime=40cerno=2Etech=3E=2C_Mateusz_K?= =?unknown-8bit?q?wiatkowski_=3Ckfyatek+publicgit=40gmail=2Ecom=3E=2C_linux-?= =?unknown-8bit?q?sunxi=40lists=2Elinux=2Edev=2C_linux-arm-kernel=40lists=2E?= =?unknown-8bit?q?infradead=2Eorg?= Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" From: Noralf Trønnes Most of the TV connectors will need a similar get_modes implementation that will, depending on the drivers' capabilities, register the 480i and 576i modes. That implementation will also need to set the preferred flag and order the modes based on the driver and users preferrence. This is especially important to guarantee that a userspace stack such as Xorg can start and pick up the preferred mode while maintaining a working output. Signed-off-by: Noralf Trønnes Signed-off-by: Maxime Ripard --- Changes in v7: - Used Noralf's implementation Changes in v6: - New patch --- drivers/gpu/drm/drm_probe_helper.c | 97 ++++++++++++++++++++++++++++++++++++++ include/drm/drm_probe_helper.h | 1 + 2 files changed, 98 insertions(+) diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c index 2fc21df709bc..edb2e4c4530a 100644 --- a/drivers/gpu/drm/drm_probe_helper.c +++ b/drivers/gpu/drm/drm_probe_helper.c @@ -1147,3 +1147,100 @@ int drm_connector_helper_get_modes(struct drm_connector *connector) return count; } EXPORT_SYMBOL(drm_connector_helper_get_modes); + +static bool tv_mode_supported(struct drm_connector *connector, + enum drm_connector_tv_mode mode) +{ + struct drm_device *dev = connector->dev; + struct drm_property *property = dev->mode_config.tv_mode_property; + + unsigned int i; + + for (i = 0; i < property->num_values; i++) + if (property->values[i] == mode) + return true; + + return false; +} + +/** + * drm_connector_helper_tv_get_modes - Fills the modes availables to a TV connector + * @connector: The connector + * + * Fills the available modes for a TV connector based on the supported + * TV modes, and the default mode expressed by the kernel command line. + * + * This can be used as the default TV connector helper .get_modes() hook + * if the driver does not need any special processing. + * + * Returns: + * The number of modes added to the connector. + */ +int drm_connector_helper_tv_get_modes(struct drm_connector *connector) +{ + struct drm_device *dev = connector->dev; + struct drm_property *tv_mode_property = + dev->mode_config.tv_mode_property; + struct drm_cmdline_mode *cmdline = &connector->cmdline_mode; + unsigned int ntsc_modes = BIT(DRM_MODE_TV_MODE_NTSC) | + BIT(DRM_MODE_TV_MODE_NTSC_443) | + BIT(DRM_MODE_TV_MODE_NTSC_J) | + BIT(DRM_MODE_TV_MODE_PAL_M); + unsigned int pal_modes = BIT(DRM_MODE_TV_MODE_PAL) | + BIT(DRM_MODE_TV_MODE_PAL_N) | + BIT(DRM_MODE_TV_MODE_SECAM); + unsigned int tv_modes[2] = { UINT_MAX, UINT_MAX }; + unsigned int i, supported_tv_modes = 0; + + if (!tv_mode_property) + return 0; + + for (i = 0; i < tv_mode_property->num_values; i++) + supported_tv_modes |= BIT(tv_mode_property->values[i]); + + if ((supported_tv_modes & ntsc_modes) && + (supported_tv_modes & pal_modes)) { + uint64_t default_mode; + + if (drm_object_property_get_default_value(&connector->base, + tv_mode_property, + &default_mode)) + return 0; + + if (cmdline->tv_mode_specified) + default_mode = cmdline->tv_mode; + + if (BIT(default_mode) & ntsc_modes) { + tv_modes[0] = DRM_MODE_TV_MODE_NTSC; + tv_modes[1] = DRM_MODE_TV_MODE_PAL; + } else { + tv_modes[0] = DRM_MODE_TV_MODE_PAL; + tv_modes[1] = DRM_MODE_TV_MODE_NTSC; + } + } else if (supported_tv_modes & ntsc_modes) { + tv_modes[0] = DRM_MODE_TV_MODE_NTSC; + } else if (supported_tv_modes & pal_modes) { + tv_modes[0] = DRM_MODE_TV_MODE_PAL; + } else { + return 0; + } + + for (i = 0; i < ARRAY_SIZE(tv_modes); i++) { + struct drm_display_mode *mode; + + if (tv_modes[i] == DRM_MODE_TV_MODE_NTSC) + mode = drm_mode_analog_ntsc_480i(dev); + else if (tv_modes[i] == DRM_MODE_TV_MODE_PAL) + mode = drm_mode_analog_pal_576i(dev); + else + break; + if (!mode) + return i; + if (!i) + mode->type |= DRM_MODE_TYPE_PREFERRED; + drm_mode_probed_add(connector, mode); + } + + return i; +} +EXPORT_SYMBOL(drm_connector_helper_tv_get_modes); diff --git a/include/drm/drm_probe_helper.h b/include/drm/drm_probe_helper.h index 5880daa14624..4977e0ab72db 100644 --- a/include/drm/drm_probe_helper.h +++ b/include/drm/drm_probe_helper.h @@ -35,5 +35,6 @@ int drm_connector_helper_get_modes_from_ddc(struct drm_connector *connector); int drm_connector_helper_get_modes_fixed(struct drm_connector *connector, const struct drm_display_mode *fixed_mode); int drm_connector_helper_get_modes(struct drm_connector *connector); +int drm_connector_helper_tv_get_modes(struct drm_connector *connector); #endif