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: 13020846 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (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 7AEAEC38A2D for ; Wed, 26 Oct 2022 15:45:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:In-Reply-To:References:Message-Id :MIME-Version:Subject:Date:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=gOgtTL0+gk2CtHaSUZDLUeuluCH/M+khK0ZcLHODjMI=; b=GNu7+bViTS44Ca kwymllXzzIIHFxwazNlOkgnsgcO9MzsMpDNWx97aLCDUKeaP5x3vP7/XMQzu0qwFIEe8ZbG7guZdG Tx0k6pMeysuoGigMxnj/Yp30EfkPAkhPIy3aOHj3aLLIySmJZmHJHVOXnJaGltjyUad34foIu0H8X lhdK650rtBPgs9H85ldEjQIQPJSZcpX9yo1sLvvcv7RMDStVKOO41ISqZH6F3X1ByIZdGJZhJratW WSyYgcfUAIfYPnpp2N5ILxBrcv9gWCISw/ccwrWkbEjlk0XDKk/Bs9q94tAtaLpC7Z5kBADtSVtoF buH45p1JKoXp/w/8wqbQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1oniYp-009xuW-Df; Wed, 26 Oct 2022 15:43:20 +0000 Received: from new4-smtp.messagingengine.com ([66.111.4.230]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1oniPt-009u9P-PF for linux-arm-kernel@lists.infradead.org; Wed, 26 Oct 2022 15:34:07 +0000 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 Subject: [PATCH v6 16/23] drm/probe-helper: Provide a TV get_modes helper 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 Cc: =?unknown-8bit?q?linux-sunxi=40lists=2Elinux=2Edev=2C_Maxime_Ripard_=3Cm?= =?unknown-8bit?q?axime=40cerno=2Etech=3E=2C_intel-gfx=40lists=2Efreedesktop?= =?unknown-8bit?q?=2Eorg=2C?= =?unknown-8bit?q?_Phil_Elwell_=3Cphil=40raspberrypi=2Ecom=3E=2C_linux-arm-ke?= =?unknown-8bit?q?rnel=40lists=2Einfradead=2Eorg=2C_nouveau=40lists=2Efreede?= =?unknown-8bit?q?sktop=2Eorg=2C?= =?unknown-8bit?q?_Hans_de_Goede_=3Chdegoede=40redhat=2Ecom=3E=2C_Dom_Cobley_?= =?unknown-8bit?q?=3Cdom=40raspberrypi=2Ecom=3E=2C?= =?unknown-8bit?q?_Mateusz_Kwiatkowski_=3Ckfyatek+publicgit=40gmail=2Ecom=3E?= =?unknown-8bit?q?=2C_dri-devel=40lists=2Efreedesktop=2Eorg=2C?= =?unknown-8bit?q?_Dave_Stevenson_=3Cdave=2Estevenson=40raspberrypi=2Ecom=3E?= =?unknown-8bit?q?=2C_linux-kernel=40vger=2Ekernel=2Eorg=2C_Noralf_Tr=C3=B8n?= =?unknown-8bit?q?nes_=3Cnoralf=40tronnes=2Eorg=3E=2C?= =?unknown-8bit?q?_Geert_Uytterhoeven_=3Cgeert=40linux-m68k=2Eorg=3E?= 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 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20221026_083405_941855_1C6DAB0D X-CRM114-Status: GOOD ( 17.32 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org 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