linux-sunxi.lists.linux.dev archive mirror
 help / color / mirror / Atom feed
From: Maxime Ripard <maxime@cerno.tech>
To: Jernej Skrabec <jernej.skrabec@gmail.com>,
	Rodrigo Vivi <rodrigo.vivi@intel.com>,
	Ben Skeggs <bskeggs@redhat.com>, David Airlie <airlied@linux.ie>,
	Maxime Ripard <mripard@kernel.org>,
	Joonas Lahtinen <joonas.lahtinen@linux.intel.com>,
	Emma Anholt <emma@anholt.net>, Karol Herbst <kherbst@redhat.com>,
	Samuel Holland <samuel@sholland.org>,
	Jani Nikula <jani.nikula@linux.intel.com>,
	Thomas Zimmermann <tzimmermann@suse.de>,
	Daniel Vetter <daniel@ffwll.ch>, Lyude Paul <lyude@redhat.com>,
	Maarten Lankhorst <maarten.lankhorst@linux.intel.com>,
	Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>,
	Chen-Yu Tsai <wens@csie.org>
Cc: Hans de Goede <hdegoede@redhat.com>,
	nouveau@lists.freedesktop.org,
	Geert Uytterhoeven <geert@linux-m68k.org>,
	Dave Stevenson <dave.stevenson@raspberrypi.com>,
	linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	Phil Elwell <phil@raspberrypi.com>,
	intel-gfx@lists.freedesktop.org,
	Noralf Trønnes <noralf@tronnes.org>,
	Dom Cobley <dom@raspberrypi.com>,
	linux-sunxi@lists.linux.dev, Maxime Ripard <maxime@cerno.tech>,
	Mateusz Kwiatkowski <kfyatek+publicgit@gmail.com>,
	dri-devel@lists.freedesktop.org
Subject: [PATCH v2 31/33] drm/vc4: vec: Convert to the new TV mode property
Date: Thu, 22 Sep 2022 16:25:48 +0200	[thread overview]
Message-ID: <20220728-rpi-analog-tv-properties-v2-31-f733a0ed9f90@cerno.tech> (raw)
In-Reply-To: <20220728-rpi-analog-tv-properties-v2-0-f733a0ed9f90@cerno.tech>

Now that the core can deal fine with analog TV modes, let's convert the vc4
VEC driver to leverage those new features.

We've added some backward compatibility to support the old TV mode property
and translate it into the new TV norm property.

Signed-off-by: Maxime Ripard <maxime@cerno.tech>

diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c
index 6828b79a1001..a9463364015b 100644
--- a/drivers/gpu/drm/vc4/vc4_vec.c
+++ b/drivers/gpu/drm/vc4/vc4_vec.c
@@ -172,6 +172,8 @@ struct vc4_vec {
 
 	struct clk *clock;
 
+	struct drm_property *legacy_tv_mode_property;
+
 	struct debugfs_regset32 regset;
 };
 
@@ -184,6 +186,12 @@ encoder_to_vc4_vec(struct drm_encoder *encoder)
 	return container_of(encoder, struct vc4_vec, encoder.base);
 }
 
+static inline struct vc4_vec *
+connector_to_vc4_vec(struct drm_connector *connector)
+{
+	return container_of(connector, struct vc4_vec, connector);
+}
+
 enum vc4_vec_tv_mode_id {
 	VC4_VEC_TV_MODE_NTSC,
 	VC4_VEC_TV_MODE_NTSC_J,
@@ -192,7 +200,7 @@ enum vc4_vec_tv_mode_id {
 };
 
 struct vc4_vec_tv_mode {
-	const struct drm_display_mode *mode;
+	unsigned int mode;
 	u32 config0;
 	u32 config1;
 	u32 custom_freq;
@@ -225,43 +233,51 @@ static const struct debugfs_reg32 vec_regs[] = {
 	VC4_REG32(VEC_DAC_MISC),
 };
 
-static const struct drm_display_mode ntsc_mode = {
-	DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 13500,
-		 720, 720 + 14, 720 + 14 + 64, 720 + 14 + 64 + 60, 0,
-		 480, 480 + 7, 480 + 7 + 6, 525, 0,
-		 DRM_MODE_FLAG_INTERLACE)
-};
-
-static const struct drm_display_mode pal_mode = {
-	DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 13500,
-		 720, 720 + 20, 720 + 20 + 64, 720 + 20 + 64 + 60, 0,
-		 576, 576 + 4, 576 + 4 + 6, 625, 0,
-		 DRM_MODE_FLAG_INTERLACE)
-};
-
 static const struct vc4_vec_tv_mode vc4_vec_tv_modes[] = {
-	[VC4_VEC_TV_MODE_NTSC] = {
-		.mode = &ntsc_mode,
+	{
+		.mode = DRM_MODE_TV_MODE_NTSC,
 		.config0 = VEC_CONFIG0_NTSC_STD | VEC_CONFIG0_PDEN,
 		.config1 = VEC_CONFIG1_C_CVBS_CVBS,
 	},
-	[VC4_VEC_TV_MODE_NTSC_J] = {
-		.mode = &ntsc_mode,
+	{
+		.mode = DRM_MODE_TV_MODE_NTSC_J,
 		.config0 = VEC_CONFIG0_NTSC_STD,
 		.config1 = VEC_CONFIG1_C_CVBS_CVBS,
 	},
-	[VC4_VEC_TV_MODE_PAL] = {
-		.mode = &pal_mode,
+	{
+		.mode = DRM_MODE_TV_MODE_PAL,
 		.config0 = VEC_CONFIG0_PAL_BDGHI_STD,
 		.config1 = VEC_CONFIG1_C_CVBS_CVBS,
 	},
-	[VC4_VEC_TV_MODE_PAL_M] = {
-		.mode = &ntsc_mode,
+	{
+		.mode = DRM_MODE_TV_MODE_PAL_M,
 		.config0 = VEC_CONFIG0_PAL_M_STD,
 		.config1 = VEC_CONFIG1_C_CVBS_CVBS,
 	},
 };
 
+static inline const struct vc4_vec_tv_mode *
+vc4_vec_tv_mode_lookup(unsigned int mode)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(vc4_vec_tv_modes); i++) {
+		const struct vc4_vec_tv_mode *tv_mode = &vc4_vec_tv_modes[i];
+
+		if (tv_mode->mode == mode)
+			return tv_mode;
+	}
+
+	return NULL;
+}
+
+static const struct drm_prop_enum_list tv_mode_names[] = {
+	{ VC4_VEC_TV_MODE_NTSC, "NTSC", },
+	{ VC4_VEC_TV_MODE_NTSC_J, "NTSC-J", },
+	{ VC4_VEC_TV_MODE_PAL, "PAL", },
+	{ VC4_VEC_TV_MODE_PAL_M, "PAL-M", },
+};
+
 static enum drm_connector_status
 vc4_vec_connector_detect(struct drm_connector *connector, bool force)
 {
@@ -276,19 +292,99 @@ static void vc4_vec_connector_reset(struct drm_connector *connector)
 
 static int vc4_vec_connector_get_modes(struct drm_connector *connector)
 {
-	struct drm_connector_state *state = connector->state;
 	struct drm_display_mode *mode;
+	int count = 0;
 
-	mode = drm_mode_duplicate(connector->dev,
-				  vc4_vec_tv_modes[state->tv.legacy_mode].mode);
+	mode = drm_mode_analog_ntsc_480i(connector->dev);
 	if (!mode) {
 		DRM_ERROR("Failed to create a new display mode\n");
 		return -ENOMEM;
 	}
 
+	mode->type |= DRM_MODE_TYPE_PREFERRED;
 	drm_mode_probed_add(connector, mode);
+	count += 1;
 
-	return 1;
+	mode = drm_mode_analog_pal_576i(connector->dev);
+	if (!mode) {
+		DRM_ERROR("Failed to create a new display mode\n");
+		return -ENOMEM;
+	}
+
+	drm_mode_probed_add(connector, mode);
+	count += 1;
+
+	return count;
+}
+
+static int
+vc4_vec_connector_set_property(struct drm_connector *connector,
+			       struct drm_connector_state *state,
+			       struct drm_property *property,
+			       uint64_t val)
+{
+	struct vc4_vec *vec = connector_to_vc4_vec(connector);
+
+	if (property != vec->legacy_tv_mode_property)
+		return -EINVAL;
+
+	switch (val) {
+	case VC4_VEC_TV_MODE_NTSC:
+		state->tv.mode = DRM_MODE_TV_MODE_NTSC;
+		break;
+
+	case VC4_VEC_TV_MODE_NTSC_J:
+		state->tv.mode = DRM_MODE_TV_MODE_NTSC_J;
+		break;
+
+	case VC4_VEC_TV_MODE_PAL:
+		state->tv.mode = DRM_MODE_TV_MODE_PAL;
+		break;
+
+	case VC4_VEC_TV_MODE_PAL_M:
+		state->tv.mode = DRM_MODE_TV_MODE_PAL_M;
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int
+vc4_vec_connector_get_property(struct drm_connector *connector,
+			       const struct drm_connector_state *state,
+			       struct drm_property *property,
+			       uint64_t *val)
+{
+	struct vc4_vec *vec = connector_to_vc4_vec(connector);
+
+	if (property != vec->legacy_tv_mode_property)
+		return -EINVAL;
+
+	switch (state->tv.mode) {
+	case DRM_MODE_TV_MODE_NTSC:
+		*val = VC4_VEC_TV_MODE_NTSC;
+		break;
+
+	case DRM_MODE_TV_MODE_NTSC_J:
+		*val = VC4_VEC_TV_MODE_NTSC_J;
+		break;
+
+	case DRM_MODE_TV_MODE_PAL:
+		*val = VC4_VEC_TV_MODE_PAL;
+		break;
+
+	case DRM_MODE_TV_MODE_PAL_M:
+		*val = VC4_VEC_TV_MODE_PAL_M;
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
 }
 
 static const struct drm_connector_funcs vc4_vec_connector_funcs = {
@@ -297,15 +393,19 @@ static const struct drm_connector_funcs vc4_vec_connector_funcs = {
 	.reset = vc4_vec_connector_reset,
 	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
 	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+	.atomic_get_property = vc4_vec_connector_get_property,
+	.atomic_set_property = vc4_vec_connector_set_property,
 };
 
 static const struct drm_connector_helper_funcs vc4_vec_connector_helper_funcs = {
+	.atomic_check = drm_atomic_helper_connector_tv_check,
 	.get_modes = vc4_vec_connector_get_modes,
 };
 
 static int vc4_vec_connector_init(struct drm_device *dev, struct vc4_vec *vec)
 {
 	struct drm_connector *connector = &vec->connector;
+	struct drm_property *prop;
 	int ret;
 
 	connector->interlace_allowed = true;
@@ -318,8 +418,16 @@ static int vc4_vec_connector_init(struct drm_device *dev, struct vc4_vec *vec)
 	drm_connector_helper_add(connector, &vc4_vec_connector_helper_funcs);
 
 	drm_object_attach_property(&connector->base,
-				   dev->mode_config.legacy_tv_mode_property,
-				   VC4_VEC_TV_MODE_NTSC);
+				   dev->mode_config.tv_mode_property,
+				   DRM_MODE_TV_MODE_NTSC);
+
+	prop = drm_property_create_enum(dev, 0, "mode",
+					tv_mode_names, ARRAY_SIZE(tv_mode_names));
+	if (!prop)
+		return -ENOMEM;
+	vec->legacy_tv_mode_property = prop;
+
+	drm_object_attach_property(&connector->base, prop, VC4_VEC_TV_MODE_NTSC);
 
 	drm_connector_attach_encoder(connector, &vec->encoder.base);
 
@@ -366,13 +474,16 @@ static void vc4_vec_encoder_enable(struct drm_encoder *encoder,
 	struct drm_connector *connector = &vec->connector;
 	struct drm_connector_state *conn_state =
 		drm_atomic_get_new_connector_state(state, connector);
-	const struct vc4_vec_tv_mode *tv_mode =
-		&vc4_vec_tv_modes[conn_state->tv.mode];
+	const struct vc4_vec_tv_mode *tv_mode;
 	int idx, ret;
 
 	if (!drm_dev_enter(drm, &idx))
 		return;
 
+	tv_mode = vc4_vec_tv_mode_lookup(conn_state->tv.mode);
+	if (!tv_mode)
+		goto err_dev_exit;
+
 	ret = pm_runtime_get_sync(&vec->pdev->dev);
 	if (ret < 0) {
 		DRM_ERROR("Failed to retain power domain: %d\n", ret);
@@ -454,13 +565,6 @@ static int vc4_vec_encoder_atomic_check(struct drm_encoder *encoder,
 					struct drm_connector_state *conn_state)
 {
 	const struct drm_display_mode *mode = &crtc_state->adjusted_mode;
-	const struct vc4_vec_tv_mode *vec_mode;
-
-	vec_mode = &vc4_vec_tv_modes[conn_state->tv.legacy_mode];
-
-	if (conn_state->crtc &&
-	    !drm_mode_equal(vec_mode->mode, &crtc_state->adjusted_mode))
-		return -EINVAL;
 
 	if (mode->crtc_hdisplay % 4)
 		return -EINVAL;
@@ -554,13 +658,6 @@ static const struct of_device_id vc4_vec_dt_match[] = {
 	{ /* sentinel */ },
 };
 
-static const char * const tv_mode_names[] = {
-	[VC4_VEC_TV_MODE_NTSC] = "NTSC",
-	[VC4_VEC_TV_MODE_NTSC_J] = "NTSC-J",
-	[VC4_VEC_TV_MODE_PAL] = "PAL",
-	[VC4_VEC_TV_MODE_PAL_M] = "PAL-M",
-};
-
 static int vc4_vec_bind(struct device *dev, struct device *master, void *data)
 {
 	struct platform_device *pdev = to_platform_device(dev);
@@ -568,9 +665,11 @@ static int vc4_vec_bind(struct device *dev, struct device *master, void *data)
 	struct vc4_vec *vec;
 	int ret;
 
-	ret = drm_mode_create_tv_properties_legacy(drm,
-						   ARRAY_SIZE(tv_mode_names),
-						   tv_mode_names);
+	ret = drm_mode_create_tv_properties(drm,
+					    BIT(DRM_MODE_TV_MODE_NTSC) |
+					    BIT(DRM_MODE_TV_MODE_NTSC_J) |
+					    BIT(DRM_MODE_TV_MODE_PAL) |
+					    BIT(DRM_MODE_TV_MODE_PAL_M));
 	if (ret)
 		return ret;
 

-- 
b4 0.10.0

  parent reply	other threads:[~2022-09-22 14:29 UTC|newest]

Thread overview: 75+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-09-22 14:25 [PATCH v2 00/33] drm: Analog TV Improvements Maxime Ripard
2022-09-22 14:25 ` [PATCH v2 01/33] drm/tests: Order Kunit tests in Makefile Maxime Ripard
2022-09-23  8:06   ` Thomas Zimmermann
2022-09-24 17:33   ` Noralf Trønnes
2022-09-22 14:25 ` [PATCH v2 02/33] drm/tests: Add Kunit Helpers Maxime Ripard
2022-09-24 17:56   ` Noralf Trønnes
2022-09-24 18:06     ` Noralf Trønnes
2022-09-26  9:36       ` Maxime Ripard
2022-09-26 12:15         ` Noralf Trønnes
2022-09-22 14:25 ` [PATCH v2 03/33] drm/atomic-helper: Rename drm_atomic_helper_connector_tv_reset to avoid ambiguity Maxime Ripard
2022-09-23  8:09   ` Thomas Zimmermann
2022-09-22 14:25 ` [PATCH v2 04/33] drm/connector: Rename subconnector state variable Maxime Ripard
2022-09-23  8:14   ` Thomas Zimmermann
2022-09-22 14:25 ` [PATCH v2 05/33] drm/atomic: Add TV subconnector property to get/set_property Maxime Ripard
2022-09-22 14:25 ` [PATCH v2 06/33] drm/connector: Rename legacy TV property Maxime Ripard
2022-09-22 20:44   ` Lyude Paul
2022-09-23  8:19   ` Thomas Zimmermann
2022-09-26  9:50     ` Maxime Ripard
2022-09-26 12:34       ` Thomas Zimmermann
2022-09-24 15:38   ` Noralf Trønnes
2022-09-22 14:25 ` [PATCH v2 07/33] drm/connector: Only register TV mode property if present Maxime Ripard
2022-09-22 14:25 ` [PATCH v2 08/33] drm/connector: Rename drm_mode_create_tv_properties Maxime Ripard
2022-09-22 20:45   ` Lyude Paul
2022-09-24 15:43   ` Noralf Trønnes
2022-09-22 14:25 ` [PATCH v2 09/33] drm/connector: Add TV standard property Maxime Ripard
2022-09-24 15:52   ` Noralf Trønnes
2022-09-26 10:01     ` Maxime Ripard
2022-09-26 12:59       ` Noralf Trønnes
2022-09-22 14:25 ` [PATCH v2 10/33] drm/modes: Add a function to generate analog display modes Maxime Ripard
2022-09-23  9:05   ` Thomas Zimmermann
2022-09-23  9:18     ` Jani Nikula
2022-09-23 10:16       ` Thomas Zimmermann
2022-09-26 10:18         ` Maxime Ripard
2022-09-26 10:55           ` Thomas Zimmermann
2022-09-26 10:17     ` Maxime Ripard
2022-09-26 10:34       ` Geert Uytterhoeven
2022-09-26 11:17         ` Thomas Zimmermann
2022-09-26 12:42           ` Maxime Ripard
2022-09-26 13:02             ` Thomas Zimmermann
2022-09-22 14:25 ` [PATCH v2 11/33] drm/modes: Only consider bpp and refresh before options Maxime Ripard
2022-09-22 14:25 ` [PATCH v2 12/33] drm/modes: parse_cmdline: Add support for named modes containing dashes Maxime Ripard
2022-09-22 14:25 ` [PATCH v2 13/33] drm/client: Add some tests for drm_connector_pick_cmdline_mode() Maxime Ripard
2022-09-23  9:15   ` Thomas Zimmermann
2022-09-23  9:26     ` Javier Martinez Canillas
2022-09-23 10:30       ` Thomas Zimmermann
2022-09-23 11:01         ` Javier Martinez Canillas
2022-09-23 11:14         ` Maxime Ripard
2022-09-23 11:59   ` Jani Nikula
2022-09-22 14:25 ` [PATCH v2 14/33] drm/modes: Move named modes parsing to a separate function Maxime Ripard
2022-09-22 14:25 ` [PATCH v2 15/33] drm/modes: Bail out of named mode parsing if empty Maxime Ripard
2022-09-22 14:25 ` [PATCH v2 16/33] drm/modes: Bail out of named mode parsing early if it's a number Maxime Ripard
2022-09-22 14:25 ` [PATCH v2 17/33] drm/modes: Bail out of named mode parsing early if it's an option Maxime Ripard
2022-09-22 14:25 ` [PATCH v2 18/33] drm/modes: Bail out of named mode parsing early if it's a status Maxime Ripard
2022-09-22 14:25 ` [PATCH v2 19/33] drm/modes: Switch to named mode descriptors Maxime Ripard
2022-09-22 14:25 ` [PATCH v2 20/33] drm/modes: Fill drm_cmdline mode from named modes Maxime Ripard
2022-09-22 14:25 ` [PATCH v2 21/33] drm/connector: Add pixel clock to cmdline mode Maxime Ripard
2022-09-22 14:25 ` [PATCH v2 22/33] drm/connector: Add a function to lookup a TV mode by its name Maxime Ripard
2022-09-22 14:25 ` [PATCH v2 23/33] drm/modes: Introduce the tv_mode property as a command-line option Maxime Ripard
2022-09-22 14:25 ` [PATCH v2 24/33] drm/modes: Properly generate a drm_display_mode from a named mode Maxime Ripard
2022-09-22 14:25 ` [PATCH v2 25/33] drm/modes: Introduce more named modes Maxime Ripard
2022-09-22 14:25 ` [PATCH v2 26/33] drm/atomic-helper: Add a TV properties reset helper Maxime Ripard
2022-09-22 14:25 ` [PATCH v2 27/33] drm/atomic-helper: Add an analog TV atomic_check implementation Maxime Ripard
2022-09-24 15:58   ` Noralf Trønnes
2022-09-22 14:25 ` [PATCH v2 28/33] drm/vc4: vec: Fix definition of PAL-M mode Maxime Ripard
2022-09-24 15:59   ` Noralf Trønnes
2022-09-22 14:25 ` [PATCH v2 29/33] drm/vc4: vec: Use TV Reset implementation Maxime Ripard
2022-09-22 14:25 ` [PATCH v2 30/33] drm/vc4: vec: Check for VEC output constraints Maxime Ripard
2022-09-24 16:00   ` Noralf Trønnes
2022-09-22 14:25 ` Maxime Ripard [this message]
2022-09-24 17:09   ` [PATCH v2 31/33] drm/vc4: vec: Convert to the new TV mode property Noralf Trønnes
2022-09-22 14:25 ` [PATCH v2 32/33] drm/vc4: vec: Add support for more analog TV standards Maxime Ripard
2022-09-24 17:12   ` Noralf Trønnes
2022-09-22 14:25 ` [PATCH v2 33/33] drm/sun4i: tv: Convert to the new TV mode property Maxime Ripard
2022-09-22 14:31 ` [PATCH v2 00/33] drm: Analog TV Improvements Maxime Ripard
2022-09-25 15:58 ` Noralf Trønnes

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220728-rpi-analog-tv-properties-v2-31-f733a0ed9f90@cerno.tech \
    --to=maxime@cerno.tech \
    --cc=airlied@linux.ie \
    --cc=bskeggs@redhat.com \
    --cc=daniel@ffwll.ch \
    --cc=dave.stevenson@raspberrypi.com \
    --cc=dom@raspberrypi.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=emma@anholt.net \
    --cc=geert@linux-m68k.org \
    --cc=hdegoede@redhat.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=jani.nikula@linux.intel.com \
    --cc=jernej.skrabec@gmail.com \
    --cc=joonas.lahtinen@linux.intel.com \
    --cc=kfyatek+publicgit@gmail.com \
    --cc=kherbst@redhat.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-sunxi@lists.linux.dev \
    --cc=lyude@redhat.com \
    --cc=maarten.lankhorst@linux.intel.com \
    --cc=mripard@kernel.org \
    --cc=noralf@tronnes.org \
    --cc=nouveau@lists.freedesktop.org \
    --cc=phil@raspberrypi.com \
    --cc=rodrigo.vivi@intel.com \
    --cc=samuel@sholland.org \
    --cc=tvrtko.ursulin@linux.intel.com \
    --cc=tzimmermann@suse.de \
    --cc=wens@csie.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).