mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* Re: [PATCH v6 14/23] drm/modes: Properly generate a drm_display_mode from a named mode
       [not found] ` <20220728-rpi-analog-tv-properties-v6-14-e7792734108f@cerno.tech>
@ 2022-10-26 21:25   ` Mateusz Kwiatkowski
  2022-11-05 17:50   ` Noralf Trønnes
  1 sibling, 0 replies; 20+ messages in thread
From: Mateusz Kwiatkowski @ 2022-10-26 21:25 UTC (permalink / raw)
  To: maxime, 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: linux-sunxi, intel-gfx, Phil Elwell, linux-arm-kernel, nouveau,
	Hans de Goede, Dom Cobley, dri-devel, Dave Stevenson,
	linux-kernel, Noralf Trønnes, Geert Uytterhoeven

Hi Maxime,

> +static struct drm_display_mode *drm_named_mode(struct drm_device *dev,
> +					       struct drm_cmdline_mode *cmd)
> +{
> +	struct drm_display_mode *mode;
> +	unsigned int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(drm_named_modes); i++) {
> +		const struct drm_named_mode *named_mode = &drm_named_modes[i];
> +
> +		if (strcmp(cmd->name, named_mode->name))
> +			continue;
> +
> +		if (!named_mode->tv_mode)
> +			continue;
> +
> +		mode = drm_analog_tv_mode(dev,
> +					  named_mode->tv_mode,
> +					  named_mode->pixel_clock_khz * 1000,
> +					  named_mode->xres,
> +					  named_mode->yres,
> +					  named_mode->flags & DRM_MODE_FLAG_INTERLACE);
> +		if (!mode)
> +			return NULL;
> +
> +		return mode;
> +	}
> +
> +	return NULL;
> +}
> +

You didn't add tv_mode_specified to struct drm_named_mode, and left the
if (!named_mode->tv_mode) condition here. This will break on NTSC.

Best regards,
Mateusz Kwiatkowski


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v6 16/23] drm/probe-helper: Provide a TV get_modes helper
       [not found] ` <20220728-rpi-analog-tv-properties-v6-16-e7792734108f@cerno.tech>
@ 2022-10-26 22:02   ` Mateusz Kwiatkowski
  2022-10-27  9:37     ` Maxime Ripard
  2022-11-06 16:59     ` Noralf Trønnes
  2022-11-06 16:33   ` Noralf Trønnes
  1 sibling, 2 replies; 20+ messages in thread
From: Mateusz Kwiatkowski @ 2022-10-26 22:02 UTC (permalink / raw)
  To: maxime, 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: linux-sunxi, intel-gfx, Phil Elwell, linux-arm-kernel, nouveau,
	Hans de Goede, Dom Cobley, dri-devel, Dave Stevenson,
	linux-kernel, Noralf Trønnes, Geert Uytterhoeven

Hi Maxime,

First of all, nice idea with the helper function that can be reused by different
drivers. This is neat!

But looking at this function, it feels a bit overcomplicated. You're creating
the two modes, then checking which one is the default, then set the preferred
one and possibly reorder them. Maybe it can be simplified somehow?

Although when I tried to refactor it myself, I ended up with something that's
not better at all. Maybe it needs to be complicated, after all :(

Anyway, the current version seems to have a couple of bugs:

> +	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 the 480i mode has been created properly, but there's an error creating the
576i one (we enter the if (!mode) clause), the 480i mode will leak.

> +	if (count == 1) {

You're handling the count == 1 case specially, but if count == 0, the rest of
the code will assume that two modes exist and probably segfault in the process.

> +	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;

In case of an error (ret != 0), the modes created so far in the tv_modes array
will leak.

Also, I wonder if maybe the if (cmdline->tv_mode_specified) clause should go
first? If we're going to use the default from cmdline, there's no point in even
querying the property default value.

Best regards,
Mateusz Kwiatkowski


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v6 22/23] drm/vc4: vec: Add support for more analog TV standards
       [not found] ` <20220728-rpi-analog-tv-properties-v6-22-e7792734108f@cerno.tech>
@ 2022-10-26 22:32   ` Mateusz Kwiatkowski
  2022-10-27 11:58     ` Maxime Ripard
  0 siblings, 1 reply; 20+ messages in thread
From: Mateusz Kwiatkowski @ 2022-10-26 22:32 UTC (permalink / raw)
  To: maxime, 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: linux-sunxi, intel-gfx, Phil Elwell, linux-arm-kernel, nouveau,
	Hans de Goede, Dom Cobley, dri-devel, Dave Stevenson,
	linux-kernel, Noralf Trønnes, Geert Uytterhoeven

Hi Maxime,

I've seen that you've incorporated my PAL60 patch. Thanks!

I still yet need to test your v6 changes, but looking at this code with just my
mental static analysis, it seems to me that the vc4_vec_encoder_atomic_check()
should have the tv_mode validation. I should've added it to the PAL60 patch,
but it somehow slipped my mind then.

Anyway, I mentioned it previously here:
https://lore.kernel.org/dri-devel/0f2beec2-ae8e-5579-f0b6-a73d9dae1af4@gmail.com/

It would look something like this, inside vc4_vec_encoder_atomic_check():

+	const struct vc4_vec_tv_mode *tv_mode =
+		vc4_vec_tv_mode_lookup(conn_state->tv.mode);
+
+	if (!tv_mode)
+		return -EINVAL;

Without this, it's possible to set e.g. 480i mode and SECAM, which will fail -
but with the current version it will only fail in vc4_vec_encoder_enable(),
which cannot return an error, and in my experience that causes a rather lengthy
lockup.

But, like I said, I still need to actually test that with this version.

Anyway, I was also thinking about adding support for the more "exotic"
non-standard modes. NTSC-50 is, unfortunately, impossible with VEC, but
PAL-N-60 and PAL-M-50 should work. The necessary vc4_vec_tv_modes entries would
look something like:

@@ -325,12 +325,28 @@ static const struct vc4_vec_tv_mode vc4_vec_tv_modes[] = {
 		.config0 = VEC_CONFIG0_PAL_M_STD,
 		.config1 = VEC_CONFIG1_C_CVBS_CVBS,
 	},
+	{
+		/* PAL-M-50 */
+		.mode = DRM_MODE_TV_MODE_PAL,
+		.expected_htotal = 864,
+		.config0 = VEC_CONFIG0_PAL_BDGHI_STD,
+		.config1 = VEC_CONFIG1_C_CVBS_CVBS | VEC_CONFIG1_CUSTOM_FREQ,
+		.custom_freq = 0x21e6efe3,
+	},
 	{
 		.mode = DRM_MODE_TV_MODE_PAL_N,
 		.expected_htotal = 864,
 		.config0 = VEC_CONFIG0_PAL_N_STD,
 		.config1 = VEC_CONFIG1_C_CVBS_CVBS,
 	},
+	{
+		/* PAL-N-60 */
+		.mode = DRM_MODE_TV_MODE_PAL_N,
+		.expected_htotal = 858,
+		.config0 = VEC_CONFIG0_PAL_M_STD,
+		.config1 = VEC_CONFIG1_C_CVBS_CVBS | VEC_CONFIG1_CUSTOM_FREQ,
+		.custom_freq = 0x21f69446,
+	},
 	{
 		.mode = DRM_MODE_TV_MODE_SECAM,
 		.expected_htotal = 864,

I'm not sure if we actually want to add that. The two arguments for doing so
I can think of is 1. it should work, so "why not", 2. it means that more modes
will result in _some_ kind of a valid signal, rather than erroring out, which
is always a plus in my book. I can also think of a hypothetical use case, like
someone in South America with an old PAL-N-only set that would nevertheless
still sync at 60 Hz (perhaps with the help of messing with vertical hold knob),
who would like to play retro games at 60 Hz in color.

But on the other hand, I admit that this scenario is likely a stretch and the
number of people who would actually use it is probably close to the proverbial
two ;) So it's your call, I'm just leaving those settings here just in case.

I'll get back in a couple of days when I do some testing of this v6 patchset.

Best regards,
Mateusz Kwiatkowski

W dniu 26.10.2022 o 17:33, maxime@cerno.tech pisze:
> From: Mateusz Kwiatkowski <kfyatek+publicgit@gmail.com>
>
> Add support for the following composite output modes (all of them are
> somewhat more obscure than the previously defined ones):
>
> - NTSC_443 - NTSC-style signal with the chroma subcarrier shifted to
>   4.43361875 MHz (the PAL subcarrier frequency). Never used for
>   broadcasting, but sometimes used as a hack to play NTSC content in PAL
>   regions (e.g. on VCRs).
> - PAL_N - PAL with alternative chroma subcarrier frequency,
>   3.58205625 MHz. Used as a broadcast standard in Argentina, Paraguay
>   and Uruguay to fit 576i50 with colour in 6 MHz channel raster.
> - PAL60 - 480i60 signal with PAL-style color at normal European PAL
>   frequency. Another non-standard, non-broadcast mode, used in similar
>   contexts as NTSC_443. Some displays support one but not the other.
> - SECAM - French frequency-modulated analog color standard; also have
>   been broadcast in Eastern Europe and various parts of Africa and Asia.
>   Uses the same 576i50 timings as PAL.
>
> Also added some comments explaining color subcarrier frequency
> registers.
>
> Acked-by: Noralf Trønnes <noralf@tronnes.org>
> Signed-off-by: Mateusz Kwiatkowski <kfyatek+publicgit@gmail.com>
> Signed-off-by: Maxime Ripard <maxime@cerno.tech>
>
> ---
> Changes in v6:
> - Support PAL60 again
> ---
>  drivers/gpu/drm/vc4/vc4_vec.c | 111 ++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 107 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c
> index 1dda451c8def..d82aef168075 100644
> --- a/drivers/gpu/drm/vc4/vc4_vec.c
> +++ b/drivers/gpu/drm/vc4/vc4_vec.c
> @@ -46,6 +46,7 @@
>  #define VEC_CONFIG0_YDEL(x)		((x) << 26)
>  #define VEC_CONFIG0_CDEL_MASK		GENMASK(25, 24)
>  #define VEC_CONFIG0_CDEL(x)		((x) << 24)
> +#define VEC_CONFIG0_SECAM_STD		BIT(21)
>  #define VEC_CONFIG0_PBPR_FIL		BIT(18)
>  #define VEC_CONFIG0_CHROMA_GAIN_MASK	GENMASK(17, 16)
>  #define VEC_CONFIG0_CHROMA_GAIN_UNITY	(0 << 16)
> @@ -76,6 +77,27 @@
>  #define VEC_SOFT_RESET			0x10c
>  #define VEC_CLMP0_START			0x144
>  #define VEC_CLMP0_END			0x148
> +
> +/*
> + * These set the color subcarrier frequency
> + * if VEC_CONFIG1_CUSTOM_FREQ is enabled.
> + *
> + * VEC_FREQ1_0 contains the most significant 16-bit half-word,
> + * VEC_FREQ3_2 contains the least significant 16-bit half-word.
> + * 0x80000000 seems to be equivalent to the pixel clock
> + * (which itself is the VEC clock divided by 8).
> + *
> + * Reference values (with the default pixel clock of 13.5 MHz):
> + *
> + * NTSC  (3579545.[45] Hz)     - 0x21F07C1F
> + * PAL   (4433618.75 Hz)       - 0x2A098ACB
> + * PAL-M (3575611.[888111] Hz) - 0x21E6EFE3
> + * PAL-N (3582056.25 Hz)       - 0x21F69446
> + *
> + * NOTE: For SECAM, it is used as the Dr center frequency,
> + * regardless of whether VEC_CONFIG1_CUSTOM_FREQ is enabled or not;
> + * that is specified as 4406250 Hz, which corresponds to 0x29C71C72.
> + */
>  #define VEC_FREQ3_2			0x180
>  #define VEC_FREQ1_0			0x184
>  
> @@ -118,6 +140,14 @@
>  
>  #define VEC_INTERRUPT_CONTROL		0x190
>  #define VEC_INTERRUPT_STATUS		0x194
> +
> +/*
> + * Db center frequency for SECAM; the clock for this is the same as for
> + * VEC_FREQ3_2/VEC_FREQ1_0, which is used for Dr center frequency.
> + *
> + * This is specified as 4250000 Hz, which corresponds to 0x284BDA13.
> + * That is also the default value, so no need to set it explicitly.
> + */
>  #define VEC_FCW_SECAM_B			0x198
>  #define VEC_SECAM_GAIN_VAL		0x19c
>  
> @@ -197,10 +227,15 @@ enum vc4_vec_tv_mode_id {
>  	VC4_VEC_TV_MODE_NTSC_J,
>  	VC4_VEC_TV_MODE_PAL,
>  	VC4_VEC_TV_MODE_PAL_M,
> +	VC4_VEC_TV_MODE_NTSC_443,
> +	VC4_VEC_TV_MODE_PAL_60,
> +	VC4_VEC_TV_MODE_PAL_N,
> +	VC4_VEC_TV_MODE_SECAM,
>  };
>  
>  struct vc4_vec_tv_mode {
>  	unsigned int mode;
> +	u16 expected_htotal;
>  	u32 config0;
>  	u32 config1;
>  	u32 custom_freq;
> @@ -236,35 +271,68 @@ static const struct debugfs_reg32 vec_regs[] = {
>  static const struct vc4_vec_tv_mode vc4_vec_tv_modes[] = {
>  	{
>  		.mode = DRM_MODE_TV_MODE_NTSC,
> +		.expected_htotal = 858,
>  		.config0 = VEC_CONFIG0_NTSC_STD | VEC_CONFIG0_PDEN,
>  		.config1 = VEC_CONFIG1_C_CVBS_CVBS,
>  	},
> +	{
> +		.mode = DRM_MODE_TV_MODE_NTSC_443,
> +		.expected_htotal = 858,
> +		.config0 = VEC_CONFIG0_NTSC_STD,
> +		.config1 = VEC_CONFIG1_C_CVBS_CVBS | VEC_CONFIG1_CUSTOM_FREQ,
> +		.custom_freq = 0x2a098acb,
> +	},
>  	{
>  		.mode = DRM_MODE_TV_MODE_NTSC_J,
> +		.expected_htotal = 858,
>  		.config0 = VEC_CONFIG0_NTSC_STD,
>  		.config1 = VEC_CONFIG1_C_CVBS_CVBS,
>  	},
>  	{
>  		.mode = DRM_MODE_TV_MODE_PAL,
> +		.expected_htotal = 864,
>  		.config0 = VEC_CONFIG0_PAL_BDGHI_STD,
>  		.config1 = VEC_CONFIG1_C_CVBS_CVBS,
>  	},
> +	{
> +		/* PAL-60 */
> +		.mode = DRM_MODE_TV_MODE_PAL,
> +		.expected_htotal = 858,
> +		.config0 = VEC_CONFIG0_PAL_M_STD,
> +		.config1 = VEC_CONFIG1_C_CVBS_CVBS | VEC_CONFIG1_CUSTOM_FREQ,
> +		.custom_freq = 0x2a098acb,
> +	},
>  	{
>  		.mode = DRM_MODE_TV_MODE_PAL_M,
> +		.expected_htotal = 858,
>  		.config0 = VEC_CONFIG0_PAL_M_STD,
>  		.config1 = VEC_CONFIG1_C_CVBS_CVBS,
>  	},
> +	{
> +		.mode = DRM_MODE_TV_MODE_PAL_N,
> +		.expected_htotal = 864,
> +		.config0 = VEC_CONFIG0_PAL_N_STD,
> +		.config1 = VEC_CONFIG1_C_CVBS_CVBS,
> +	},
> +	{
> +		.mode = DRM_MODE_TV_MODE_SECAM,
> +		.expected_htotal = 864,
> +		.config0 = VEC_CONFIG0_SECAM_STD,
> +		.config1 = VEC_CONFIG1_C_CVBS_CVBS,
> +		.custom_freq = 0x29c71c72,
> +	},
>  };
>  
>  static inline const struct vc4_vec_tv_mode *
> -vc4_vec_tv_mode_lookup(unsigned int mode)
> +vc4_vec_tv_mode_lookup(unsigned int mode, u16 htotal)
>  {
>  	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)
> +		if (tv_mode->mode == mode &&
> +		    tv_mode->expected_htotal == htotal)
>  			return tv_mode;
>  	}
>  
> @@ -273,9 +341,13 @@ vc4_vec_tv_mode_lookup(unsigned int mode)
>  
>  static const struct drm_prop_enum_list legacy_tv_mode_names[] = {
>  	{ VC4_VEC_TV_MODE_NTSC, "NTSC", },
> +	{ VC4_VEC_TV_MODE_NTSC_443, "NTSC-443", },
>  	{ VC4_VEC_TV_MODE_NTSC_J, "NTSC-J", },
>  	{ VC4_VEC_TV_MODE_PAL, "PAL", },
> +	{ VC4_VEC_TV_MODE_PAL_60, "PAL-60", },
>  	{ VC4_VEC_TV_MODE_PAL_M, "PAL-M", },
> +	{ VC4_VEC_TV_MODE_PAL_N, "PAL-N", },
> +	{ VC4_VEC_TV_MODE_SECAM, "SECAM", },
>  };
>  
>  static enum drm_connector_status
> @@ -306,11 +378,16 @@ vc4_vec_connector_set_property(struct drm_connector *connector,
>  		state->tv.mode = DRM_MODE_TV_MODE_NTSC;
>  		break;
>  
> +	case VC4_VEC_TV_MODE_NTSC_443:
> +		state->tv.mode = DRM_MODE_TV_MODE_NTSC_443;
> +		break;
> +
>  	case VC4_VEC_TV_MODE_NTSC_J:
>  		state->tv.mode = DRM_MODE_TV_MODE_NTSC_J;
>  		break;
>  
>  	case VC4_VEC_TV_MODE_PAL:
> +	case VC4_VEC_TV_MODE_PAL_60:
>  		state->tv.mode = DRM_MODE_TV_MODE_PAL;
>  		break;
>  
> @@ -318,6 +395,14 @@ vc4_vec_connector_set_property(struct drm_connector *connector,
>  		state->tv.mode = DRM_MODE_TV_MODE_PAL_M;
>  		break;
>  
> +	case VC4_VEC_TV_MODE_PAL_N:
> +		state->tv.mode = DRM_MODE_TV_MODE_PAL_N;
> +		break;
> +
> +	case VC4_VEC_TV_MODE_SECAM:
> +		state->tv.mode = DRM_MODE_TV_MODE_SECAM;
> +		break;
> +
>  	default:
>  		return -EINVAL;
>  	}
> @@ -341,6 +426,10 @@ vc4_vec_connector_get_property(struct drm_connector *connector,
>  		*val = VC4_VEC_TV_MODE_NTSC;
>  		break;
>  
> +	case DRM_MODE_TV_MODE_NTSC_443:
> +		*val = VC4_VEC_TV_MODE_NTSC_443;
> +		break;
> +
>  	case DRM_MODE_TV_MODE_NTSC_J:
>  		*val = VC4_VEC_TV_MODE_NTSC_J;
>  		break;
> @@ -353,6 +442,14 @@ vc4_vec_connector_get_property(struct drm_connector *connector,
>  		*val = VC4_VEC_TV_MODE_PAL_M;
>  		break;
>  
> +	case DRM_MODE_TV_MODE_PAL_N:
> +		*val = VC4_VEC_TV_MODE_PAL_N;
> +		break;
> +
> +	case DRM_MODE_TV_MODE_SECAM:
> +		*val = VC4_VEC_TV_MODE_SECAM;
> +		break;
> +
>  	default:
>  		return -EINVAL;
>  	}
> @@ -448,13 +545,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);
> +	struct drm_display_mode *adjusted_mode =
> +		&encoder->crtc->state->adjusted_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);
> +	tv_mode = vc4_vec_tv_mode_lookup(conn_state->tv.mode,
> +					 adjusted_mode->htotal);
>  	if (!tv_mode)
>  		goto err_dev_exit;
>  
> @@ -643,9 +743,12 @@ static int vc4_vec_bind(struct device *dev, struct device *master, void *data)
>  
>  	ret = drm_mode_create_tv_properties(drm,
>  					    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) |
> -					    BIT(DRM_MODE_TV_MODE_PAL_M));
> +					    BIT(DRM_MODE_TV_MODE_PAL_M) |
> +					    BIT(DRM_MODE_TV_MODE_PAL_N) |
> +					    BIT(DRM_MODE_TV_MODE_SECAM));
>  	if (ret)
>  		return ret;
>  
>


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v6 16/23] drm/probe-helper: Provide a TV get_modes helper
  2022-10-26 22:02   ` [PATCH v6 16/23] drm/probe-helper: Provide a TV get_modes helper Mateusz Kwiatkowski
@ 2022-10-27  9:37     ` Maxime Ripard
  2022-11-06 16:59     ` Noralf Trønnes
  1 sibling, 0 replies; 20+ messages in thread
From: Maxime Ripard @ 2022-10-27  9:37 UTC (permalink / raw)
  To: Mateusz Kwiatkowski
  Cc: 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, Joonas Lahtinen, Lyude Paul,
	linux-sunxi, intel-gfx, Phil Elwell, linux-arm-kernel, nouveau,
	Hans de Goede, Dom Cobley, dri-devel, Dave Stevenson,
	linux-kernel, Noralf Trønnes, Geert Uytterhoeven

[-- Attachment #1: Type: text/plain, Size: 2797 bytes --]

Hi Mateusz,

On Thu, Oct 27, 2022 at 12:02:24AM +0200, Mateusz Kwiatkowski wrote:
> First of all, nice idea with the helper function that can be reused by
> different drivers. This is neat!

Yeah, it looked to me that given how complex it is, we don't want to
duplicate it in each and every driver.

> But looking at this function, it feels a bit overcomplicated. You're
> creating the two modes,

If reported as supported by the connector, yes.

> then checking which one is the default, then set the preferred one and
> possibly reorder them. Maybe it can be simplified somehow?

Possibly, but I couldn't find something simpler. We should only expose
the modes that the driver reports as supported, so we can have 0-2
modes. Then the preferred flag needs to be set on the default one like
you suggested.

But also, EDIDs define the preferred mode as either the mode with the
flag set or the first mode listed. So a lot of program just use the
heuristic to just pick the first mode listed.

So it might be that I'm too careful, but it still seems useful to me.

> Although when I tried to refactor it myself, I ended up with something that's
> not better at all. Maybe it needs to be complicated, after all :(

Yeah, that was my conclusion too :/

> Anyway, the current version seems to have a couple of bugs:
> 
> > +	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 the 480i mode has been created properly, but there's an error creating the
> 576i one (we enter the if (!mode) clause), the 480i mode will leak.
> 
> > +	if (count == 1) {
> 
> You're handling the count == 1 case specially, but if count == 0, the rest of
> the code will assume that two modes exist and probably segfault in the process.
> 
> > +	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;
> 
> In case of an error (ret != 0), the modes created so far in the tv_modes array
> will leak.

Thanks for the review, I'll fix these bugs

> Also, I wonder if maybe the if (cmdline->tv_mode_specified) clause should go
> first? If we're going to use the default from cmdline, there's no point in even
> querying the property default value.

Maybe, I don't know. I find the flow of the code more readable that way,
but if you disagree I'll change it.

Maxime

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v6 22/23] drm/vc4: vec: Add support for more analog TV standards
  2022-10-26 22:32   ` [PATCH v6 22/23] drm/vc4: vec: Add support for more analog TV standards Mateusz Kwiatkowski
@ 2022-10-27 11:58     ` Maxime Ripard
  0 siblings, 0 replies; 20+ messages in thread
From: Maxime Ripard @ 2022-10-27 11:58 UTC (permalink / raw)
  To: Mateusz Kwiatkowski
  Cc: 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, Joonas Lahtinen, Lyude Paul,
	linux-sunxi, intel-gfx, Phil Elwell, linux-arm-kernel, nouveau,
	Hans de Goede, Dom Cobley, dri-devel, Dave Stevenson,
	linux-kernel, Noralf Trønnes, Geert Uytterhoeven

[-- Attachment #1: Type: text/plain, Size: 3333 bytes --]

Hi,

On Thu, Oct 27, 2022 at 12:32:50AM +0200, Mateusz Kwiatkowski wrote:
> I've seen that you've incorporated my PAL60 patch. Thanks!
> 
> I still yet need to test your v6 changes, but looking at this code with just my
> mental static analysis, it seems to me that the vc4_vec_encoder_atomic_check()
> should have the tv_mode validation. I should've added it to the PAL60 patch,
> but it somehow slipped my mind then.
> 
> Anyway, I mentioned it previously here:
> https://lore.kernel.org/dri-devel/0f2beec2-ae8e-5579-f0b6-a73d9dae1af4@gmail.com/
> 
> It would look something like this, inside vc4_vec_encoder_atomic_check():
> 
> +	const struct vc4_vec_tv_mode *tv_mode =
> +		vc4_vec_tv_mode_lookup(conn_state->tv.mode);
> +
> +	if (!tv_mode)
> +		return -EINVAL;
> 
> Without this, it's possible to set e.g. 480i mode and SECAM, which will fail -
> but with the current version it will only fail in vc4_vec_encoder_enable(),
> which cannot return an error, and in my experience that causes a rather lengthy
> lockup.

ACK, I'll add it.

> But, like I said, I still need to actually test that with this version.
>
> Anyway, I was also thinking about adding support for the more "exotic"
> non-standard modes. NTSC-50 is, unfortunately, impossible with VEC, but
> PAL-N-60 and PAL-M-50 should work. The necessary vc4_vec_tv_modes entries would
> look something like:
> 
> @@ -325,12 +325,28 @@ static const struct vc4_vec_tv_mode vc4_vec_tv_modes[] = {
>  		.config0 = VEC_CONFIG0_PAL_M_STD,
>  		.config1 = VEC_CONFIG1_C_CVBS_CVBS,
>  	},
> +	{
> +		/* PAL-M-50 */
> +		.mode = DRM_MODE_TV_MODE_PAL,
> +		.expected_htotal = 864,
> +		.config0 = VEC_CONFIG0_PAL_BDGHI_STD,
> +		.config1 = VEC_CONFIG1_C_CVBS_CVBS | VEC_CONFIG1_CUSTOM_FREQ,
> +		.custom_freq = 0x21e6efe3,
> +	},
>  	{
>  		.mode = DRM_MODE_TV_MODE_PAL_N,
>  		.expected_htotal = 864,
>  		.config0 = VEC_CONFIG0_PAL_N_STD,
>  		.config1 = VEC_CONFIG1_C_CVBS_CVBS,
>  	},
> +	{
> +		/* PAL-N-60 */
> +		.mode = DRM_MODE_TV_MODE_PAL_N,
> +		.expected_htotal = 858,
> +		.config0 = VEC_CONFIG0_PAL_M_STD,
> +		.config1 = VEC_CONFIG1_C_CVBS_CVBS | VEC_CONFIG1_CUSTOM_FREQ,
> +		.custom_freq = 0x21f69446,
> +	},
>  	{
>  		.mode = DRM_MODE_TV_MODE_SECAM,
>  		.expected_htotal = 864,
> 
> I'm not sure if we actually want to add that. The two arguments for doing so
> I can think of is 1. it should work, so "why not", 2. it means that more modes
> will result in _some_ kind of a valid signal, rather than erroring out, which
> is always a plus in my book. I can also think of a hypothetical use case, like
> someone in South America with an old PAL-N-only set that would nevertheless
> still sync at 60 Hz (perhaps with the help of messing with vertical hold knob),
> who would like to play retro games at 60 Hz in color.
> 
> But on the other hand, I admit that this scenario is likely a stretch and the
> number of people who would actually use it is probably close to the proverbial
> two ;) So it's your call, I'm just leaving those settings here just in case.

This series is already pretty massive and is difficult to merge, so I'd
rather avoid to add new stuff in at every version. The changes look easy
enough to be a follow-up patch, so I'd prefer to do it that way.

Maxime

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v6 08/23] drm/modes: Move named modes parsing to a separate function
       [not found] ` <20220728-rpi-analog-tv-properties-v6-8-e7792734108f@cerno.tech>
@ 2022-11-05 14:02   ` Noralf Trønnes
  0 siblings, 0 replies; 20+ messages in thread
From: Noralf Trønnes @ 2022-11-05 14:02 UTC (permalink / raw)
  To: maxime, 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: linux-sunxi, intel-gfx, Phil Elwell, linux-arm-kernel, nouveau,
	Hans de Goede, Dom Cobley, Mateusz Kwiatkowski, dri-devel,
	Dave Stevenson, linux-kernel, Geert Uytterhoeven,
	Noralf Trønnes



Den 26.10.2022 17.33, skrev maxime@cerno.tech:
> The current construction of the named mode parsing doesn't allow to extend
> it easily. Let's move it to a separate function so we can add more
> parameters and modes.
> 
> In order for the tests to still pass, some extra checks are needed, so
> it's not a 1:1 move.
> 
> Signed-off-by: Maxime Ripard <maxime@cerno.tech>
> 
> ---

Reviewed-by: Noralf Trønnes <noralf@tronnes.org>

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v6 09/23] drm/modes: Switch to named mode descriptors
       [not found] ` <20220728-rpi-analog-tv-properties-v6-9-e7792734108f@cerno.tech>
@ 2022-11-05 14:06   ` Noralf Trønnes
  0 siblings, 0 replies; 20+ messages in thread
From: Noralf Trønnes @ 2022-11-05 14:06 UTC (permalink / raw)
  To: maxime, 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: linux-sunxi, intel-gfx, Phil Elwell, linux-arm-kernel, nouveau,
	Hans de Goede, Dom Cobley, Mateusz Kwiatkowski, dri-devel,
	Dave Stevenson, linux-kernel, Geert Uytterhoeven,
	Noralf Trønnes



Den 26.10.2022 17.33, skrev maxime@cerno.tech:
> The current named mode parsing relies only the mode name, and doesn't allow

only the -> only on the

> to specify any other parameter.
> 
> Let's convert that string list to an array of a custom structure that will
> hold the name and some additional parameters in the future.
> 
> Signed-off-by: Maxime Ripard <maxime@cerno.tech>
> ---

Reviewed-by: Noralf Trønnes <noralf@tronnes.org>

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v6 14/23] drm/modes: Properly generate a drm_display_mode from a named mode
       [not found] ` <20220728-rpi-analog-tv-properties-v6-14-e7792734108f@cerno.tech>
  2022-10-26 21:25   ` [PATCH v6 14/23] drm/modes: Properly generate a drm_display_mode from a named mode Mateusz Kwiatkowski
@ 2022-11-05 17:50   ` Noralf Trønnes
  2022-11-07 13:34     ` Maxime Ripard
  1 sibling, 1 reply; 20+ messages in thread
From: Noralf Trønnes @ 2022-11-05 17:50 UTC (permalink / raw)
  To: maxime, 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: linux-sunxi, intel-gfx, Phil Elwell, linux-arm-kernel, nouveau,
	Hans de Goede, Dom Cobley, Mateusz Kwiatkowski, dri-devel,
	Dave Stevenson, linux-kernel, Geert Uytterhoeven,
	Noralf Trønnes



Den 26.10.2022 17.33, skrev maxime@cerno.tech:
> The framework will get the drm_display_mode from the drm_cmdline_mode it
> got by parsing the video command line argument by calling
> drm_connector_pick_cmdline_mode().
> 
> The heavy lifting will then be done by the drm_mode_create_from_cmdline_mode()
> function.
> 
> In the case of the named modes though, there's no real code to make that
> translation and we rely on the drivers to guess which actual display mode
> we meant.
> 
> Let's modify drm_mode_create_from_cmdline_mode() to properly generate the
> drm_display_mode we mean when passing a named mode.
> 
> Signed-off-by: Maxime Ripard <maxime@cerno.tech>
> 
> ---
> Changes in v6:
> - Fix get_modes to return 0 instead of an error code
> - Rename the tests to follow the DRM test naming convention
> 
> Changes in v5:
> - Switched to KUNIT_ASSERT_NOT_NULL
> ---
>  drivers/gpu/drm/drm_modes.c                     | 34 ++++++++++-
>  drivers/gpu/drm/tests/drm_client_modeset_test.c | 77 ++++++++++++++++++++++++-
>  2 files changed, 109 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
> index dc037f7ceb37..85aa9898c229 100644
> --- a/drivers/gpu/drm/drm_modes.c
> +++ b/drivers/gpu/drm/drm_modes.c
> @@ -2497,6 +2497,36 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option,
>  }
>  EXPORT_SYMBOL(drm_mode_parse_command_line_for_connector);
>  
> +static struct drm_display_mode *drm_named_mode(struct drm_device *dev,
> +					       struct drm_cmdline_mode *cmd)
> +{
> +	struct drm_display_mode *mode;
> +	unsigned int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(drm_named_modes); i++) {
> +		const struct drm_named_mode *named_mode = &drm_named_modes[i];
> +
> +		if (strcmp(cmd->name, named_mode->name))
> +			continue;
> +
> +		if (!named_mode->tv_mode)
> +			continue;
> +
> +		mode = drm_analog_tv_mode(dev,
> +					  named_mode->tv_mode,
> +					  named_mode->pixel_clock_khz * 1000,
> +					  named_mode->xres,
> +					  named_mode->yres,
> +					  named_mode->flags & DRM_MODE_FLAG_INTERLACE);
> +		if (!mode)
> +			return NULL;
> +
> +		return mode;
> +	}
> +
> +	return NULL;
> +}
> +
>  /**
>   * drm_mode_create_from_cmdline_mode - convert a command line modeline into a DRM display mode
>   * @dev: DRM device to create the new mode for
> @@ -2514,7 +2544,9 @@ drm_mode_create_from_cmdline_mode(struct drm_device *dev,
>  	if (cmd->xres == 0 || cmd->yres == 0)
>  		return NULL;
>  
> -	if (cmd->cvt)
> +	if (strlen(cmd->name))
> +		mode = drm_named_mode(dev, cmd);

I'm trying to track how this generated mode fits into to it all and
AFAICS if the connector already supports a mode with the same xres/yres
as the named mode, the named mode will never be created because of the
check at the beginning of drm_helper_probe_add_cmdline_mode(). It will
just mark the existing mode with USERDEF and return.

If the connector doesn't already support a mode with such a resolution
it will be created, but should we do that? If the driver supported such
a mode it would certainly already have added it to the mode list,
wouldn't it? After all it's just 2 variants NTSC and PAL.

We have this in drm_client_modeset.c:drm_connector_pick_cmdline_mode():

	list_for_each_entry(mode, &connector->modes, head) {
		/* Check (optional) mode name first */
		if (!strcmp(mode->name, cmdline_mode->name))
			return mode;

Here it looks like the named mode thing is a way to choose a mode, not
to add one.

I couldn't find any documentation on how named modes is supposed to
work, have you seen any?

Noralf.

> +	else if (cmd->cvt)
>  		mode = drm_cvt_mode(dev,
>  				    cmd->xres, cmd->yres,
>  				    cmd->refresh_specified ? cmd->refresh : 60,

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v6 10/23] drm/modes: Fill drm_cmdline mode from named modes
       [not found] ` <20220728-rpi-analog-tv-properties-v6-10-e7792734108f@cerno.tech>
@ 2022-11-06 13:04   ` Noralf Trønnes
  2022-11-07 10:02     ` Maxime Ripard
  0 siblings, 1 reply; 20+ messages in thread
From: Noralf Trønnes @ 2022-11-06 13:04 UTC (permalink / raw)
  To: maxime, 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: linux-sunxi, intel-gfx, Phil Elwell, linux-arm-kernel, nouveau,
	Hans de Goede, Dom Cobley, Mateusz Kwiatkowski, dri-devel,
	Dave Stevenson, linux-kernel, Geert Uytterhoeven,
	Noralf Trønnes



Den 26.10.2022 17.33, skrev maxime@cerno.tech:
> The current code to deal with named modes will only set the mode name, and
> then it's up to drivers to try to match that name to whatever mode or
> configuration they see fit.
> 

I couldn't find any driver that does that, all I could find that cares
about named modes are drm_client. Did I miss something here?

Apart from that:

Reviewed-by: Noralf Trønnes <noralf@tronnes.org>

> The plan is to remove that need and move the named mode handling out of
> drivers and into the core, and only rely on modes and properties. Let's
> start by properly filling drm_cmdline_mode from a named mode.
> 
> Signed-off-by: Maxime Ripard <maxime@cerno.tech>
> ---
>  drivers/gpu/drm/drm_modes.c | 18 ++++++++++++++++--
>  1 file changed, 16 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
> index 7594b657f86a..acee23e1a8b7 100644
> --- a/drivers/gpu/drm/drm_modes.c
> +++ b/drivers/gpu/drm/drm_modes.c
> @@ -2226,11 +2226,22 @@ static int drm_mode_parse_cmdline_options(const char *str,
>  
>  struct drm_named_mode {
>  	const char *name;
> +	unsigned int xres;
> +	unsigned int yres;
> +	unsigned int flags;
>  };
>  
> +#define NAMED_MODE(_name, _x, _y, _flags)		\
> +	{						\
> +		.name = _name,				\
> +		.xres = _x,				\
> +		.yres = _y,				\
> +		.flags = _flags,			\
> +	}
> +
>  static const struct drm_named_mode drm_named_modes[] = {
> -	{ "NTSC", },
> -	{ "PAL", },
> +	NAMED_MODE("NTSC", 720, 480, DRM_MODE_FLAG_INTERLACE),
> +	NAMED_MODE("PAL", 720, 576, DRM_MODE_FLAG_INTERLACE),
>  };
>  
>  static int drm_mode_parse_cmdline_named_mode(const char *name,
> @@ -2271,6 +2282,9 @@ static int drm_mode_parse_cmdline_named_mode(const char *name,
>  			continue;
>  
>  		strcpy(cmdline_mode->name, mode->name);
> +		cmdline_mode->xres = mode->xres;
> +		cmdline_mode->yres = mode->yres;
> +		cmdline_mode->interlace = !!(mode->flags & DRM_MODE_FLAG_INTERLACE);
>  		cmdline_mode->specified = true;
>  
>  		return 1;
> 

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v6 11/23] drm/connector: Add pixel clock to cmdline mode
       [not found] ` <20220728-rpi-analog-tv-properties-v6-11-e7792734108f@cerno.tech>
@ 2022-11-06 13:06   ` Noralf Trønnes
  0 siblings, 0 replies; 20+ messages in thread
From: Noralf Trønnes @ 2022-11-06 13:06 UTC (permalink / raw)
  To: maxime, 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: linux-sunxi, intel-gfx, Phil Elwell, linux-arm-kernel, nouveau,
	Hans de Goede, Dom Cobley, Mateusz Kwiatkowski, dri-devel,
	Dave Stevenson, linux-kernel, Geert Uytterhoeven,
	Noralf Trønnes



Den 26.10.2022 17.33, skrev maxime@cerno.tech:
> We'll need to get the pixel clock to generate proper display modes for
> all the current named modes. Let's add it to struct drm_cmdline_mode and
> fill it when parsing the named mode.
> 
> Signed-off-by: Maxime Ripard <maxime@cerno.tech>
> ---

I would just squash this with the previous patch, either way:

Reviewed-by: Noralf Trønnes <noralf@tronnes.org>

>  drivers/gpu/drm/drm_modes.c | 9 ++++++---
>  include/drm/drm_connector.h | 7 +++++++
>  2 files changed, 13 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
> index acee23e1a8b7..c826f9583a1d 100644
> --- a/drivers/gpu/drm/drm_modes.c
> +++ b/drivers/gpu/drm/drm_modes.c
> @@ -2226,22 +2226,24 @@ static int drm_mode_parse_cmdline_options(const char *str,
>  
>  struct drm_named_mode {
>  	const char *name;
> +	unsigned int pixel_clock_khz;
>  	unsigned int xres;
>  	unsigned int yres;
>  	unsigned int flags;
>  };
>  
> -#define NAMED_MODE(_name, _x, _y, _flags)		\
> +#define NAMED_MODE(_name, _pclk, _x, _y, _flags)	\
>  	{						\
>  		.name = _name,				\
> +		.pixel_clock_khz = _pclk,		\
>  		.xres = _x,				\
>  		.yres = _y,				\
>  		.flags = _flags,			\
>  	}
>  
>  static const struct drm_named_mode drm_named_modes[] = {
> -	NAMED_MODE("NTSC", 720, 480, DRM_MODE_FLAG_INTERLACE),
> -	NAMED_MODE("PAL", 720, 576, DRM_MODE_FLAG_INTERLACE),
> +	NAMED_MODE("NTSC", 13500, 720, 480, DRM_MODE_FLAG_INTERLACE),
> +	NAMED_MODE("PAL", 13500, 720, 576, DRM_MODE_FLAG_INTERLACE),
>  };
>  
>  static int drm_mode_parse_cmdline_named_mode(const char *name,
> @@ -2282,6 +2284,7 @@ static int drm_mode_parse_cmdline_named_mode(const char *name,
>  			continue;
>  
>  		strcpy(cmdline_mode->name, mode->name);
> +		cmdline_mode->pixel_clock = mode->pixel_clock_khz;
>  		cmdline_mode->xres = mode->xres;
>  		cmdline_mode->yres = mode->yres;
>  		cmdline_mode->interlace = !!(mode->flags & DRM_MODE_FLAG_INTERLACE);
> diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
> index 96b2e4e12334..5c5e67de2296 100644
> --- a/include/drm/drm_connector.h
> +++ b/include/drm/drm_connector.h
> @@ -1273,6 +1273,13 @@ struct drm_cmdline_mode {
>  	 */
>  	bool bpp_specified;
>  
> +	/**
> +	 * @pixel_clock:
> +	 *
> +	 * Pixel Clock in kHz. Optional.
> +	 */
> +	unsigned int pixel_clock;
> +
>  	/**
>  	 * @xres:
>  	 *
> 

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v6 13/23] drm/modes: Introduce the tv_mode property as a command-line option
       [not found] ` <20220728-rpi-analog-tv-properties-v6-13-e7792734108f@cerno.tech>
@ 2022-11-06 13:10   ` Noralf Trønnes
  0 siblings, 0 replies; 20+ messages in thread
From: Noralf Trønnes @ 2022-11-06 13:10 UTC (permalink / raw)
  To: maxime, 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: linux-sunxi, intel-gfx, Phil Elwell, linux-arm-kernel, nouveau,
	Hans de Goede, Dom Cobley, Mateusz Kwiatkowski, dri-devel,
	Dave Stevenson, linux-kernel, Geert Uytterhoeven,
	Noralf Trønnes



Den 26.10.2022 17.33, skrev maxime@cerno.tech:
> Our new tv mode option allows to specify the TV mode from a property.
> However, it can still be useful, for example to avoid any boot time
> artifact, to set that property directly from the kernel command line.
> 
> Let's add some code to allow it, and some unit tests to exercise that code.
> 
> Signed-off-by: Maxime Ripard <maxime@cerno.tech>
> 
> ---

I would have just squashed the named mode part of this patch together
with the 2 other named mode patches and keep just the video= option part
here, but up to you:

Reviewed-by: Noralf Trønnes <noralf@tronnes.org>

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v6 16/23] drm/probe-helper: Provide a TV get_modes helper
       [not found] ` <20220728-rpi-analog-tv-properties-v6-16-e7792734108f@cerno.tech>
  2022-10-26 22:02   ` [PATCH v6 16/23] drm/probe-helper: Provide a TV get_modes helper Mateusz Kwiatkowski
@ 2022-11-06 16:33   ` Noralf Trønnes
  2022-11-07 10:21     ` Maxime Ripard
  1 sibling, 1 reply; 20+ messages in thread
From: Noralf Trønnes @ 2022-11-06 16:33 UTC (permalink / raw)
  To: maxime, 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: linux-sunxi, intel-gfx, Phil Elwell, linux-arm-kernel, nouveau,
	Hans de Goede, Dom Cobley, Mateusz Kwiatkowski, dri-devel,
	Dave Stevenson, linux-kernel, Geert Uytterhoeven,
	Noralf Trønnes



Den 26.10.2022 17.33, skrev maxime@cerno.tech:
> 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 <maxime@cerno.tech>
> 
> ---
> 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;
> +

Superfluous linebreak

> +	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

availables -> available

> + * @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);

Nit: You can use the dev variable here and below.

> +		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;

You leak the ntsc mode when returning (possibly).

> +
> +		tv_modes[count++] = mode;
> +	}
> +

Maybe check for count being zero here?

> +	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;

You leak both modes when returning here. Maybe move this up before
allocation to simplify error handling.

> +
> +	if (cmdline->tv_mode_specified)
> +		default_mode = cmdline->tv_mode;

I realised that we don't verify tv_mode coming from the command line,
not here and not in the reset helper. Should we do that? A driver should
be programmed defensively to handle an illegal/unsupported value, but it
doesn't feel right to allow an illegal enum value coming through the
core/helpers.

> +
> +	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);

I know this is not expensive, but you're looping over the property
values 7 times. An alternative solution is to rebuild the supported bitmask:

int drm_connector_helper_tv_get_modes(struct drm_connector *connector)
{
...
	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 supported_tv_modes = 0;

...
	for (i = 0; i < property->num_values; i++)
		supported_tv_modes |= BIT(property->values[i]);

	if (supported_tv_modes & ntsc_modes)
...
	if (supported_tv_modes & pal_modes)
...

	if (BIT(default_mode) & ntsc_modes)
		first_mode_idx = 0;
	else
		first_mode_idx = 1;


Up to you if you want to do this.

Noralf.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v6 16/23] drm/probe-helper: Provide a TV get_modes helper
  2022-10-26 22:02   ` [PATCH v6 16/23] drm/probe-helper: Provide a TV get_modes helper Mateusz Kwiatkowski
  2022-10-27  9:37     ` Maxime Ripard
@ 2022-11-06 16:59     ` Noralf Trønnes
  2022-11-07 10:07       ` Maxime Ripard
  1 sibling, 1 reply; 20+ messages in thread
From: Noralf Trønnes @ 2022-11-06 16:59 UTC (permalink / raw)
  To: Mateusz Kwiatkowski, maxime, 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: linux-sunxi, intel-gfx, Phil Elwell, linux-arm-kernel, nouveau,
	Hans de Goede, Dom Cobley, dri-devel, Dave Stevenson,
	linux-kernel, Geert Uytterhoeven, Noralf Trønnes



Den 27.10.2022 00.02, skrev Mateusz Kwiatkowski:
> Hi Maxime,
> 
> First of all, nice idea with the helper function that can be reused by different
> drivers. This is neat!
> 
> But looking at this function, it feels a bit overcomplicated. You're creating
> the two modes, then checking which one is the default, then set the preferred
> one and possibly reorder them. Maybe it can be simplified somehow?
> 
> Although when I tried to refactor it myself, I ended up with something that's
> not better at all. Maybe it needs to be complicated, after all :(
> 

I also thought that the function was complicated/difficult to read, in
particular the index stuff at the end, but I also failed in finding a
"better" solution, just a different one ;)

Noralf.

My version:

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;
}

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v6 10/23] drm/modes: Fill drm_cmdline mode from named modes
  2022-11-06 13:04   ` [PATCH v6 10/23] drm/modes: Fill drm_cmdline mode from named modes Noralf Trønnes
@ 2022-11-07 10:02     ` Maxime Ripard
  0 siblings, 0 replies; 20+ messages in thread
From: Maxime Ripard @ 2022-11-07 10:02 UTC (permalink / raw)
  To: Noralf Trønnes
  Cc: 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, Joonas Lahtinen, Lyude Paul,
	linux-sunxi, intel-gfx, Phil Elwell, linux-arm-kernel, nouveau,
	Hans de Goede, Dom Cobley, Mateusz Kwiatkowski, dri-devel,
	Dave Stevenson, linux-kernel, Geert Uytterhoeven

[-- Attachment #1: Type: text/plain, Size: 737 bytes --]

On Sun, Nov 06, 2022 at 02:04:56PM +0100, Noralf Trønnes wrote:
> 
> 
> Den 26.10.2022 17.33, skrev maxime@cerno.tech:
> > The current code to deal with named modes will only set the mode name, and
> > then it's up to drivers to try to match that name to whatever mode or
> > configuration they see fit.
> > 
> 
> I couldn't find any driver that does that, all I could find that cares
> about named modes are drm_client. Did I miss something here?

sun4i at least does it:
https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/sun4i/sun4i_tv.c#L292

I'm not aware of any other driver relying on named modes though.

> Apart from that:
> 
> Reviewed-by: Noralf Trønnes <noralf@tronnes.org>

Thanks!
Maxime

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v6 16/23] drm/probe-helper: Provide a TV get_modes helper
  2022-11-06 16:59     ` Noralf Trønnes
@ 2022-11-07 10:07       ` Maxime Ripard
  2022-11-07 11:17         ` Noralf Trønnes
  0 siblings, 1 reply; 20+ messages in thread
From: Maxime Ripard @ 2022-11-07 10:07 UTC (permalink / raw)
  To: Noralf Trønnes
  Cc: Mateusz Kwiatkowski, 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, Joonas Lahtinen, Lyude Paul,
	linux-sunxi, intel-gfx, Phil Elwell, linux-arm-kernel, nouveau,
	Hans de Goede, Dom Cobley, dri-devel, Dave Stevenson,
	linux-kernel, Geert Uytterhoeven

[-- Attachment #1: Type: text/plain, Size: 996 bytes --]

Hi Noralf,

On Sun, Nov 06, 2022 at 05:59:23PM +0100, Noralf Trønnes wrote:
> 
> 
> Den 27.10.2022 00.02, skrev Mateusz Kwiatkowski:
> > Hi Maxime,
> > 
> > First of all, nice idea with the helper function that can be reused by different
> > drivers. This is neat!
> > 
> > But looking at this function, it feels a bit overcomplicated. You're creating
> > the two modes, then checking which one is the default, then set the preferred
> > one and possibly reorder them. Maybe it can be simplified somehow?
> > 
> > Although when I tried to refactor it myself, I ended up with something that's
> > not better at all. Maybe it needs to be complicated, after all :(
> > 
> 
> I also thought that the function was complicated/difficult to read, in
> particular the index stuff at the end, but I also failed in finding a
> "better" solution, just a different one ;)

I think I like yours better still :)

Can I bring it into my series, with your authorship and SoB?

Maxime

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v6 16/23] drm/probe-helper: Provide a TV get_modes helper
  2022-11-06 16:33   ` Noralf Trønnes
@ 2022-11-07 10:21     ` Maxime Ripard
  2022-11-07 11:29       ` Noralf Trønnes
  0 siblings, 1 reply; 20+ messages in thread
From: Maxime Ripard @ 2022-11-07 10:21 UTC (permalink / raw)
  To: Noralf Trønnes
  Cc: 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, Joonas Lahtinen, Lyude Paul,
	linux-sunxi, intel-gfx, Phil Elwell, linux-arm-kernel, nouveau,
	Hans de Goede, Dom Cobley, Mateusz Kwiatkowski, dri-devel,
	Dave Stevenson, linux-kernel, Geert Uytterhoeven

[-- Attachment #1: Type: text/plain, Size: 1153 bytes --]

Hi Noralf,

I'll leave aside your comments on the code, since we'll use your implementation.

On Sun, Nov 06, 2022 at 05:33:48PM +0100, Noralf Trønnes wrote:
> Den 26.10.2022 17.33, skrev maxime@cerno.tech:
> > +
> > +	if (cmdline->tv_mode_specified)
> > +		default_mode = cmdline->tv_mode;
> 
> I realised that we don't verify tv_mode coming from the command line,
> not here and not in the reset helper. Should we do that? A driver should
> be programmed defensively to handle an illegal/unsupported value, but it
> doesn't feel right to allow an illegal enum value coming through the
> core/helpers.

I don't think we can end up with an invalid value here if it's been
specified.

We parse the command line through drm_mode_parse_tv_mode() (introduced
in patch 13 "drm/modes: Introduce the tv_mode property as a command-line
option") that will pick the tv mode part of the command line, and call
drm_get_tv_mode_from_name() using it.

drm_get_tv_mode_from_name() will return a EINVAL if it's not a value we
expect, and mode->tv_mode is only set on success. And AFAIK, there's no
other path that will set tv_mode.

Maxime

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v6 16/23] drm/probe-helper: Provide a TV get_modes helper
  2022-11-07 10:07       ` Maxime Ripard
@ 2022-11-07 11:17         ` Noralf Trønnes
  0 siblings, 0 replies; 20+ messages in thread
From: Noralf Trønnes @ 2022-11-07 11:17 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Mateusz Kwiatkowski, 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, Joonas Lahtinen, Lyude Paul,
	linux-sunxi, intel-gfx, Phil Elwell, linux-arm-kernel, nouveau,
	Hans de Goede, Dom Cobley, dri-devel, Dave Stevenson,
	linux-kernel, Geert Uytterhoeven, Noralf Trønnes



Den 07.11.2022 11.07, skrev Maxime Ripard:
> Hi Noralf,
> 
> On Sun, Nov 06, 2022 at 05:59:23PM +0100, Noralf Trønnes wrote:
>>
>>
>> Den 27.10.2022 00.02, skrev Mateusz Kwiatkowski:
>>> Hi Maxime,
>>>
>>> First of all, nice idea with the helper function that can be reused by different
>>> drivers. This is neat!
>>>
>>> But looking at this function, it feels a bit overcomplicated. You're creating
>>> the two modes, then checking which one is the default, then set the preferred
>>> one and possibly reorder them. Maybe it can be simplified somehow?
>>>
>>> Although when I tried to refactor it myself, I ended up with something that's
>>> not better at all. Maybe it needs to be complicated, after all :(
>>>
>>
>> I also thought that the function was complicated/difficult to read, in
>> particular the index stuff at the end, but I also failed in finding a
>> "better" solution, just a different one ;)
> 
> I think I like yours better still :)
> 
> Can I bring it into my series, with your authorship and SoB?
> 

Sure, no problem.

Noralf.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v6 16/23] drm/probe-helper: Provide a TV get_modes helper
  2022-11-07 10:21     ` Maxime Ripard
@ 2022-11-07 11:29       ` Noralf Trønnes
  2022-11-07 12:45         ` Maxime Ripard
  0 siblings, 1 reply; 20+ messages in thread
From: Noralf Trønnes @ 2022-11-07 11:29 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: 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, Joonas Lahtinen, Lyude Paul,
	linux-sunxi, intel-gfx, Phil Elwell, linux-arm-kernel, nouveau,
	Hans de Goede, Dom Cobley, Mateusz Kwiatkowski, dri-devel,
	Dave Stevenson, linux-kernel, Geert Uytterhoeven,
	Noralf Trønnes



Den 07.11.2022 11.21, skrev Maxime Ripard:
> Hi Noralf,
> 
> I'll leave aside your comments on the code, since we'll use your implementation.
> 
> On Sun, Nov 06, 2022 at 05:33:48PM +0100, Noralf Trønnes wrote:
>> Den 26.10.2022 17.33, skrev maxime@cerno.tech:
>>> +
>>> +	if (cmdline->tv_mode_specified)
>>> +		default_mode = cmdline->tv_mode;
>>
>> I realised that we don't verify tv_mode coming from the command line,
>> not here and not in the reset helper. Should we do that? A driver should
>> be programmed defensively to handle an illegal/unsupported value, but it
>> doesn't feel right to allow an illegal enum value coming through the
>> core/helpers.
> 
> I don't think we can end up with an invalid value here if it's been
> specified.
> 
> We parse the command line through drm_mode_parse_tv_mode() (introduced
> in patch 13 "drm/modes: Introduce the tv_mode property as a command-line
> option") that will pick the tv mode part of the command line, and call
> drm_get_tv_mode_from_name() using it.
> 
> drm_get_tv_mode_from_name() will return a EINVAL if it's not a value we
> expect, and mode->tv_mode is only set on success. And AFAIK, there's no
> other path that will set tv_mode.
> 

I see now that illegal was the wrong word, but if the driver only
supports ntsc, the user can still set tv_mode=PAL right? And that's an
unsupported value that the driver can't fulfill, so it errors out. But
then again maybe that's just how it is, we can also set a display mode
that the driver can't handle, so this is no different in that respect.
Yeah, my argument lost some of its strength here :)

Noralf.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v6 16/23] drm/probe-helper: Provide a TV get_modes helper
  2022-11-07 11:29       ` Noralf Trønnes
@ 2022-11-07 12:45         ` Maxime Ripard
  0 siblings, 0 replies; 20+ messages in thread
From: Maxime Ripard @ 2022-11-07 12:45 UTC (permalink / raw)
  To: Noralf Trønnes
  Cc: 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, Joonas Lahtinen, Lyude Paul,
	linux-sunxi, intel-gfx, Phil Elwell, linux-arm-kernel, nouveau,
	Hans de Goede, Dom Cobley, Mateusz Kwiatkowski, dri-devel,
	Dave Stevenson, linux-kernel, Geert Uytterhoeven

[-- Attachment #1: Type: text/plain, Size: 2099 bytes --]

On Mon, Nov 07, 2022 at 12:29:28PM +0100, Noralf Trønnes wrote:
> 
> 
> Den 07.11.2022 11.21, skrev Maxime Ripard:
> > Hi Noralf,
> > 
> > I'll leave aside your comments on the code, since we'll use your implementation.
> > 
> > On Sun, Nov 06, 2022 at 05:33:48PM +0100, Noralf Trønnes wrote:
> >> Den 26.10.2022 17.33, skrev maxime@cerno.tech:
> >>> +
> >>> +	if (cmdline->tv_mode_specified)
> >>> +		default_mode = cmdline->tv_mode;
> >>
> >> I realised that we don't verify tv_mode coming from the command line,
> >> not here and not in the reset helper. Should we do that? A driver should
> >> be programmed defensively to handle an illegal/unsupported value, but it
> >> doesn't feel right to allow an illegal enum value coming through the
> >> core/helpers.
> > 
> > I don't think we can end up with an invalid value here if it's been
> > specified.
> > 
> > We parse the command line through drm_mode_parse_tv_mode() (introduced
> > in patch 13 "drm/modes: Introduce the tv_mode property as a command-line
> > option") that will pick the tv mode part of the command line, and call
> > drm_get_tv_mode_from_name() using it.
> > 
> > drm_get_tv_mode_from_name() will return a EINVAL if it's not a value we
> > expect, and mode->tv_mode is only set on success. And AFAIK, there's no
> > other path that will set tv_mode.
> > 
> 
> I see now that illegal was the wrong word, but if the driver only
> supports ntsc, the user can still set tv_mode=PAL right? And that's an
> unsupported value that the driver can't fulfill, so it errors out. But
> then again maybe that's just how it is, we can also set a display mode
> that the driver can't handle, so this is no different in that respect.
> Yeah, my argument lost some of its strength here :)

I don't think we can handle this better, really. Falling back to NTSC in
that case would really be a stretch: it's a different mode, with a
different TV mode, etc.

It's an even bigger stretch than picking another mode I guess, and like
you said we're not doing that if the mode isn't supported

Maxime

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v6 14/23] drm/modes: Properly generate a drm_display_mode from a named mode
  2022-11-05 17:50   ` Noralf Trønnes
@ 2022-11-07 13:34     ` Maxime Ripard
  0 siblings, 0 replies; 20+ messages in thread
From: Maxime Ripard @ 2022-11-07 13:34 UTC (permalink / raw)
  To: Noralf Trønnes
  Cc: 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, Joonas Lahtinen, Lyude Paul,
	linux-sunxi, intel-gfx, Phil Elwell, linux-arm-kernel, nouveau,
	Hans de Goede, Dom Cobley, Mateusz Kwiatkowski, dri-devel,
	Dave Stevenson, linux-kernel, Geert Uytterhoeven

[-- Attachment #1: Type: text/plain, Size: 4945 bytes --]

On Sat, Nov 05, 2022 at 06:50:30PM +0100, Noralf Trønnes wrote:
> Den 26.10.2022 17.33, skrev maxime@cerno.tech:
> > The framework will get the drm_display_mode from the drm_cmdline_mode it
> > got by parsing the video command line argument by calling
> > drm_connector_pick_cmdline_mode().
> > 
> > The heavy lifting will then be done by the drm_mode_create_from_cmdline_mode()
> > function.
> > 
> > In the case of the named modes though, there's no real code to make that
> > translation and we rely on the drivers to guess which actual display mode
> > we meant.
> > 
> > Let's modify drm_mode_create_from_cmdline_mode() to properly generate the
> > drm_display_mode we mean when passing a named mode.
> > 
> > Signed-off-by: Maxime Ripard <maxime@cerno.tech>
> > 
> > ---
> > Changes in v6:
> > - Fix get_modes to return 0 instead of an error code
> > - Rename the tests to follow the DRM test naming convention
> > 
> > Changes in v5:
> > - Switched to KUNIT_ASSERT_NOT_NULL
> > ---
> >  drivers/gpu/drm/drm_modes.c                     | 34 ++++++++++-
> >  drivers/gpu/drm/tests/drm_client_modeset_test.c | 77 ++++++++++++++++++++++++-
> >  2 files changed, 109 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
> > index dc037f7ceb37..85aa9898c229 100644
> > --- a/drivers/gpu/drm/drm_modes.c
> > +++ b/drivers/gpu/drm/drm_modes.c
> > @@ -2497,6 +2497,36 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option,
> >  }
> >  EXPORT_SYMBOL(drm_mode_parse_command_line_for_connector);
> >  
> > +static struct drm_display_mode *drm_named_mode(struct drm_device *dev,
> > +					       struct drm_cmdline_mode *cmd)
> > +{
> > +	struct drm_display_mode *mode;
> > +	unsigned int i;
> > +
> > +	for (i = 0; i < ARRAY_SIZE(drm_named_modes); i++) {
> > +		const struct drm_named_mode *named_mode = &drm_named_modes[i];
> > +
> > +		if (strcmp(cmd->name, named_mode->name))
> > +			continue;
> > +
> > +		if (!named_mode->tv_mode)
> > +			continue;
> > +
> > +		mode = drm_analog_tv_mode(dev,
> > +					  named_mode->tv_mode,
> > +					  named_mode->pixel_clock_khz * 1000,
> > +					  named_mode->xres,
> > +					  named_mode->yres,
> > +					  named_mode->flags & DRM_MODE_FLAG_INTERLACE);
> > +		if (!mode)
> > +			return NULL;
> > +
> > +		return mode;
> > +	}
> > +
> > +	return NULL;
> > +}
> > +
> >  /**
> >   * drm_mode_create_from_cmdline_mode - convert a command line modeline into a DRM display mode
> >   * @dev: DRM device to create the new mode for
> > @@ -2514,7 +2544,9 @@ drm_mode_create_from_cmdline_mode(struct drm_device *dev,
> >  	if (cmd->xres == 0 || cmd->yres == 0)
> >  		return NULL;
> >  
> > -	if (cmd->cvt)
> > +	if (strlen(cmd->name))
> > +		mode = drm_named_mode(dev, cmd);
> 
> I'm trying to track how this generated mode fits into to it all and
> AFAICS if the connector already supports a mode with the same xres/yres
> as the named mode, the named mode will never be created because of the
> check at the beginning of drm_helper_probe_add_cmdline_mode(). It will
> just mark the existing mode with USERDEF and return.

Yep, you're right

> If the connector doesn't already support a mode with such a resolution
> it will be created, but should we do that? If the driver supported such
> a mode it would certainly already have added it to the mode list,
> wouldn't it? After all it's just 2 variants NTSC and PAL.

I wasn't so sure about this part. I think it's still benefitial because
some users (Geert at least has expressed that need) might want a smaller
mode than 480i/576i, whereas the driver is realistically only going to
register those two.

So creating that mode if it isn't declared seems to have value to some.

> We have this in drm_client_modeset.c:drm_connector_pick_cmdline_mode():
> 
> 	list_for_each_entry(mode, &connector->modes, head) {
> 		/* Check (optional) mode name first */
> 		if (!strcmp(mode->name, cmdline_mode->name))
> 			return mode;
> 
> Here it looks like the named mode thing is a way to choose a mode, not
> to add one.
> 
> I couldn't find any documentation on how named modes is supposed to
> work, have you seen any?

Eh, I guess I'm to blame for that :)

Named modes are really only about the command-line name. The way it was
initially introduced was pretty much to only pass down the name to
drivers for them to figure it out, like we've been doing in sun4i:

https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/sun4i/sun4i_tv.c#L292

It wasn't really working, especially because the userspace pretty much
ignores it. One of the point of this series is to create a proper mode
(and state, really) from the name passed on the command line so that
drivers don't have to behave any different from usual, and userspace can
be involved there too.

Maxime

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2022-11-07 13:34 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <20220728-rpi-analog-tv-properties-v6-0-e7792734108f@cerno.tech>
     [not found] ` <20220728-rpi-analog-tv-properties-v6-22-e7792734108f@cerno.tech>
2022-10-26 22:32   ` [PATCH v6 22/23] drm/vc4: vec: Add support for more analog TV standards Mateusz Kwiatkowski
2022-10-27 11:58     ` Maxime Ripard
     [not found] ` <20220728-rpi-analog-tv-properties-v6-8-e7792734108f@cerno.tech>
2022-11-05 14:02   ` [PATCH v6 08/23] drm/modes: Move named modes parsing to a separate function Noralf Trønnes
     [not found] ` <20220728-rpi-analog-tv-properties-v6-9-e7792734108f@cerno.tech>
2022-11-05 14:06   ` [PATCH v6 09/23] drm/modes: Switch to named mode descriptors Noralf Trønnes
     [not found] ` <20220728-rpi-analog-tv-properties-v6-14-e7792734108f@cerno.tech>
2022-10-26 21:25   ` [PATCH v6 14/23] drm/modes: Properly generate a drm_display_mode from a named mode Mateusz Kwiatkowski
2022-11-05 17:50   ` Noralf Trønnes
2022-11-07 13:34     ` Maxime Ripard
     [not found] ` <20220728-rpi-analog-tv-properties-v6-10-e7792734108f@cerno.tech>
2022-11-06 13:04   ` [PATCH v6 10/23] drm/modes: Fill drm_cmdline mode from named modes Noralf Trønnes
2022-11-07 10:02     ` Maxime Ripard
     [not found] ` <20220728-rpi-analog-tv-properties-v6-11-e7792734108f@cerno.tech>
2022-11-06 13:06   ` [PATCH v6 11/23] drm/connector: Add pixel clock to cmdline mode Noralf Trønnes
     [not found] ` <20220728-rpi-analog-tv-properties-v6-13-e7792734108f@cerno.tech>
2022-11-06 13:10   ` [PATCH v6 13/23] drm/modes: Introduce the tv_mode property as a command-line option Noralf Trønnes
     [not found] ` <20220728-rpi-analog-tv-properties-v6-16-e7792734108f@cerno.tech>
2022-10-26 22:02   ` [PATCH v6 16/23] drm/probe-helper: Provide a TV get_modes helper Mateusz Kwiatkowski
2022-10-27  9:37     ` Maxime Ripard
2022-11-06 16:59     ` Noralf Trønnes
2022-11-07 10:07       ` Maxime Ripard
2022-11-07 11:17         ` Noralf Trønnes
2022-11-06 16:33   ` Noralf Trønnes
2022-11-07 10:21     ` Maxime Ripard
2022-11-07 11:29       ` Noralf Trønnes
2022-11-07 12:45         ` Maxime Ripard

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome