From patchwork Wed Oct 26 15:33:35 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 13020778 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 9E9DEC38A2D for ; Wed, 26 Oct 2022 15:35:51 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id D13EF10E54F; Wed, 26 Oct 2022 15:34:19 +0000 (UTC) Received: from new4-smtp.messagingengine.com (new4-smtp.messagingengine.com [66.111.4.230]) by gabe.freedesktop.org (Postfix) with ESMTPS id C325710E50B; Wed, 26 Oct 2022 15:34:05 +0000 (UTC) Received: from compute5.internal (compute5.nyi.internal [10.202.2.45]) by mailnew.nyi.internal (Postfix) with ESMTP id 2BB2F58020E; Wed, 26 Oct 2022 11:34:05 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute5.internal (MEProxy); Wed, 26 Oct 2022 11:34:05 -0400 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=fm3; t=1666798445; x= 1666805645; bh=1T+7LmwysEui9fmTjQ2jT2uQZZdRAQ2dvrVSUd976IE=; b=o BHA9uC+T4rta9AjW1tIFE7JRJt2Sq3b/Be1eM2yj+25txLj+snhVlZh/g9eoCkYj j4OoQe7Y26L5IrXr5zstdHqIhayW/f2qmbdwEQydC9ET7yTsUHTEk0sYrJXHd5Hv lVuwxvR028QLJwplvnDC712COqVs3h3OCrHCB4einkDhK039n/HsV/jDkWtWV/uW uOhAa5AL41PDtUm2naloZSXQbJ6LXpnQ8MSpybF4dtmysoFNNaYCEhXeVlQRgkaI oHcOBvzyFZloDPAHn13caDLKHD+A5RAlqyxOye9zHkPK2HXp/Ir8SKVuVca+QA2z NX8G1M8aStT9sjDLAAk5A== 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=fm3; t=1666798445; x= 1666805645; bh=1T+7LmwysEui9fmTjQ2jT2uQZZdRAQ2dvrVSUd976IE=; b=h 9kjxR5GpTLsXqxA4yq36eydTqZVdH22J/TX30KCcN+kkQhOEqtP6eB9uCPEnR8fY r76ujTbJ0zzMf9SlurVehA3ZGnxMCPqV8UBBsZh3+81g0Jt9rxYmf79QU0/jwCIG ImI79m0ZdEIlwUVyu/sNd5ZdBLyIQ1V1niwfTyqZsXe6UTRkofbW7uPVxuzQWve/ 8nbanSrtpsMoRQAsMI1CL9axRfo+SvP97qbTrDU8R1DpP/yoEq5Qb9NjKScCplOE 9BR+ddaj/qcUkfPFwnlV9c+A2kMRgc1ZE8yBu/RoCXpl1B7d51HZOS60ITLGGUaP 2j6CD4YTUd5ZJvZ4ToNRw== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvgedrtddvgdeltdcutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpefhfffugggtgffkfhgjvfevofesthekredtredtjeenucfhrhhomhepmhgrgihi mhgvsegtvghrnhhordhtvggthhenucggtffrrghtthgvrhhnpeefudfhgeevhefhfedtue evueeluddutdetuddtvddvgeekheelvefhteekteeihfenucevlhhushhtvghrufhiiigv pedvnecurfgrrhgrmhepmhgrihhlfhhrohhmpehmrgigihhmvgestggvrhhnohdrthgvtg hh X-ME-Proxy: Feedback-ID: i8771445c:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Wed, 26 Oct 2022 11:34:04 -0400 (EDT) From: maxime@cerno.tech Date: Wed, 26 Oct 2022 17:33:35 +0200 MIME-Version: 1.0 Message-Id: <20220728-rpi-analog-tv-properties-v6-16-e7792734108f@cerno.tech> References: <20220728-rpi-analog-tv-properties-v6-0-e7792734108f@cerno.tech> In-Reply-To: <20220728-rpi-analog-tv-properties-v6-0-e7792734108f@cerno.tech> To: Karol Herbst , Emma Anholt , Ben Skeggs , Chen-Yu Tsai , Rodrigo Vivi , Maarten Lankhorst , Jani Nikula , Daniel Vetter , Thomas Zimmermann , Tvrtko Ursulin , Samuel Holland , Jernej Skrabec , David Airlie , Maxime Ripard , Joonas Lahtinen , Lyude Paul X-Mailer: b4 0.11.0-dev-99e3a X-Developer-Signature: v=1; a=openpgp-sha256; l=4600; i=maxime@cerno.tech; h=from:subject:message-id; bh=kB8d4Q2Rea+o0SLUJtfAVmIRp8jA5wLsaZa5DDIbyWs=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDMmRwe7TL/xh2l7ifkGKyXLuhplXovZ6m2+8djRKSFX/7Eyt iCzejlIWBjEuBlkxRZYYYfMlcadmve5k45sHM4eVCWQIAxenAEzEqIaR4c2vb7EejoVpNXtXmul91t 4iJnZVXfHHpV9JF/8Yejy6FMLIcLNp5U0zx9O2z21u3vOYPn35KyvBqMg9DkyGD3ly7NTtOQE= X-Developer-Key: i=maxime@cerno.tech; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D Subject: [Intel-gfx] [PATCH v6 16/23] drm/probe-helper: Provide a TV get_modes helper X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & 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_linux-sunxi=40lists=2E?= =?unknown-8bit?q?linux=2Edev=2C_Hans_de_Goede_=3Chdegoede=40redhat=2Ecom=3E?= =?unknown-8bit?q?=2C_Noralf_Tr=C3=B8nnes_=3Cnoralf=40tronnes=2Eorg=3E=2C_Ge?= =?unknown-8bit?q?ert_Uytterhoeven_=3Cgeert=40linux-m68k=2Eorg=3E=2C_Maxime_?= =?unknown-8bit?q?Ripard_=3Cmaxime=40cerno=2Etech=3E=2C_Mateusz_Kwiatkowski_?= =?unknown-8bit?q?=3Ckfyatek+publicgit=40gmail=2Ecom=3E=2C_Phil_Elwell_=3Cph?= =?unknown-8bit?q?il=40raspberrypi=2Ecom=3E=2C_linux-arm-kernel=40lists=2Ein?= =?unknown-8bit?q?fradead=2Eorg?= Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" 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: Maxime Ripard --- 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 69b0b2b9cc1c..4a60575f5c66 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_cmdline_mode *cmdline = &connector->cmdline_mode; + struct drm_display_mode *tv_modes[2] = {}; + struct drm_display_mode *mode; + unsigned int first_mode_idx; + unsigned int count = 0; + uint64_t default_mode; + int ret; + + if (!dev->mode_config.tv_mode_property) + return 0; + + if (tv_mode_supported(connector, DRM_MODE_TV_MODE_NTSC) || + tv_mode_supported(connector, DRM_MODE_TV_MODE_NTSC_443) || + tv_mode_supported(connector, DRM_MODE_TV_MODE_NTSC_J) || + tv_mode_supported(connector, DRM_MODE_TV_MODE_PAL_M)) { + mode = drm_mode_analog_ntsc_480i(connector->dev); + if (!mode) + return 0; + + tv_modes[count++] = mode; + } + + if (tv_mode_supported(connector, DRM_MODE_TV_MODE_PAL) || + tv_mode_supported(connector, DRM_MODE_TV_MODE_PAL_N) || + tv_mode_supported(connector, DRM_MODE_TV_MODE_SECAM)) { + mode = drm_mode_analog_pal_576i(connector->dev); + if (!mode) + return 0; + + tv_modes[count++] = mode; + } + + if (count == 1) { + mode->type |= DRM_MODE_TYPE_PREFERRED; + drm_mode_probed_add(connector, mode); + return count; + } + + ret = drm_object_property_get_default_value(&connector->base, + dev->mode_config.tv_mode_property, + &default_mode); + if (ret) + return 0; + + if (cmdline->tv_mode_specified) + default_mode = cmdline->tv_mode; + + if ((default_mode == DRM_MODE_TV_MODE_NTSC) || + (default_mode == DRM_MODE_TV_MODE_NTSC_443) || + (default_mode == DRM_MODE_TV_MODE_NTSC_J) || + (default_mode == DRM_MODE_TV_MODE_PAL_M)) + first_mode_idx = 0; + else + first_mode_idx = 1; + + mode = tv_modes[first_mode_idx]; + mode->type |= DRM_MODE_TYPE_PREFERRED; + drm_mode_probed_add(connector, mode); + + mode = first_mode_idx ? tv_modes[0] : tv_modes[1]; + drm_mode_probed_add(connector, mode); + + return count; +} +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