From patchwork Mon Aug 29 13:11:23 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 12957864 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 9BD8CECAAD2 for ; Mon, 29 Aug 2022 13:21:02 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 3CD4010F275; Mon, 29 Aug 2022 13:21:00 +0000 (UTC) Received: from wnew2-smtp.messagingengine.com (wnew2-smtp.messagingengine.com [64.147.123.27]) by gabe.freedesktop.org (Postfix) with ESMTPS id 015D210F29A; Mon, 29 Aug 2022 13:20:48 +0000 (UTC) Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailnew.west.internal (Postfix) with ESMTP id 50F762B06051; Mon, 29 Aug 2022 09:13:02 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute4.internal (MEProxy); Mon, 29 Aug 2022 09:13: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=1661778781; x= 1661785981; bh=pUcO8T1pRwVJWUV8j5AkJO7nJ/phgtzS7l6oijEk91k=; b=h jk77p72PHGwqdvEqsHEDJdrp59h9UVzI4KyqYLcBOusFW5OUwh2WxIopUiZEJZEb A7rJHnP2caSC+4AtlMk+IahxrWomMpNX4ZzZm+8WC8cgznTps1HzPbdPTtGMYFJk 9Z+E6kvgNMam9sNTsVVt/27/Y6XSd8b14Io+0F1wYV6A+oV06Q373O7cg/98YWF4 QC5YfoFiyFrpS474bfT4V+n0ox9tzkU4KGIdxtHe07Ko3WESplL0Z2VZasehYSM8 Pfmc/ANOTJrUFaxUtCfEf101vXS63YS4p3BM50RUj6TEeQFc8HeZCkVM/OVL+zK/ foCTww06TxuT1OWKdaiSA== 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=1661778781; x= 1661785981; bh=pUcO8T1pRwVJWUV8j5AkJO7nJ/phgtzS7l6oijEk91k=; b=Y xREWxW9XhwrXljndhgR4ufOrG6NShB8SW5oLtNps8h7Xl9eJdide4pX4jCYGIHAn ogpI2Aggdgnv/EsAdSmRVvUhx8V6AmuPEB20Js4jTCBuJCBdxA3KuY2C38Iy6pOv 26EgWBIIZkYPe57SDvDrnlocVM/0VeAsecBCL+scrBSDRqubuiPQYVtVTxeVErQA tHGguaMYQKnFJ7U6qB44j5B8KqzJjoJH5p+JT0yHrZMp1bhJbuqt2kWtdzyEYI5M vi+S0bFPBNBMdEHU9sgtAlwa4GEAJCFigcv6XLW2T97vH8w6/MhyMx0QFSXpeq4S e3PrtU58lkQKhj2KjCsZQ== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvfedrvdekuddgieefucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhephffvvefufffkofgjfhggtgfogfesthhqredtredtjeenucfhrhhomhepofgr gihimhgvucftihhprghrugcuoehmrgigihhmvgestggvrhhnohdrthgvtghhqeenucggtf frrghtthgvrhhnpeefiedvfefggffgffehveejieffuddtgffhjefggeetieduvdeileet lefgveegtdenucevlhhushhtvghrufhiiigvpedunecurfgrrhgrmhepmhgrihhlfhhroh hmpehmrgigihhmvgestggvrhhnohdrthgvtghh X-ME-Proxy: Feedback-ID: i8771445c:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 29 Aug 2022 09:13:00 -0400 (EDT) From: Maxime Ripard To: Maxime Ripard , Ben Skeggs , David Airlie , Chen-Yu Tsai , Thomas Zimmermann , Jani Nikula , Lyude Paul , Philipp Zabel , Maarten Lankhorst , Rodrigo Vivi , Tvrtko Ursulin , Jernej Skrabec , Samuel Holland , Karol Herbst , =?utf-8?q?Noralf_Tr=C3=B8nnes?= , Emma Anholt , Daniel Vetter , Joonas Lahtinen Date: Mon, 29 Aug 2022 15:11:23 +0200 Message-Id: <20220728-rpi-analog-tv-properties-v2-9-459522d653a7@cerno.tech> X-Mailer: git-send-email 2.37.1 In-Reply-To: <20220728-rpi-analog-tv-properties-v2-0-459522d653a7@cerno.tech> References: <20220728-rpi-analog-tv-properties-v2-0-459522d653a7@cerno.tech> MIME-Version: 1.0 X-Mailer: b4 0.10.0-dev-65ba7 X-Developer-Signature: v=1; a=openpgp-sha256; l=11994; i=maxime@cerno.tech; h=from:subject:message-id; bh=0imIXTKfc8i6bjpLPiDjTCY1QehnDS9P83WB+hmMDZk=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDMk8u+Q/JdoJu7KuXb828Py/u8+Ytsa/9dr5ZOaWss9fHgak cSfbdpSyMIhxMciKKbLECJsviTs163UnG988mDmsTCBDGLg4BWAiN5IYGWZIaBw4P4XB9paW4IIpnY tFc1ZEH7zvnXj2o7/62vrJE64zMtxr+Hw1s/dsQeq64P6L651XiFyVOxxRv3v31YWBnYeVj7IAAA== X-Developer-Key: i=maxime@cerno.tech; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D Subject: [Intel-gfx] [PATCH v2 09/41] drm/connector: Add TV standard property 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: Dom Cobley , Dave Stevenson , nouveau@lists.freedesktop.org, intel-gfx@lists.freedesktop.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-sunxi@lists.linux.dev, Geert Uytterhoeven , Maxime Ripard , Mateusz Kwiatkowski , Phil Elwell , linux-arm-kernel@lists.infradead.org Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" The TV mode property has been around for a while now to select and get the current TV mode output on an analog TV connector. Despite that property name being generic, its content isn't and has been driver-specific which makes it hard to build any generic behaviour on top of it, both in kernel and user-space. Let's create a new bitmask tv norm property, that can contain any of the analog TV standards currently supported by kernel drivers. Each driver can then pass in a bitmask of the modes it supports. We'll then be able to phase out the older tv mode property. Signed-off-by: Maxime Ripard diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c index 7f2b9a07fbdf..d867e7f9f2cd 100644 --- a/drivers/gpu/drm/drm_atomic_uapi.c +++ b/drivers/gpu/drm/drm_atomic_uapi.c @@ -700,6 +700,8 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector, state->tv.margins.bottom = val; } else if (property == config->legacy_tv_mode_property) { state->tv.legacy_mode = val; + } else if (property == config->tv_mode_property) { + state->tv.mode = val; } else if (property == config->tv_brightness_property) { state->tv.brightness = val; } else if (property == config->tv_contrast_property) { @@ -810,6 +812,8 @@ drm_atomic_connector_get_property(struct drm_connector *connector, *val = state->tv.margins.bottom; } else if (property == config->legacy_tv_mode_property) { *val = state->tv.legacy_mode; + } else if (property == config->tv_mode_property) { + *val = state->tv.mode; } else if (property == config->tv_brightness_property) { *val = state->tv.brightness; } else if (property == config->tv_contrast_property) { diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index 4e4fbc9e0049..b1fcacd150e8 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -980,6 +980,29 @@ static const struct drm_prop_enum_list drm_dvi_i_subconnector_enum_list[] = { DRM_ENUM_NAME_FN(drm_get_dvi_i_subconnector_name, drm_dvi_i_subconnector_enum_list) +static const struct drm_prop_enum_list drm_tv_mode_enum_list[] = { + { DRM_MODE_TV_MODE_NTSC_443, "NTSC-443" }, + { DRM_MODE_TV_MODE_NTSC_J, "NTSC-J" }, + { DRM_MODE_TV_MODE_NTSC_M, "NTSC-M" }, + { DRM_MODE_TV_MODE_PAL_60, "PAL-60" }, + { DRM_MODE_TV_MODE_PAL_B, "PAL-B" }, + { DRM_MODE_TV_MODE_PAL_D, "PAL-D" }, + { DRM_MODE_TV_MODE_PAL_G, "PAL-G" }, + { DRM_MODE_TV_MODE_PAL_H, "PAL-H" }, + { DRM_MODE_TV_MODE_PAL_I, "PAL-I" }, + { DRM_MODE_TV_MODE_PAL_M, "PAL-M" }, + { DRM_MODE_TV_MODE_PAL_N, "PAL-N" }, + { DRM_MODE_TV_MODE_PAL_NC, "PAL-Nc" }, + { DRM_MODE_TV_MODE_SECAM_60, "SECAM-60" }, + { DRM_MODE_TV_MODE_SECAM_B, "SECAM-B" }, + { DRM_MODE_TV_MODE_SECAM_D, "SECAM-D" }, + { DRM_MODE_TV_MODE_SECAM_G, "SECAM-G" }, + { DRM_MODE_TV_MODE_SECAM_K, "SECAM-K" }, + { DRM_MODE_TV_MODE_SECAM_K1, "SECAM-K1" }, + { DRM_MODE_TV_MODE_SECAM_L, "SECAM-L" }, +}; +DRM_ENUM_NAME_FN(drm_get_tv_mode_name, drm_tv_mode_enum_list) + static const struct drm_prop_enum_list drm_tv_select_enum_list[] = { { DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */ { DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */ @@ -1645,6 +1668,10 @@ EXPORT_SYMBOL(drm_mode_create_tv_margin_properties); * responsible for allocating a list of format names and passing them to * this routine. * + * NOTE: This functions registers the deprecated "mode" connector + * property to select the analog TV mode (ie, NTSC, PAL, etc.). New + * drivers must use drm_mode_create_tv_properties() instead. + * * Returns: * 0 on success or a negative error code on failure. */ @@ -1686,7 +1713,6 @@ int drm_mode_create_tv_properties_legacy(struct drm_device *dev, if (drm_mode_create_tv_margin_properties(dev)) goto nomem; - if (num_modes) { dev->mode_config.legacy_tv_mode_property = drm_property_create(dev, DRM_MODE_PROP_ENUM, @@ -1735,6 +1761,46 @@ int drm_mode_create_tv_properties_legacy(struct drm_device *dev, } EXPORT_SYMBOL(drm_mode_create_tv_properties_legacy); +/** + * drm_mode_create_tv_properties - create TV specific connector properties + * @dev: DRM device + * @supported_tv_modes: Bitmask of TV modes supported (See DRM_MODE_TV_MODE_*) + + * Called by a driver's TV initialization routine, this function creates + * the TV specific connector properties for a given device. Caller is + * responsible for allocating a list of format names and passing them to + * this routine. + * + * Returns: + * 0 on success or a negative error code on failure. + */ +int drm_mode_create_tv_properties(struct drm_device *dev, + unsigned int supported_tv_modes) +{ + struct drm_prop_enum_list tv_mode_list[DRM_MODE_TV_MODE_MAX]; + struct drm_property *tv_mode; + unsigned int i, len = 0; + + for (i = 0; i < DRM_MODE_TV_MODE_MAX; i++) { + if (!(supported_tv_modes & BIT(i))) + continue; + + tv_mode_list[len].type = i; + tv_mode_list[len].name = drm_get_tv_mode_name(i); + len++; + } + + tv_mode = drm_property_create_enum(dev, 0, "TV mode", + tv_mode_list, len); + if (!tv_mode) + return -ENOMEM; + + dev->mode_config.tv_mode_property = tv_mode; + + return drm_mode_create_tv_properties_legacy(dev, 0, NULL); +} +EXPORT_SYMBOL(drm_mode_create_tv_properties); + /** * drm_mode_create_scaling_mode_property - create scaling mode property * @dev: DRM device diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index d566b4a4709c..7d3881f35e7c 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -143,6 +143,144 @@ enum subpixel_order { }; +/** + * enum drm_connector_tv_mode - Analog TV output mode + * + * This enum is used to indicate the TV output mode used on an analog TV + * connector. + * + * WARNING: The values of this enum is uABI since they're exposed in the + * "TV mode" connector property. + */ +enum drm_connector_tv_mode { + /** + * @DRM_MODE_TV_MODE_NTSC_443: Variant of + * @DRM_MODE_TV_MODE_NTSC_M. Uses a color subcarrier frequency + * of 4.43 MHz. + */ + DRM_MODE_TV_MODE_NTSC_443 = 0, + + /** + * @DRM_MODE_TV_MODE_NTSC_J: Variant of @DRM_MODE_TV_MODE_NTSC_M + * used in Japan. Uses a black level equals to the blanking + * level. + */ + DRM_MODE_TV_MODE_NTSC_J, + + /** + * @DRM_MODE_TV_MODE_NTSC_M: CCIR System M (aka 525-lines) + * together with the NTSC Color Encoding. + */ + DRM_MODE_TV_MODE_NTSC_M, + + /** + * @DRM_MODE_TV_MODE_PAL_60: CCIR System M (aka 525-lines) + * together with the PAL color encoding and color subcarrier + * frequency. + */ + DRM_MODE_TV_MODE_PAL_60, + + /** + * @DRM_MODE_TV_MODE_PAL_B: CCIR System B together with the PAL + * color system. + */ + DRM_MODE_TV_MODE_PAL_B, + + /** + * @DRM_MODE_TV_MODE_PAL_D: CCIR System D together with the PAL + * color system. + */ + DRM_MODE_TV_MODE_PAL_D, + + /** + * @DRM_MODE_TV_MODE_PAL_G: CCIR System G together with the PAL + * color system. Similar to @DRM_MODE_TV_MODE_PAL_B but uses a + * different channel bandwidth and transmission band. + */ + DRM_MODE_TV_MODE_PAL_G, + + /** + * @DRM_MODE_TV_MODE_PAL_H: CCIR System H together with the PAL + * color system. Similar to @DRM_MODE_TV_MODE_PAL_G but uses a + * narrower lower side band. + */ + DRM_MODE_TV_MODE_PAL_H, + + /** + * @DRM_MODE_TV_MODE_PAL_I: CCIR System I together with the PAL + * color system. Similar to @DRM_MODE_TV_MODE_PAL_B, but with a + * different audio encoding. + */ + DRM_MODE_TV_MODE_PAL_I, + + /** + * @DRM_MODE_TV_MODE_PAL_M: CCIR System M (aka 525-lines) + * together with the PAL color encoding + */ + DRM_MODE_TV_MODE_PAL_M, + + /** + * @DRM_MODE_TV_MODE_PAL_N: CCIR System N together with the PAL + * color encoding. It uses 625 lines, but has a color subcarrier + * frequency of 3.58MHz, the SECAM color space, and narrower + * channels compared to most of the other PAL variants. + */ + DRM_MODE_TV_MODE_PAL_N, + + /** + * @DRM_MODE_TV_MODE_PAL_NC: Seems equivalent to + * @DRM_MODE_TV_MODE_PAL_N. + */ + DRM_MODE_TV_MODE_PAL_NC, + + /** + * @DRM_MODE_TV_MODE_SECAM_60: CCIR System M (aka 525-lines) + * together with the SECAM color system. + */ + DRM_MODE_TV_MODE_SECAM_60, + + /** + * @DRM_MODE_TV_MODE_SECAM_B: CCIR System B together with the + * SECAM color system. + */ + DRM_MODE_TV_MODE_SECAM_B, + + /** + * @DRM_MODE_TV_MODE_SECAM_D: CCIR System D together with the + * SECAM color system. + */ + DRM_MODE_TV_MODE_SECAM_D, + + /** + * @DRM_MODE_TV_MODE_SECAM_G: CCIR System G together with the + * SECAM color system. Similar to @DRM_MODE_TV_MODE_SECAM_B but + * uses a different channel bandwidth and transmission band. + */ + DRM_MODE_TV_MODE_SECAM_G, + + /** + * @DRM_MODE_TV_MODE_SECAM_K: CCIR System G together with the + * SECAM color system. Similar to @DRM_MODE_TV_MODE_SECAM_G but + * with different channels. + */ + DRM_MODE_TV_MODE_SECAM_K, + + /** + * @DRM_MODE_TV_MODE_SECAM_K1: CCIR System G together with the + * SECAM color system. Similar to @DRM_MODE_TV_MODE_SECAM_G and + * @DRM_MODE_TV_MODE_SECAM_K but with different channels. + */ + DRM_MODE_TV_MODE_SECAM_K1, + + /** + * @DRM_MODE_TV_MODE_SECAM_L: CCIR System L together with the + * SECAM color system. + */ + DRM_MODE_TV_MODE_SECAM_L, + + DRM_MODE_TV_MODE_MAX, +}; + /** * struct drm_scrambling: sink's scrambling support. */ @@ -696,6 +834,7 @@ struct drm_connector_tv_margins { * @subconnector: detected subconnector * @margins: TV margins * @legacy_mode: Legacy TV mode, driver specific value + * @mode: TV mode * @brightness: brightness in percent * @contrast: contrast in percent * @flicker_reduction: flicker reduction in percent @@ -708,6 +847,7 @@ struct drm_tv_connector_state { enum drm_mode_subconnector subconnector; struct drm_connector_tv_margins margins; unsigned int legacy_mode; + unsigned int mode; unsigned int brightness; unsigned int contrast; unsigned int flicker_reduction; @@ -1789,6 +1929,7 @@ const char *drm_get_subpixel_order_name(enum subpixel_order order); const char *drm_get_dpms_name(int val); const char *drm_get_dvi_i_subconnector_name(int val); const char *drm_get_dvi_i_select_name(int val); +const char *drm_get_tv_mode_name(int val); const char *drm_get_tv_subconnector_name(int val); const char *drm_get_tv_select_name(int val); const char *drm_get_dp_subconnector_name(int val); @@ -1802,6 +1943,8 @@ int drm_mode_create_tv_margin_properties(struct drm_device *dev); int drm_mode_create_tv_properties_legacy(struct drm_device *dev, unsigned int num_modes, const char * const modes[]); +int drm_mode_create_tv_properties(struct drm_device *dev, + unsigned int supported_tv_modes); void drm_connector_attach_tv_margin_properties(struct drm_connector *conn); int drm_mode_create_scaling_mode_property(struct drm_device *dev); int drm_connector_attach_content_type_property(struct drm_connector *dev); diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h index 35a827175c24..10a6f7d1df0d 100644 --- a/include/drm/drm_mode_config.h +++ b/include/drm/drm_mode_config.h @@ -718,9 +718,17 @@ struct drm_mode_config { /** * @legacy_tv_mode_property: Optional TV property to select * the output TV mode. + * + * Superseeded by @tv_mode_property */ struct drm_property *legacy_tv_mode_property; + /** + * @tv_mode_property: Optional TV property to select the TV + * standard output on the connector. + */ + struct drm_property *tv_mode_property; + /** * @tv_left_margin_property: Optional TV property to set the left * margin (expressed in pixels).