2022-07-29 16:50:03

by Maxime Ripard

[permalink] [raw]
Subject: [PATCH v1 00/35] drm: Analog TV Improvements

Hi,

Here's a series aiming at improving the command line named modes support,
and more importantly how we deal with all the analog TV variants.

The named modes support were initially introduced to allow to specify the
analog TV mode to be used.

However, this was causing multiple issues:

* The mode name parsed on the command line was passed directly to the
driver, which had to figure out which mode it was suppose to match;

* Figuring that out wasn't really easy, since the video= argument or what
the userspace might not even have a name in the first place, but
instead could have passed a mode with the same timings;

* The fallback to matching on the timings was mostly working as long as
we were supporting one 525 lines (most likely NSTC) and one 625 lines
(PAL), but couldn't differentiate between two modes with the same
timings (NTSC vs PAL-M vs NSTC-J for example);

* There was also some overlap with the tv mode property registered by
drm_mode_create_tv_properties(), but named modes weren't interacting
with that property at all.

* Even though that property was generic, its possible values were
specific to each drivers, which made some generic support difficult.

Thus, I chose to tackle in multiple steps:

* A new TV norm property was introduced, with generic values, each driver
reporting through a bitmask what standard it supports to the userspace;

* This option was added to the command line parsing code to be able to
specify it on the kernel command line, and new atomic_check and reset
helpers were created to integrate properly into atomic KMS;

* The named mode parsing code is now creating a proper display mode for
the given named mode, and the TV standard will thus be part of the
connector state;

* Two drivers were converted and tested for now (vc4 and sun4i), with
some backward compatibility code to translate the old TV mode to the
new TV mode;

Unit tests were created along the way. Nouveau, ch7006 and gud are
currently broken for now since I expect that work to be reworked fairly
significantly. I'm also not entirely sure about how to migrate GUD to the
new property.

Let me know what you think,
Maxime

Cc: Geert Uytterhoeven <[email protected]>
Cc: "Noralf Trønnes" <[email protected]>
Cc: Dave Stevenson <[email protected]>
Cc: Dom Cobley <[email protected]>
Cc: Phil Elwell <[email protected]>
Cc: Maarten Lankhorst <[email protected]>
Cc: Thomas Zimmermann <[email protected]>
Cc: Daniel Vetter <[email protected]>
Cc: David Airlie <[email protected]>
Cc: <[email protected]>
Signed-off-by: Maxime Ripard <[email protected]>

---
Mateusz Kwiatkowski (5):
drm/vc4: vec: Refactor VEC TV mode setting
drm/vc4: vec: Remove redundant atomic_mode_set
drm/vc4: vec: Fix timings for VEC modes
drm/vc4: vec: Fix definition of PAL-M mode
drm/vc4: vec: Add support for more analog TV standards

Maxime Ripard (30):
drm/atomic-helper: Rename drm_atomic_helper_connector_tv_reset to avoid ambiguity
drm/connector: Rename subconnector state variable
drm/atomic: Add TV subconnector property to get/set_property
drm/modes: Introduce 480i and 576i modes
drm/connector: Add TV standard property
drm/connector: Only register TV mode property if present
drm/modes: Only consider bpp and refresh before options
drm/client: Add some tests for drm_connector_pick_cmdline_mode()
drm/modes: Move named modes parsing to a separate function
drm/modes: Switch to named mode descriptors
drm/modes: Fill drm_cmdline mode from named modes
drmi/modes: Properly generate a drm_display_mode from a named mode
drm/atomic-helper: Add a TV properties reset helper
drm/atomic-helper: Add an analog TV atomic_check implementation
drm/vc4: vec: Remove empty mode_fixup
drm/vc4: vec: Convert to atomic helpers
drm/vc4: vec: Switch for common modes
drm/vc4: vec: Use TV Reset implementation
drm/vc4: vec: Convert to the new TV mode property
drm/sun4i: tv: Remove unused mode_valid
drm/sun4i: tv: Convert to atomic hooks
drm/sun4i: tv: Merge mode_set into atomic_enable
drm/sun4i: tv: Remove useless function
drm/sun4i: tv: Remove useless destroy function
drm/sun4i: tv: Rename error label
drm/sun4i: tv: Add missing reset assertion
drm/sun4i: tv: Convert to the new TV mode property
drm/connector: Remove TV modes property
drm/modes: Introduce the tv_mode property as a command-line option
drm/modes: Introduce more named modes

drivers/gpu/drm/drm_atomic_state_helper.c | 166 +++++++++-
drivers/gpu/drm/drm_atomic_uapi.c | 12 +-
drivers/gpu/drm/drm_client_modeset.c | 4 +
drivers/gpu/drm/drm_connector.c | 46 ++-
drivers/gpu/drm/drm_modes.c | 198 +++++++++--
drivers/gpu/drm/gud/gud_connector.c | 2 +-
drivers/gpu/drm/meson/meson_encoder_cvbs.c | 18 +-
drivers/gpu/drm/meson/meson_encoder_cvbs.h | 2 +-
drivers/gpu/drm/sun4i/sun4i_tv.c | 173 +++-------
drivers/gpu/drm/tests/drm_cmdline_parser_test.c | 295 +++++++++++++++++
drivers/gpu/drm/tests/drm_mode_test.c | 255 +++++++++++++++
drivers/gpu/drm/vc4/vc4_hdmi.c | 2 +-
drivers/gpu/drm/vc4/vc4_vec.c | 418 ++++++++++++++++--------
include/drm/drm_atomic_state_helper.h | 4 +
include/drm/drm_connector.h | 40 ++-
include/drm/drm_mode_config.h | 6 +
include/drm/drm_modes.h | 3 +
17 files changed, 1314 insertions(+), 330 deletions(-)
---
base-commit: 37b355fdaf31ee18bda9a93c2a438dc1cbf57ec9
change-id: 20220728-rpi-analog-tv-properties-0914dfcee460

Best regards,
--
Maxime Ripard <[email protected]>


2022-07-29 16:51:32

by Maxime Ripard

[permalink] [raw]
Subject: [PATCH v1 10/35] drm/modes: Switch to named mode descriptors

The current named mode parsing relies only the mode name, and doesn't allow
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 <[email protected]>

diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index e85099df0326..1421e5da49e0 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -1768,9 +1768,13 @@ static int drm_mode_parse_cmdline_options(const char *str,
return 0;
}

-static const char * const drm_named_modes_whitelist[] = {
- "NTSC",
- "PAL",
+struct drm_named_mode {
+ const char *name;
+};
+
+static const struct drm_named_mode drm_named_modes[] = {
+ { "NTSC", },
+ { "PAL", },
};

static bool drm_mode_parse_cmdline_named_mode(const char *name,
@@ -1779,14 +1783,15 @@ static bool drm_mode_parse_cmdline_named_mode(const char *name,
{
unsigned int i;

- for (i = 0; i < ARRAY_SIZE(drm_named_modes_whitelist); i++) {
+ for (i = 0; i < ARRAY_SIZE(drm_named_modes); i++) {
+ const struct drm_named_mode *mode = &drm_named_modes[i];
int ret;

- ret = str_has_prefix(name, drm_named_modes_whitelist[i]);
+ ret = str_has_prefix(name, mode->name);
if (ret != name_end)
continue;

- strcpy(cmdline_mode->name, drm_named_modes_whitelist[i]);
+ strcpy(cmdline_mode->name, mode->name);
cmdline_mode->specified = true;

return true;

--
b4 0.10.0-dev-49460

2022-07-29 16:52:24

by Maxime Ripard

[permalink] [raw]
Subject: [PATCH v1 09/35] drm/modes: Move named modes parsing to a separate function

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.

Signed-off-by: Maxime Ripard <[email protected]>

diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index 06a006e0b2e3..e85099df0326 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -1773,6 +1773,28 @@ static const char * const drm_named_modes_whitelist[] = {
"PAL",
};

+static bool drm_mode_parse_cmdline_named_mode(const char *name,
+ unsigned int name_end,
+ struct drm_cmdline_mode *cmdline_mode)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(drm_named_modes_whitelist); i++) {
+ int ret;
+
+ ret = str_has_prefix(name, drm_named_modes_whitelist[i]);
+ if (ret != name_end)
+ continue;
+
+ strcpy(cmdline_mode->name, drm_named_modes_whitelist[i]);
+ cmdline_mode->specified = true;
+
+ return true;
+ }
+
+ return false;
+}
+
/**
* drm_mode_parse_command_line_for_connector - parse command line modeline for connector
* @mode_option: optional per connector mode option
@@ -1809,7 +1831,7 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option,
const char *bpp_ptr = NULL, *refresh_ptr = NULL, *extra_ptr = NULL;
const char *options_ptr = NULL;
char *bpp_end_ptr = NULL, *refresh_end_ptr = NULL;
- int i, len, ret;
+ int len, ret;

memset(mode, 0, sizeof(*mode));
mode->panel_orientation = DRM_MODE_PANEL_ORIENTATION_UNKNOWN;
@@ -1848,18 +1870,14 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option,
parse_extras = true;
}

- /* First check for a named mode */
- for (i = 0; i < ARRAY_SIZE(drm_named_modes_whitelist); i++) {
- ret = str_has_prefix(name, drm_named_modes_whitelist[i]);
- if (ret == mode_end) {
- if (refresh_ptr)
- return false; /* named + refresh is invalid */
+ /*
+ * Having a mode that starts by a letter (and thus is named) and
+ * an at-sign (used to specify a refresh rate) is disallowed.
+ */
+ if (!isdigit(name[0]) && refresh_ptr)
+ return false;

- strcpy(mode->name, drm_named_modes_whitelist[i]);
- mode->specified = true;
- break;
- }
- }
+ drm_mode_parse_cmdline_named_mode(name, mode_end, mode);

/* No named mode? Check for a normal mode argument, e.g. 1024x768 */
if (!mode->specified && isdigit(name[0])) {

--
b4 0.10.0-dev-49460

2022-07-29 16:52:28

by Maxime Ripard

[permalink] [raw]
Subject: [PATCH v1 06/35] drm/connector: Only register TV mode property if present

The drm_create_tv_properties() will create the TV mode property
unconditionally.

However, since we'll gradually phase it out, let's register it only if we
have a list passed as an argument. This will make the transition easier.

Signed-off-by: Maxime Ripard <[email protected]>

diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 68a4e47f85a9..d73a68764b6e 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -1684,7 +1684,6 @@ int drm_mode_create_tv_properties(struct drm_device *dev,
struct drm_property *tv_selector;
struct drm_property *tv_subconnector;
struct drm_property *tv_norm;
- unsigned int i;

if (dev->mode_config.tv_select_subconnector_property)
return 0;
@@ -1723,15 +1722,19 @@ int drm_mode_create_tv_properties(struct drm_device *dev,
goto nomem;
dev->mode_config.tv_norm_property = tv_norm;

- dev->mode_config.tv_mode_property =
- drm_property_create(dev, DRM_MODE_PROP_ENUM,
- "mode", num_modes);
- if (!dev->mode_config.tv_mode_property)
- goto nomem;
+ if (num_modes) {
+ unsigned int i;

- for (i = 0; i < num_modes; i++)
- drm_property_add_enum(dev->mode_config.tv_mode_property,
- i, modes[i]);
+ dev->mode_config.tv_mode_property =
+ drm_property_create(dev, DRM_MODE_PROP_ENUM,
+ "mode", num_modes);
+ if (!dev->mode_config.tv_mode_property)
+ goto nomem;
+
+ for (i = 0; i < num_modes; i++)
+ drm_property_add_enum(dev->mode_config.tv_mode_property,
+ i, modes[i]);
+ }

dev->mode_config.tv_brightness_property =
drm_property_create_range(dev, 0, "brightness", 0, 100);

--
b4 0.10.0-dev-49460

2022-07-29 16:52:29

by Maxime Ripard

[permalink] [raw]
Subject: [PATCH v1 08/35] drm/client: Add some tests for drm_connector_pick_cmdline_mode()

drm_connector_pick_cmdline_mode() is in charge of finding a proper
drm_display_mode from the definition we got in the video= command line
argument.

Let's add some unit tests to make sure we're not getting any regressions
there.

Signed-off-by: Maxime Ripard <[email protected]>

diff --git a/drivers/gpu/drm/drm_client_modeset.c b/drivers/gpu/drm/drm_client_modeset.c
index bbc535cc50dd..ee6b8f193c24 100644
--- a/drivers/gpu/drm/drm_client_modeset.c
+++ b/drivers/gpu/drm/drm_client_modeset.c
@@ -1237,3 +1237,7 @@ int drm_client_modeset_dpms(struct drm_client_dev *client, int mode)
return ret;
}
EXPORT_SYMBOL(drm_client_modeset_dpms);
+
+#ifdef CONFIG_DRM_KUNIT_TEST
+#include "tests/drm_mode_test.c"
+#endif
diff --git a/drivers/gpu/drm/tests/drm_mode_test.c b/drivers/gpu/drm/tests/drm_mode_test.c
new file mode 100644
index 000000000000..0f71519788a7
--- /dev/null
+++ b/drivers/gpu/drm/tests/drm_mode_test.c
@@ -0,0 +1,132 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 Maxime Ripard <[email protected]>
+ */
+
+#include <drm/drm_mode.h>
+#include <kunit/test.h>
+
+#include <drm/drm_connector.h>
+#include <drm/drm_edid.h>
+#include <drm/drm_drv.h>
+#include <drm/drm_modes.h>
+#include <drm/drm_modeset_helper_vtables.h>
+#include <drm/drm_probe_helper.h>
+
+struct drm_mode_test_priv {
+ struct device *dev;
+ struct drm_device *drm;
+ struct drm_connector connector;
+};
+
+static const struct drm_mode_config_funcs drm_mode_config_funcs = {
+};
+
+static const struct drm_driver drm_mode_driver = {
+};
+
+static int drm_mode_connector_get_modes(struct drm_connector *connector)
+{
+ struct drm_display_mode *mode;
+ int ret;
+
+ ret = drm_add_modes_noedid(connector, 1920, 1200);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static const struct drm_connector_helper_funcs drm_mode_connector_helper_funcs = {
+ .get_modes = drm_mode_connector_get_modes,
+};
+
+static const struct drm_connector_funcs drm_mode_connector_funcs = {
+};
+
+static int drm_mode_test_init(struct kunit *test)
+{
+ struct drm_mode_test_priv *priv;
+ int ret;
+
+ priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+ test->priv = priv;
+
+ priv->dev = root_device_register("drm-mode-test");
+ if (IS_ERR(priv->dev))
+ return PTR_ERR(priv->dev);
+
+ priv->drm = drm_dev_alloc(&drm_mode_driver, priv->dev);
+ if (IS_ERR(priv->drm))
+ return PTR_ERR(priv->drm);
+ priv->drm->mode_config.funcs = &drm_mode_config_funcs;
+
+ ret = drmm_mode_config_init(priv->drm);
+ if (ret)
+ return ret;
+
+ ret = drmm_connector_init(priv->drm, &priv->connector,
+ &drm_mode_connector_funcs,
+ DRM_MODE_CONNECTOR_Unknown,
+ NULL);
+ if (ret)
+ return ret;
+ drm_connector_helper_add(&priv->connector, &drm_mode_connector_helper_funcs);
+
+ return 0;
+}
+
+static void drm_mode_test_exit(struct kunit *test)
+{
+ struct drm_mode_test_priv *priv = test->priv;
+
+ drm_dev_put(priv->drm);
+ root_device_unregister(priv->dev);
+}
+
+static void drm_mode_res_1920_1080_60(struct kunit *test)
+{
+ struct drm_mode_test_priv *priv = test->priv;
+ struct drm_device *drm = priv->drm;
+ struct drm_connector *connector = &priv->connector;
+ struct drm_cmdline_mode *cmdline_mode = &connector->cmdline_mode;
+ struct drm_display_mode *expected_mode, *mode;
+ const char *cmdline = "1920x1080@60";
+ int ret;
+
+ expected_mode = drm_mode_find_dmt(priv->drm, 1920, 1080, 60, false);
+ KUNIT_ASSERT_PTR_NE(test, expected_mode, NULL);
+
+ KUNIT_ASSERT_TRUE(test,
+ drm_mode_parse_command_line_for_connector(cmdline,
+ connector,
+ cmdline_mode));
+
+ mutex_lock(&drm->mode_config.mutex);
+ ret = drm_helper_probe_single_connector_modes(connector, 1920, 1080);
+ mutex_unlock(&drm->mode_config.mutex);
+ KUNIT_ASSERT_GT(test, ret, 0);
+
+ mode = drm_connector_pick_cmdline_mode(connector);
+ KUNIT_ASSERT_PTR_NE(test, mode, NULL);
+
+ KUNIT_EXPECT_TRUE(test, drm_mode_equal(expected_mode, mode));
+}
+
+static struct kunit_case drm_mode_tests[] = {
+ KUNIT_CASE(drm_mode_res_1920_1080_60),
+ {}
+};
+
+static struct kunit_suite drm_mode_test_suite = {
+ .name = "drm_mode",
+ .init = drm_mode_test_init,
+ .exit = drm_mode_test_exit,
+ .test_cases = drm_mode_tests
+};
+
+kunit_test_suite(drm_mode_test_suite);
+MODULE_AUTHOR("Maxime Ripard <[email protected]>");
+MODULE_LICENSE("GPL");

--
b4 0.10.0-dev-49460

2022-07-29 16:53:00

by Maxime Ripard

[permalink] [raw]
Subject: [PATCH v1 16/35] drm/vc4: vec: Convert to atomic helpers

The VC4 VEC driver still uses legacy enable and disable hook
implementation. Let's convert to the atomic variants.

Signed-off-by: Maxime Ripard <[email protected]>

diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c
index 17a6afac61cd..ba0a81250d08 100644
--- a/drivers/gpu/drm/vc4/vc4_vec.c
+++ b/drivers/gpu/drm/vc4/vc4_vec.c
@@ -375,7 +375,8 @@ static int vc4_vec_connector_init(struct drm_device *dev, struct vc4_vec *vec)
return 0;
}

-static void vc4_vec_encoder_disable(struct drm_encoder *encoder)
+static void vc4_vec_encoder_disable(struct drm_encoder *encoder,
+ struct drm_atomic_state *state)
{
struct drm_device *drm = encoder->dev;
struct vc4_vec *vec = encoder_to_vc4_vec(encoder);
@@ -406,7 +407,8 @@ static void vc4_vec_encoder_disable(struct drm_encoder *encoder)
drm_dev_exit(idx);
}

-static void vc4_vec_encoder_enable(struct drm_encoder *encoder)
+static void vc4_vec_encoder_enable(struct drm_encoder *encoder,
+ struct drm_atomic_state *state)
{
struct drm_device *drm = encoder->dev;
struct vc4_vec *vec = encoder_to_vc4_vec(encoder);
@@ -508,9 +510,9 @@ static int vc4_vec_encoder_atomic_check(struct drm_encoder *encoder,
}

static const struct drm_encoder_helper_funcs vc4_vec_encoder_helper_funcs = {
- .disable = vc4_vec_encoder_disable,
- .enable = vc4_vec_encoder_enable,
.atomic_check = vc4_vec_encoder_atomic_check,
+ .atomic_disable = vc4_vec_encoder_disable,
+ .atomic_enable = vc4_vec_encoder_enable,
.atomic_mode_set = vc4_vec_encoder_atomic_mode_set,
};


--
b4 0.10.0-dev-49460

2022-07-29 16:53:36

by Maxime Ripard

[permalink] [raw]
Subject: [PATCH v1 04/35] drm/modes: Introduce 480i and 576i modes

Multiple drivers (meson, vc4) define the analog TV 525-lines and 625-lines
modes in the drivers.

Since those modes are fairly standards, and that we'll need to use them in
more places in the future, let's move the meson definition into the
framework.

The meson one was chosen because vc4's isn't accurate and doesn't amount to
525 and 625 lines.

Signed-off-by: Maxime Ripard <[email protected]>

diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index 304004fb80aa..a4c1bd688338 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -48,6 +48,24 @@

#include "drm_crtc_internal.h"

+const struct drm_display_mode drm_mode_480i = {
+ DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 13500,
+ 720, 739, 801, 858, 0,
+ 480, 488, 494, 525, 0,
+ DRM_MODE_FLAG_INTERLACE),
+ .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3,
+};
+EXPORT_SYMBOL_GPL(drm_mode_480i);
+
+const struct drm_display_mode drm_mode_576i = {
+ DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 13500,
+ 720, 732, 795, 864, 0,
+ 576, 580, 586, 625, 0,
+ DRM_MODE_FLAG_INTERLACE),
+ .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3,
+};
+EXPORT_SYMBOL_GPL(drm_mode_576i);
+
/**
* drm_mode_debug_printmodeline - print a mode to dmesg
* @mode: mode to print
diff --git a/drivers/gpu/drm/meson/meson_encoder_cvbs.c b/drivers/gpu/drm/meson/meson_encoder_cvbs.c
index 8110a6e39320..98ec3e563155 100644
--- a/drivers/gpu/drm/meson/meson_encoder_cvbs.c
+++ b/drivers/gpu/drm/meson/meson_encoder_cvbs.c
@@ -45,21 +45,11 @@ struct meson_encoder_cvbs {
struct meson_cvbs_mode meson_cvbs_modes[MESON_CVBS_MODES_COUNT] = {
{ /* PAL */
.enci = &meson_cvbs_enci_pal,
- .mode = {
- DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 13500,
- 720, 732, 795, 864, 0, 576, 580, 586, 625, 0,
- DRM_MODE_FLAG_INTERLACE),
- .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3,
- },
+ .mode = &drm_mode_576i,
},
{ /* NTSC */
.enci = &meson_cvbs_enci_ntsc,
- .mode = {
- DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 13500,
- 720, 739, 801, 858, 0, 480, 488, 494, 525, 0,
- DRM_MODE_FLAG_INTERLACE),
- .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3,
- },
+ .mode = &drm_mode_480i,
},
};

@@ -71,7 +61,7 @@ meson_cvbs_get_mode(const struct drm_display_mode *req_mode)
for (i = 0; i < MESON_CVBS_MODES_COUNT; ++i) {
struct meson_cvbs_mode *meson_mode = &meson_cvbs_modes[i];

- if (drm_mode_match(req_mode, &meson_mode->mode,
+ if (drm_mode_match(req_mode, meson_mode->mode,
DRM_MODE_MATCH_TIMINGS |
DRM_MODE_MATCH_CLOCK |
DRM_MODE_MATCH_FLAGS |
@@ -104,7 +94,7 @@ static int meson_encoder_cvbs_get_modes(struct drm_bridge *bridge,
for (i = 0; i < MESON_CVBS_MODES_COUNT; ++i) {
struct meson_cvbs_mode *meson_mode = &meson_cvbs_modes[i];

- mode = drm_mode_duplicate(priv->drm, &meson_mode->mode);
+ mode = drm_mode_duplicate(priv->drm, meson_mode->mode);
if (!mode) {
dev_err(priv->dev, "Failed to create a new display mode\n");
return 0;
diff --git a/drivers/gpu/drm/meson/meson_encoder_cvbs.h b/drivers/gpu/drm/meson/meson_encoder_cvbs.h
index 61d9d183ce7f..26cefb202924 100644
--- a/drivers/gpu/drm/meson/meson_encoder_cvbs.h
+++ b/drivers/gpu/drm/meson/meson_encoder_cvbs.h
@@ -16,7 +16,7 @@

struct meson_cvbs_mode {
struct meson_cvbs_enci_mode *enci;
- struct drm_display_mode mode;
+ const struct drm_display_mode *mode;
};

#define MESON_CVBS_MODES_COUNT 2
diff --git a/include/drm/drm_modes.h b/include/drm/drm_modes.h
index a80ae9639e96..b4a440e2688c 100644
--- a/include/drm/drm_modes.h
+++ b/include/drm/drm_modes.h
@@ -394,6 +394,9 @@ struct drm_display_mode {

};

+extern const struct drm_display_mode drm_mode_480i;
+extern const struct drm_display_mode drm_mode_576i;
+
/**
* DRM_MODE_FMT - printf string for &struct drm_display_mode
*/

--
b4 0.10.0-dev-49460

2022-07-29 16:53:39

by Maxime Ripard

[permalink] [raw]
Subject: [PATCH v1 05/35] drm/connector: Add TV standard property

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 <[email protected]>

diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
index c06d0639d552..d7ff6c644c2f 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->tv_mode_property) {
state->tv.mode = val;
+ } else if (property == config->tv_norm_property) {
+ state->tv.norm = 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->tv_mode_property) {
*val = state->tv.mode;
+ } else if (property == config->tv_norm_property) {
+ *val = state->tv.norm;
} 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 e3142c8142b3..68a4e47f85a9 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -1637,6 +1637,7 @@ EXPORT_SYMBOL(drm_mode_create_tv_margin_properties);
/**
* drm_mode_create_tv_properties - create TV specific connector properties
* @dev: DRM device
+ * @supported_tv_norms: Bitmask of TV norms supported (See DRM_MODE_TV_NORM_*)
* @num_modes: number of different TV formats (modes) supported
* @modes: array of pointers to strings containing name of each format
*
@@ -1649,11 +1650,40 @@ EXPORT_SYMBOL(drm_mode_create_tv_margin_properties);
* 0 on success or a negative error code on failure.
*/
int drm_mode_create_tv_properties(struct drm_device *dev,
+ unsigned int supported_tv_norms,
unsigned int num_modes,
const char * const modes[])
{
+ static const struct drm_prop_enum_list tv_norm_values[] = {
+ { __builtin_ffs(DRM_MODE_TV_NORM_NTSC_443) - 1, "NTSC-443" },
+ { __builtin_ffs(DRM_MODE_TV_NORM_NTSC_J) - 1, "NTSC-J" },
+ { __builtin_ffs(DRM_MODE_TV_NORM_NTSC_M) - 1, "NTSC-M" },
+ { __builtin_ffs(DRM_MODE_TV_NORM_PAL_60) - 1, "PAL-60" },
+ { __builtin_ffs(DRM_MODE_TV_NORM_PAL_B) - 1, "PAL-B" },
+ { __builtin_ffs(DRM_MODE_TV_NORM_PAL_D) - 1, "PAL-D" },
+ { __builtin_ffs(DRM_MODE_TV_NORM_PAL_G) - 1, "PAL-G" },
+ { __builtin_ffs(DRM_MODE_TV_NORM_PAL_H) - 1, "PAL-H" },
+ { __builtin_ffs(DRM_MODE_TV_NORM_PAL_I) - 1, "PAL-I" },
+ { __builtin_ffs(DRM_MODE_TV_NORM_PAL_M) - 1, "PAL-M" },
+ { __builtin_ffs(DRM_MODE_TV_NORM_PAL_N) - 1, "PAL-N" },
+ { __builtin_ffs(DRM_MODE_TV_NORM_PAL_NC) - 1, "PAL-Nc" },
+ { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_60) - 1, "SECAM-60" },
+ { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_B) - 1, "SECAM-B" },
+ { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_D) - 1, "SECAM-D" },
+ { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_G) - 1, "SECAM-G" },
+ { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_K) - 1, "SECAM-K" },
+ { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_K1) - 1, "SECAM-K1" },
+ { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_L) - 1, "SECAM-L" },
+ { __builtin_ffs(DRM_MODE_TV_NORM_HD480I) - 1, "hd480i" },
+ { __builtin_ffs(DRM_MODE_TV_NORM_HD480P) - 1, "hd480p" },
+ { __builtin_ffs(DRM_MODE_TV_NORM_HD576I) - 1, "hd576i" },
+ { __builtin_ffs(DRM_MODE_TV_NORM_HD576P) - 1, "hd576p" },
+ { __builtin_ffs(DRM_MODE_TV_NORM_HD720P) - 1, "hd720p" },
+ { __builtin_ffs(DRM_MODE_TV_NORM_HD1080I) - 1, "hd1080i" },
+ };
struct drm_property *tv_selector;
struct drm_property *tv_subconnector;
+ struct drm_property *tv_norm;
unsigned int i;

if (dev->mode_config.tv_select_subconnector_property)
@@ -1686,6 +1716,13 @@ int drm_mode_create_tv_properties(struct drm_device *dev,
if (drm_mode_create_tv_margin_properties(dev))
goto nomem;

+ tv_norm = drm_property_create_bitmask(dev, 0, "tv norm",
+ tv_norm_values, ARRAY_SIZE(tv_norm_values),
+ supported_tv_norms);
+ if (!tv_norm)
+ goto nomem;
+ dev->mode_config.tv_norm_property = tv_norm;
+
dev->mode_config.tv_mode_property =
drm_property_create(dev, DRM_MODE_PROP_ENUM,
"mode", num_modes);
diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c
index 4a788c1c9058..457529e5d857 100644
--- a/drivers/gpu/drm/vc4/vc4_vec.c
+++ b/drivers/gpu/drm/vc4/vc4_vec.c
@@ -573,7 +573,9 @@ 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(drm, ARRAY_SIZE(tv_mode_names),
+ ret = drm_mode_create_tv_properties(drm,
+ 0,
+ ARRAY_SIZE(tv_mode_names),
tv_mode_names);
if (ret)
return ret;
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 1e9996b33cc8..78275e68ff66 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -143,6 +143,32 @@ enum subpixel_order {

};

+#define DRM_MODE_TV_NORM_NTSC_443 (1 << 0)
+#define DRM_MODE_TV_NORM_NTSC_J (1 << 1)
+#define DRM_MODE_TV_NORM_NTSC_M (1 << 2)
+#define DRM_MODE_TV_NORM_PAL_60 (1 << 3)
+#define DRM_MODE_TV_NORM_PAL_B (1 << 4)
+#define DRM_MODE_TV_NORM_PAL_D (1 << 5)
+#define DRM_MODE_TV_NORM_PAL_G (1 << 6)
+#define DRM_MODE_TV_NORM_PAL_H (1 << 7)
+#define DRM_MODE_TV_NORM_PAL_I (1 << 8)
+#define DRM_MODE_TV_NORM_PAL_M (1 << 9)
+#define DRM_MODE_TV_NORM_PAL_N (1 << 10)
+#define DRM_MODE_TV_NORM_PAL_NC (1 << 11)
+#define DRM_MODE_TV_NORM_SECAM_60 (1 << 12)
+#define DRM_MODE_TV_NORM_SECAM_B (1 << 13)
+#define DRM_MODE_TV_NORM_SECAM_D (1 << 14)
+#define DRM_MODE_TV_NORM_SECAM_G (1 << 15)
+#define DRM_MODE_TV_NORM_SECAM_K (1 << 16)
+#define DRM_MODE_TV_NORM_SECAM_K1 (1 << 17)
+#define DRM_MODE_TV_NORM_SECAM_L (1 << 18)
+#define DRM_MODE_TV_NORM_HD480I (1 << 19)
+#define DRM_MODE_TV_NORM_HD480P (1 << 20)
+#define DRM_MODE_TV_NORM_HD576I (1 << 21)
+#define DRM_MODE_TV_NORM_HD576P (1 << 22)
+#define DRM_MODE_TV_NORM_HD720P (1 << 23)
+#define DRM_MODE_TV_NORM_HD1080I (1 << 24)
+
/**
* struct drm_scrambling: sink's scrambling support.
*/
@@ -687,6 +713,7 @@ struct drm_tv_connector_state {
enum drm_mode_subconnector subconnector;
struct drm_connector_tv_margins margins;
unsigned int mode;
+ unsigned int norm;
unsigned int brightness;
unsigned int contrast;
unsigned int flicker_reduction;
@@ -1779,6 +1806,7 @@ void drm_connector_attach_dp_subconnector_property(struct drm_connector *connect

int drm_mode_create_tv_margin_properties(struct drm_device *dev);
int drm_mode_create_tv_properties(struct drm_device *dev,
+ unsigned int supported_tv_norms,
unsigned int num_modes,
const char * const modes[]);
void drm_connector_attach_tv_margin_properties(struct drm_connector *conn);
diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index 6b5e01295348..d9e79def8b92 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -704,6 +704,12 @@ struct drm_mode_config {
*/
struct drm_property *dp_subconnector_property;

+ /**
+ * @tv_norm_property: Optional TV property to select the TV
+ * standard output on the connector.
+ */
+ struct drm_property *tv_norm_property;
+
/**
* @tv_subconnector_property: Optional TV property to differentiate
* between different TV connector types.

--
b4 0.10.0-dev-49460

2022-07-29 16:54:14

by Maxime Ripard

[permalink] [raw]
Subject: [PATCH v1 03/35] drm/atomic: Add TV subconnector property to get/set_property

The subconnector property was created by drm_mode_create_tv_properties(),
but wasn't exposed to the userspace through the generic
atomic_get/set_property implementation, and wasn't stored in any generic
state structure.

Let's solve this.

Signed-off-by: Maxime Ripard <[email protected]>

diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
index c74c78a28171..c06d0639d552 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -688,6 +688,8 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector,
return -EINVAL;
} else if (property == config->tv_select_subconnector_property) {
state->tv.select_subconnector = val;
+ } else if (property == config->tv_subconnector_property) {
+ state->tv.subconnector = val;
} else if (property == config->tv_left_margin_property) {
state->tv.margins.left = val;
} else if (property == config->tv_right_margin_property) {
@@ -796,6 +798,8 @@ drm_atomic_connector_get_property(struct drm_connector *connector,
*val = connector->dpms;
} else if (property == config->tv_select_subconnector_property) {
*val = state->tv.select_subconnector;
+ } else if (property == config->tv_subconnector_property) {
+ *val = state->tv.subconnector;
} else if (property == config->tv_left_margin_property) {
*val = state->tv.margins.left;
} else if (property == config->tv_right_margin_property) {
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index f8091edf9a33..1e9996b33cc8 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -672,6 +672,7 @@ struct drm_connector_tv_margins {
/**
* struct drm_tv_connector_state - TV connector related states
* @select_subconnector: selected subconnector
+ * @subconnector: detected subconnector
* @margins: TV margins
* @mode: TV mode
* @brightness: brightness in percent
@@ -683,6 +684,7 @@ struct drm_connector_tv_margins {
*/
struct drm_tv_connector_state {
enum drm_mode_subconnector select_subconnector;
+ enum drm_mode_subconnector subconnector;
struct drm_connector_tv_margins margins;
unsigned int mode;
unsigned int brightness;

--
b4 0.10.0-dev-49460

2022-07-29 16:55:09

by Maxime Ripard

[permalink] [raw]
Subject: [PATCH v1 15/35] drm/vc4: vec: Remove empty mode_fixup

The mode_fixup hooks are deprecated, and the behaviour we implement is the
default one anyway. Let's remove it.

Signed-off-by: Maxime Ripard <[email protected]>

diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c
index 457529e5d857..17a6afac61cd 100644
--- a/drivers/gpu/drm/vc4/vc4_vec.c
+++ b/drivers/gpu/drm/vc4/vc4_vec.c
@@ -483,14 +483,6 @@ static void vc4_vec_encoder_enable(struct drm_encoder *encoder)
drm_dev_exit(idx);
}

-
-static bool vc4_vec_encoder_mode_fixup(struct drm_encoder *encoder,
- const struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
-{
- return true;
-}
-
static void vc4_vec_encoder_atomic_mode_set(struct drm_encoder *encoder,
struct drm_crtc_state *crtc_state,
struct drm_connector_state *conn_state)
@@ -518,7 +510,6 @@ static int vc4_vec_encoder_atomic_check(struct drm_encoder *encoder,
static const struct drm_encoder_helper_funcs vc4_vec_encoder_helper_funcs = {
.disable = vc4_vec_encoder_disable,
.enable = vc4_vec_encoder_enable,
- .mode_fixup = vc4_vec_encoder_mode_fixup,
.atomic_check = vc4_vec_encoder_atomic_check,
.atomic_mode_set = vc4_vec_encoder_atomic_mode_set,
};

--
b4 0.10.0-dev-49460

2022-07-29 16:55:37

by Maxime Ripard

[permalink] [raw]
Subject: [PATCH v1 14/35] drm/atomic-helper: Add an analog TV atomic_check implementation

The analog TV connector drivers share some atomic_check logic, and the new
TV standard property have created a bunch of new constraints that needs to
be shared across drivers too.

Let's create an atomic_check helper for those use cases.

Signed-off-by: Maxime Ripard <[email protected]>

diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
index 6d14cb0c64b1..fce5569bd66a 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -552,6 +552,93 @@ void drm_atomic_helper_connector_tv_reset(struct drm_connector *connector)
}
EXPORT_SYMBOL(drm_atomic_helper_connector_tv_reset);

+/**
+ * @drm_atomic_helper_connector_tv_check: Validate an analog TV connector state
+ * @connector: DRM Connector
+ * @state: the DRM State object
+ *
+ * Checks the state object to see if the requested state is valid for an
+ * analog TV connector.
+ *
+ * Returns:
+ * Zero for success, a negative error code on error.
+ */
+int drm_atomic_helper_connector_tv_check(struct drm_connector *connector,
+ struct drm_atomic_state *state)
+{
+ struct drm_connector_state *old_conn_state =
+ drm_atomic_get_old_connector_state(state, connector);
+ struct drm_connector_state *new_conn_state =
+ drm_atomic_get_new_connector_state(state, connector);
+ const struct drm_display_mode *mode;
+ struct drm_crtc_state *crtc_state;
+ struct drm_crtc *crtc;
+
+ crtc = new_conn_state->crtc;
+ if (!crtc)
+ return 0;
+
+ crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
+ if (!crtc_state)
+ return -EINVAL;
+
+ switch (new_conn_state->tv.norm) {
+ case DRM_MODE_TV_NORM_NTSC_443:
+ fallthrough;
+ case DRM_MODE_TV_NORM_NTSC_J:
+ fallthrough;
+ case DRM_MODE_TV_NORM_NTSC_M:
+ fallthrough;
+ case DRM_MODE_TV_NORM_PAL_M:
+ mode = &drm_mode_480i;
+ break;
+
+ case DRM_MODE_TV_NORM_PAL_60:
+ fallthrough;
+ case DRM_MODE_TV_NORM_PAL_B:
+ fallthrough;
+ case DRM_MODE_TV_NORM_PAL_D:
+ fallthrough;
+ case DRM_MODE_TV_NORM_PAL_G:
+ fallthrough;
+ case DRM_MODE_TV_NORM_PAL_H:
+ fallthrough;
+ case DRM_MODE_TV_NORM_PAL_I:
+ fallthrough;
+ case DRM_MODE_TV_NORM_PAL_N:
+ fallthrough;
+ case DRM_MODE_TV_NORM_PAL_NC:
+ fallthrough;
+ case DRM_MODE_TV_NORM_SECAM_60:
+ fallthrough;
+ case DRM_MODE_TV_NORM_SECAM_B:
+ fallthrough;
+ case DRM_MODE_TV_NORM_SECAM_D:
+ fallthrough;
+ case DRM_MODE_TV_NORM_SECAM_G:
+ fallthrough;
+ case DRM_MODE_TV_NORM_SECAM_K:
+ fallthrough;
+ case DRM_MODE_TV_NORM_SECAM_K1:
+ fallthrough;
+ case DRM_MODE_TV_NORM_SECAM_L:
+ mode = &drm_mode_576i;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ if (!drm_mode_equal(mode, &crtc_state->mode))
+ return -EINVAL;
+
+ if (old_conn_state->tv.norm != new_conn_state->tv.norm)
+ crtc_state->mode_changed = true;
+
+ return 0;
+}
+EXPORT_SYMBOL(drm_atomic_helper_connector_tv_check);
+
/**
* __drm_atomic_helper_connector_duplicate_state - copy atomic connector state
* @connector: connector object
diff --git a/include/drm/drm_atomic_state_helper.h b/include/drm/drm_atomic_state_helper.h
index c8fbce795ee7..b9740edb2658 100644
--- a/include/drm/drm_atomic_state_helper.h
+++ b/include/drm/drm_atomic_state_helper.h
@@ -26,6 +26,7 @@

#include <linux/types.h>

+struct drm_atomic_state;
struct drm_bridge;
struct drm_bridge_state;
struct drm_crtc;
@@ -71,6 +72,8 @@ void __drm_atomic_helper_connector_reset(struct drm_connector *connector,
struct drm_connector_state *conn_state);
void drm_atomic_helper_connector_reset(struct drm_connector *connector);
void drm_atomic_helper_connector_tv_reset(struct drm_connector *connector);
+int drm_atomic_helper_connector_tv_check(struct drm_connector *connector,
+ struct drm_atomic_state *state);
void drm_atomic_helper_connector_tv_margins_reset(struct drm_connector *connector);
void
__drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector,

--
b4 0.10.0-dev-49460

2022-07-29 17:04:23

by Maxime Ripard

[permalink] [raw]
Subject: [PATCH v1 27/35] drm/sun4i: tv: Merge mode_set into atomic_enable

Our mode_set implementation can be merged into our atomic_enable
implementation to simplify things, so let's do this.

Signed-off-by: Maxime Ripard <[email protected]>

diff --git a/drivers/gpu/drm/sun4i/sun4i_tv.c b/drivers/gpu/drm/sun4i/sun4i_tv.c
index f7aad995ab5b..3944da9a3c34 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tv.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tv.c
@@ -359,23 +359,13 @@ static void sun4i_tv_enable(struct drm_encoder *encoder,
{
struct sun4i_tv *tv = drm_encoder_to_sun4i_tv(encoder);
struct sun4i_crtc *crtc = drm_crtc_to_sun4i_crtc(encoder->crtc);
-
- DRM_DEBUG_DRIVER("Enabling the TV Output\n");
-
- sunxi_engine_apply_color_correction(crtc->engine);
-
- regmap_update_bits(tv->regs, SUN4I_TVE_EN_REG,
- SUN4I_TVE_EN_ENABLE,
- SUN4I_TVE_EN_ENABLE);
-}
-
-static void sun4i_tv_mode_set(struct drm_encoder *encoder,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
-{
- struct sun4i_tv *tv = drm_encoder_to_sun4i_tv(encoder);
+ struct drm_crtc_state *crtc_state =
+ drm_atomic_get_new_crtc_state(state, encoder->crtc);
+ struct drm_display_mode *mode = &crtc_state->mode;
const struct tv_mode *tv_mode = sun4i_tv_find_tv_by_mode(mode);

+ DRM_DEBUG_DRIVER("Enabling the TV Output\n");
+
/* Enable and map the DAC to the output */
regmap_update_bits(tv->regs, SUN4I_TVE_EN_REG,
SUN4I_TVE_EN_DAC_MAP_MASK,
@@ -468,12 +458,17 @@ static void sun4i_tv_mode_set(struct drm_encoder *encoder,
SUN4I_TVE_RESYNC_FIELD : 0));

regmap_write(tv->regs, SUN4I_TVE_SLAVE_REG, 0);
+
+ sunxi_engine_apply_color_correction(crtc->engine);
+
+ regmap_update_bits(tv->regs, SUN4I_TVE_EN_REG,
+ SUN4I_TVE_EN_ENABLE,
+ SUN4I_TVE_EN_ENABLE);
}

static const struct drm_encoder_helper_funcs sun4i_tv_helper_funcs = {
.atomic_disable = sun4i_tv_disable,
.atomic_enable = sun4i_tv_enable,
- .mode_set = sun4i_tv_mode_set,
};

static int sun4i_tv_comp_get_modes(struct drm_connector *connector)

--
b4 0.10.0-dev-49460

2022-07-29 17:07:21

by Maxime Ripard

[permalink] [raw]
Subject: [PATCH v1 02/35] drm/connector: Rename subconnector state variable

There is two TV subconnector related properties registered by
drm_mode_create_tv_properties(): subconnector and select subconnector.

While the select subconnector property is stored in the kernel by the
drm_tv_connector_state structure, the subconnector property isn't stored
anywhere.

Worse, the select subconnector property is stored in a field called
subconnector, creating some ambiguity about which property content we're
accessing.

Let's rename that field to one called select_subconnector to make it move
obvious what it's about.

Signed-off-by: Maxime Ripard <[email protected]>

diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
index 79730fa1dd8e..c74c78a28171 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -687,7 +687,7 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector,
*/
return -EINVAL;
} else if (property == config->tv_select_subconnector_property) {
- state->tv.subconnector = val;
+ state->tv.select_subconnector = val;
} else if (property == config->tv_left_margin_property) {
state->tv.margins.left = val;
} else if (property == config->tv_right_margin_property) {
@@ -795,7 +795,7 @@ drm_atomic_connector_get_property(struct drm_connector *connector,
else
*val = connector->dpms;
} else if (property == config->tv_select_subconnector_property) {
- *val = state->tv.subconnector;
+ *val = state->tv.select_subconnector;
} else if (property == config->tv_left_margin_property) {
*val = state->tv.margins.left;
} else if (property == config->tv_right_margin_property) {
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index f185ad862cb1..f8091edf9a33 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -682,7 +682,7 @@ struct drm_connector_tv_margins {
* @hue: hue in percent
*/
struct drm_tv_connector_state {
- enum drm_mode_subconnector subconnector;
+ enum drm_mode_subconnector select_subconnector;
struct drm_connector_tv_margins margins;
unsigned int mode;
unsigned int brightness;

--
b4 0.10.0-dev-49460

2022-07-29 17:07:22

by Maxime Ripard

[permalink] [raw]
Subject: [PATCH v1 24/35] drm/vc4: vec: Add support for more analog TV standards

From: Mateusz Kwiatkowski <[email protected]>

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.

Signed-off-by: Mateusz Kwiatkowski <[email protected]>
Signed-off-by: Maxime Ripard <[email protected]>

diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c
index e40b55de1b3c..91d343238b0f 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

@@ -194,9 +224,13 @@ connector_to_vc4_vec(struct drm_connector *connector)

enum vc4_vec_tv_mode_id {
VC4_VEC_TV_MODE_NTSC,
+ VC4_VEC_TV_MODE_NTSC_443,
VC4_VEC_TV_MODE_NTSC_J,
VC4_VEC_TV_MODE_PAL,
+ VC4_VEC_TV_MODE_PAL_60,
VC4_VEC_TV_MODE_PAL_M,
+ VC4_VEC_TV_MODE_PAL_N,
+ VC4_VEC_TV_MODE_SECAM,
};

struct vc4_vec_tv_mode {
@@ -234,6 +268,12 @@ static const struct debugfs_reg32 vec_regs[] = {
};

static const struct vc4_vec_tv_mode vc4_vec_tv_modes[] = {
+ {
+ .mode = DRM_MODE_TV_NORM_NTSC_443,
+ .config0 = VEC_CONFIG0_NTSC_STD,
+ .config1 = VEC_CONFIG1_C_CVBS_CVBS | VEC_CONFIG1_CUSTOM_FREQ,
+ .custom_freq = 0x2a098acb,
+ },
{
.mode = DRM_MODE_TV_NORM_NTSC_M,
.config0 = VEC_CONFIG0_NTSC_STD | VEC_CONFIG0_PDEN,
@@ -244,6 +284,12 @@ static const struct vc4_vec_tv_mode vc4_vec_tv_modes[] = {
.config0 = VEC_CONFIG0_NTSC_STD,
.config1 = VEC_CONFIG1_C_CVBS_CVBS,
},
+ {
+ .mode = DRM_MODE_TV_NORM_PAL_60,
+ .config0 = VEC_CONFIG0_PAL_M_STD,
+ .config1 = VEC_CONFIG1_C_CVBS_CVBS | VEC_CONFIG1_CUSTOM_FREQ,
+ .custom_freq = 0x2a098acb,
+ },
{
.mode = DRM_MODE_TV_NORM_PAL_B,
.config0 = VEC_CONFIG0_PAL_BDGHI_STD,
@@ -254,6 +300,17 @@ static const struct vc4_vec_tv_mode vc4_vec_tv_modes[] = {
.config0 = VEC_CONFIG0_PAL_M_STD,
.config1 = VEC_CONFIG1_C_CVBS_CVBS,
},
+ {
+ .mode = DRM_MODE_TV_NORM_PAL_N,
+ .config0 = VEC_CONFIG0_PAL_N_STD,
+ .config1 = VEC_CONFIG1_C_CVBS_CVBS,
+ },
+ {
+ .mode = DRM_MODE_TV_NORM_SECAM_B,
+ .config0 = VEC_CONFIG0_SECAM_STD,
+ .config1 = VEC_CONFIG1_C_CVBS_CVBS,
+ .custom_freq = 0x29c71c72,
+ },
};

static inline const struct vc4_vec_tv_mode *
@@ -273,9 +330,13 @@ vc4_vec_tv_mode_lookup(unsigned int mode)

static const struct drm_prop_enum_list 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
@@ -329,6 +390,10 @@ vc4_vec_connector_set_property(struct drm_connector *connector,
state->tv.norm = DRM_MODE_TV_NORM_NTSC_M;
break;

+ case VC4_VEC_TV_MODE_NTSC_443:
+ state->tv.norm = DRM_MODE_TV_NORM_NTSC_443;
+ break;
+
case VC4_VEC_TV_MODE_NTSC_J:
state->tv.norm = DRM_MODE_TV_NORM_NTSC_J;
break;
@@ -337,10 +402,22 @@ vc4_vec_connector_set_property(struct drm_connector *connector,
state->tv.norm = DRM_MODE_TV_NORM_PAL_B;
break;

+ case VC4_VEC_TV_MODE_PAL_60:
+ state->tv.norm = DRM_MODE_TV_NORM_PAL_60;
+ break;
+
case VC4_VEC_TV_MODE_PAL_M:
state->tv.norm = DRM_MODE_TV_NORM_PAL_M;
break;

+ case VC4_VEC_TV_MODE_PAL_N:
+ state->tv.norm = DRM_MODE_TV_NORM_PAL_N;
+ break;
+
+ case VC4_VEC_TV_MODE_SECAM:
+ state->tv.norm = DRM_MODE_TV_NORM_SECAM_B;
+ break;
+
default:
return -EINVAL;
}
@@ -360,6 +437,10 @@ vc4_vec_connector_get_property(struct drm_connector *connector,
return -EINVAL;

switch (state->tv.norm) {
+ case DRM_MODE_TV_NORM_NTSC_443:
+ *val = VC4_VEC_TV_MODE_NTSC_443;
+ break;
+
case DRM_MODE_TV_NORM_NTSC_J:
*val = VC4_VEC_TV_MODE_NTSC_J;
break;
@@ -368,6 +449,10 @@ vc4_vec_connector_get_property(struct drm_connector *connector,
*val = VC4_VEC_TV_MODE_NTSC;
break;

+ case DRM_MODE_TV_NORM_PAL_60:
+ *val = VC4_VEC_TV_MODE_PAL_60;
+ break;
+
case DRM_MODE_TV_NORM_PAL_B:
*val = VC4_VEC_TV_MODE_PAL;
break;
@@ -376,6 +461,14 @@ vc4_vec_connector_get_property(struct drm_connector *connector,
*val = VC4_VEC_TV_MODE_PAL_M;
break;

+ case DRM_MODE_TV_NORM_PAL_N:
+ *val = VC4_VEC_TV_MODE_PAL_N;
+ break;
+
+ case DRM_MODE_TV_NORM_SECAM_B:
+ *val = VC4_VEC_TV_MODE_SECAM;
+ break;
+
default:
return -EINVAL;
}
@@ -605,10 +698,13 @@ static int vc4_vec_bind(struct device *dev, struct device *master, void *data)
int ret;

ret = drm_mode_create_tv_properties(drm,
+ DRM_MODE_TV_NORM_NTSC_443 |
DRM_MODE_TV_NORM_NTSC_J |
DRM_MODE_TV_NORM_NTSC_M |
DRM_MODE_TV_NORM_PAL_B |
- DRM_MODE_TV_NORM_PAL_M,
+ DRM_MODE_TV_NORM_PAL_M |
+ DRM_MODE_TV_NORM_PAL_N |
+ DRM_MODE_TV_NORM_SECAM_B,
0, NULL);
if (ret)
return ret;

--
b4 0.10.0-dev-49460

2022-07-29 17:09:53

by Maxime Ripard

[permalink] [raw]
Subject: [PATCH v1 11/35] drm/modes: Fill drm_cmdline mode from named modes

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.

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 <[email protected]>

diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index 1421e5da49e0..78ea520f2822 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -1770,11 +1770,12 @@ static int drm_mode_parse_cmdline_options(const char *str,

struct drm_named_mode {
const char *name;
+ const struct drm_display_mode *mode;
};

static const struct drm_named_mode drm_named_modes[] = {
- { "NTSC", },
- { "PAL", },
+ { "NTSC", &drm_mode_480i, },
+ { "PAL", &drm_mode_576i, },
};

static bool drm_mode_parse_cmdline_named_mode(const char *name,
@@ -1792,6 +1793,9 @@ static bool drm_mode_parse_cmdline_named_mode(const char *name,
continue;

strcpy(cmdline_mode->name, mode->name);
+ cmdline_mode->xres = mode->mode->hdisplay;
+ cmdline_mode->yres = mode->mode->vdisplay;
+ cmdline_mode->interlace = !!(mode->mode->flags & DRM_MODE_FLAG_INTERLACE);
cmdline_mode->specified = true;

return true;

--
b4 0.10.0-dev-49460

2022-07-29 17:10:00

by Maxime Ripard

[permalink] [raw]
Subject: [PATCH v1 23/35] drm/vc4: vec: Convert to the new TV mode property

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 <[email protected]>

diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c
index 6f4536bf537f..e40b55de1b3c 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 *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;
@@ -226,28 +234,50 @@ static const struct debugfs_reg32 vec_regs[] = {
};

static const struct vc4_vec_tv_mode vc4_vec_tv_modes[] = {
- [VC4_VEC_TV_MODE_NTSC] = {
- .mode = &drm_mode_480i,
+ {
+ .mode = DRM_MODE_TV_NORM_NTSC_M,
.config0 = VEC_CONFIG0_NTSC_STD | VEC_CONFIG0_PDEN,
.config1 = VEC_CONFIG1_C_CVBS_CVBS,
},
- [VC4_VEC_TV_MODE_NTSC_J] = {
- .mode = &drm_mode_480i,
+ {
+ .mode = DRM_MODE_TV_NORM_NTSC_J,
.config0 = VEC_CONFIG0_NTSC_STD,
.config1 = VEC_CONFIG1_C_CVBS_CVBS,
},
- [VC4_VEC_TV_MODE_PAL] = {
- .mode = &drm_mode_576i,
+ {
+ .mode = DRM_MODE_TV_NORM_PAL_B,
.config0 = VEC_CONFIG0_PAL_BDGHI_STD,
.config1 = VEC_CONFIG1_C_CVBS_CVBS,
},
- [VC4_VEC_TV_MODE_PAL_M] = {
- .mode = &drm_mode_480i,
+ {
+ .mode = DRM_MODE_TV_NORM_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)
{
@@ -262,11 +292,17 @@ 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;

- mode = drm_mode_duplicate(connector->dev,
- vc4_vec_tv_modes[state->tv.mode].mode);
+ mode = drm_mode_duplicate(connector->dev, &drm_mode_480i);
+ if (!mode) {
+ DRM_ERROR("Failed to create a new display mode\n");
+ return -ENOMEM;
+ }
+
+ drm_mode_probed_add(connector, mode);
+
+ mode = drm_mode_duplicate(connector->dev, &drm_mode_576i);
if (!mode) {
DRM_ERROR("Failed to create a new display mode\n");
return -ENOMEM;
@@ -277,21 +313,95 @@ static int vc4_vec_connector_get_modes(struct drm_connector *connector)
return 1;
}

+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->tv_mode_property)
+ return -EINVAL;
+
+ switch (val) {
+ case VC4_VEC_TV_MODE_NTSC:
+ state->tv.norm = DRM_MODE_TV_NORM_NTSC_M;
+ break;
+
+ case VC4_VEC_TV_MODE_NTSC_J:
+ state->tv.norm = DRM_MODE_TV_NORM_NTSC_J;
+ break;
+
+ case VC4_VEC_TV_MODE_PAL:
+ state->tv.norm = DRM_MODE_TV_NORM_PAL_B;
+ break;
+
+ case VC4_VEC_TV_MODE_PAL_M:
+ state->tv.norm = DRM_MODE_TV_NORM_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->tv_mode_property)
+ return -EINVAL;
+
+ switch (state->tv.norm) {
+ case DRM_MODE_TV_NORM_NTSC_J:
+ *val = VC4_VEC_TV_MODE_NTSC_J;
+ break;
+
+ case DRM_MODE_TV_NORM_NTSC_M:
+ *val = VC4_VEC_TV_MODE_NTSC;
+ break;
+
+ case DRM_MODE_TV_NORM_PAL_B:
+ *val = VC4_VEC_TV_MODE_PAL;
+ break;
+
+ case DRM_MODE_TV_NORM_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 = {
.detect = vc4_vec_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.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;
@@ -304,8 +414,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.tv_mode_property,
- VC4_VEC_TV_MODE_NTSC);
+ dev->mode_config.tv_norm_property,
+ DRM_MODE_TV_NORM_NTSC_M);
+
+ prop = drm_property_create_enum(dev, 0, "mode",
+ tv_mode_names, ARRAY_SIZE(tv_mode_names));
+ if (!prop)
+ return -ENOMEM;
+ vec->tv_mode_property = prop;
+
+ drm_object_attach_property(&connector->base, prop, VC4_VEC_TV_MODE_NTSC);

drm_connector_attach_encoder(connector, &vec->encoder.base);

@@ -352,13 +470,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.norm);
+ 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);
@@ -435,23 +556,7 @@ static void vc4_vec_encoder_enable(struct drm_encoder *encoder,
drm_dev_exit(idx);
}

-static int vc4_vec_encoder_atomic_check(struct drm_encoder *encoder,
- struct drm_crtc_state *crtc_state,
- struct drm_connector_state *conn_state)
-{
- const struct vc4_vec_tv_mode *vec_mode;
-
- vec_mode = &vc4_vec_tv_modes[conn_state->tv.mode];
-
- if (conn_state->crtc &&
- !drm_mode_equal(vec_mode->mode, &crtc_state->adjusted_mode))
- return -EINVAL;
-
- return 0;
-}
-
static const struct drm_encoder_helper_funcs vc4_vec_encoder_helper_funcs = {
- .atomic_check = vc4_vec_encoder_atomic_check,
.atomic_disable = vc4_vec_encoder_disable,
.atomic_enable = vc4_vec_encoder_enable,
};
@@ -492,13 +597,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);
@@ -507,9 +605,11 @@ static int vc4_vec_bind(struct device *dev, struct device *master, void *data)
int ret;

ret = drm_mode_create_tv_properties(drm,
- 0,
- ARRAY_SIZE(tv_mode_names),
- tv_mode_names);
+ DRM_MODE_TV_NORM_NTSC_J |
+ DRM_MODE_TV_NORM_NTSC_M |
+ DRM_MODE_TV_NORM_PAL_B |
+ DRM_MODE_TV_NORM_PAL_M,
+ 0, NULL);
if (ret)
return ret;


--
b4 0.10.0-dev-49460

2022-07-29 17:10:51

by Maxime Ripard

[permalink] [raw]
Subject: [PATCH v1 29/35] drm/sun4i: tv: Remove useless destroy function

Our destroy implementation is just calling the generic helper, so let's
just remove our function and directly use the helper.

Signed-off-by: Maxime Ripard <[email protected]>

diff --git a/drivers/gpu/drm/sun4i/sun4i_tv.c b/drivers/gpu/drm/sun4i/sun4i_tv.c
index 52bbba8f19dc..6d7e1d51569a 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tv.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tv.c
@@ -491,15 +491,9 @@ static const struct drm_connector_helper_funcs sun4i_tv_comp_connector_helper_fu
.get_modes = sun4i_tv_comp_get_modes,
};

-static void
-sun4i_tv_comp_connector_destroy(struct drm_connector *connector)
-{
- drm_connector_cleanup(connector);
-}
-
static const struct drm_connector_funcs sun4i_tv_comp_connector_funcs = {
.fill_modes = drm_helper_probe_single_connector_modes,
- .destroy = sun4i_tv_comp_connector_destroy,
+ .destroy = drm_connector_cleanup,
.reset = drm_atomic_helper_connector_reset,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,

--
b4 0.10.0-dev-49460

2022-07-29 17:10:51

by Maxime Ripard

[permalink] [raw]
Subject: [PATCH v1 18/35] drm/vc4: vec: Remove redundant atomic_mode_set

From: Mateusz Kwiatkowski <[email protected]>

Let's remove the superfluous tv_mode field, which was redundant with the
mode field in struct drm_tv_connector_state.

Signed-off-by: Mateusz Kwiatkowski <[email protected]>
Signed-off-by: Maxime Ripard <[email protected]>

diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c
index 02cef4134f2f..a9fefd92f0f1 100644
--- a/drivers/gpu/drm/vc4/vc4_vec.c
+++ b/drivers/gpu/drm/vc4/vc4_vec.c
@@ -171,8 +171,6 @@ struct vc4_vec {

struct clk *clock;

- const struct vc4_vec_tv_mode *tv_mode;
-
struct debugfs_regset32 regset;
};

@@ -316,7 +314,6 @@ static int vc4_vec_connector_init(struct drm_device *dev, struct vc4_vec *vec)
drm_object_attach_property(&connector->base,
dev->mode_config.tv_mode_property,
VC4_VEC_TV_MODE_NTSC);
- vec->tv_mode = &vc4_vec_tv_modes[VC4_VEC_TV_MODE_NTSC];

drm_connector_attach_encoder(connector, &vec->encoder.base);

@@ -360,6 +357,11 @@ static void vc4_vec_encoder_enable(struct drm_encoder *encoder,
{
struct drm_device *drm = encoder->dev;
struct vc4_vec *vec = encoder_to_vc4_vec(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];
int idx, ret;

if (!drm_dev_enter(drm, &idx))
@@ -418,15 +420,14 @@ static void vc4_vec_encoder_enable(struct drm_encoder *encoder,
/* Mask all interrupts. */
VEC_WRITE(VEC_MASK0, 0);

- VEC_WRITE(VEC_CONFIG0, vec->tv_mode->config0);
- VEC_WRITE(VEC_CONFIG1, vec->tv_mode->config1);
+ VEC_WRITE(VEC_CONFIG0, tv_mode->config0);
+ VEC_WRITE(VEC_CONFIG1, tv_mode->config1);

- if (vec->tv_mode->custom_freq != 0) {
+ if (tv_mode->custom_freq != 0) {
VEC_WRITE(VEC_FREQ3_2,
- (vec->tv_mode->custom_freq >> 16) &
- 0xffff);
+ (tv_mode->custom_freq >> 16) & 0xffff);
VEC_WRITE(VEC_FREQ1_0,
- vec->tv_mode->custom_freq & 0xffff);
+ tv_mode->custom_freq & 0xffff);
}

VEC_WRITE(VEC_DAC_MISC,
@@ -442,15 +443,6 @@ static void vc4_vec_encoder_enable(struct drm_encoder *encoder,
drm_dev_exit(idx);
}

-static void vc4_vec_encoder_atomic_mode_set(struct drm_encoder *encoder,
- struct drm_crtc_state *crtc_state,
- struct drm_connector_state *conn_state)
-{
- struct vc4_vec *vec = encoder_to_vc4_vec(encoder);
-
- vec->tv_mode = &vc4_vec_tv_modes[conn_state->tv.mode];
-}
-
static int vc4_vec_encoder_atomic_check(struct drm_encoder *encoder,
struct drm_crtc_state *crtc_state,
struct drm_connector_state *conn_state)
@@ -470,7 +462,6 @@ static const struct drm_encoder_helper_funcs vc4_vec_encoder_helper_funcs = {
.atomic_check = vc4_vec_encoder_atomic_check,
.atomic_disable = vc4_vec_encoder_disable,
.atomic_enable = vc4_vec_encoder_enable,
- .atomic_mode_set = vc4_vec_encoder_atomic_mode_set,
};

static int vc4_vec_late_register(struct drm_encoder *encoder)

--
b4 0.10.0-dev-49460

2022-07-29 17:11:19

by Maxime Ripard

[permalink] [raw]
Subject: [PATCH v1 07/35] drm/modes: Only consider bpp and refresh before options

Some video= options might have a value that contains a dash. However, the
command line parsing mode considers all dashes as the separator between the
mode and the bpp count.

Let's rework the parsing code a bit to only consider a dash as the bpp
separator if it before a comma, the options separator.

A follow-up patch will add a unit-test for this once such an option is
introduced.

Signed-off-by: Maxime Ripard <[email protected]>

diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index a4c1bd688338..06a006e0b2e3 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -1819,20 +1819,22 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option,

name = mode_option;

+ /* Locate the start of named options */
+ options_ptr = strchr(name, ',');
+ if (options_ptr)
+ options_off = options_ptr - name;
+ else
+ options_off = strlen(name);
+
/* Try to locate the bpp and refresh specifiers, if any */
- bpp_ptr = strchr(name, '-');
+ bpp_ptr = strnchr(name, options_off, '-');
if (bpp_ptr)
bpp_off = bpp_ptr - name;

- refresh_ptr = strchr(name, '@');
+ refresh_ptr = strnchr(name, options_off, '@');
if (refresh_ptr)
refresh_off = refresh_ptr - name;

- /* Locate the start of named options */
- options_ptr = strchr(name, ',');
- if (options_ptr)
- options_off = options_ptr - name;
-
/* Locate the end of the name / resolution, and parse it */
if (bpp_ptr) {
mode_end = bpp_off;

--
b4 0.10.0-dev-49460

2022-07-29 17:11:57

by Maxime Ripard

[permalink] [raw]
Subject: [PATCH v1 28/35] drm/sun4i: tv: Remove useless function

The drm_connector_to_sun4i_tv() function isn't used anywhere in the driver,
so let's remove it.

Signed-off-by: Maxime Ripard <[email protected]>

diff --git a/drivers/gpu/drm/sun4i/sun4i_tv.c b/drivers/gpu/drm/sun4i/sun4i_tv.c
index 3944da9a3c34..52bbba8f19dc 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tv.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tv.c
@@ -275,13 +275,6 @@ drm_encoder_to_sun4i_tv(struct drm_encoder *encoder)
encoder);
}

-static inline struct sun4i_tv *
-drm_connector_to_sun4i_tv(struct drm_connector *connector)
-{
- return container_of(connector, struct sun4i_tv,
- connector);
-}
-
/*
* FIXME: If only the drm_display_mode private field was usable, this
* could go away...

--
b4 0.10.0-dev-49460

2022-07-29 17:12:03

by Maxime Ripard

[permalink] [raw]
Subject: [PATCH v1 31/35] drm/sun4i: tv: Add missing reset assertion

The reset line is deasserted at bind, and asserted if we ever encounter an
error there. However, it's never deasserted in unbind which will lead to a
resource unbalance.

Signed-off-by: Maxime Ripard <[email protected]>

diff --git a/drivers/gpu/drm/sun4i/sun4i_tv.c b/drivers/gpu/drm/sun4i/sun4i_tv.c
index ad6a3739bfa9..74ff5ad6a8b9 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tv.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tv.c
@@ -605,6 +605,7 @@ static void sun4i_tv_unbind(struct device *dev, struct device *master,
drm_connector_cleanup(&tv->connector);
drm_encoder_cleanup(&tv->encoder);
clk_disable_unprepare(tv->clk);
+ reset_control_assert(tv->reset);
}

static const struct component_ops sun4i_tv_ops = {

--
b4 0.10.0-dev-49460

2022-07-29 17:13:07

by Maxime Ripard

[permalink] [raw]
Subject: [PATCH v1 32/35] drm/sun4i: tv: Convert to the new TV mode property

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

Signed-off-by: Maxime Ripard <[email protected]>

diff --git a/drivers/gpu/drm/sun4i/sun4i_tv.c b/drivers/gpu/drm/sun4i/sun4i_tv.c
index 74ff5ad6a8b9..bed52423776e 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tv.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tv.c
@@ -140,23 +140,15 @@ struct resync_parameters {
struct tv_mode {
char *name;

+ unsigned int tv_mode;
+ const struct drm_display_mode *display_mode;
+
u32 mode;
u32 chroma_freq;
u16 back_porch;
u16 front_porch;
- u16 line_number;
u16 vblank_level;

- u32 hdisplay;
- u16 hfront_porch;
- u16 hsync_len;
- u16 hback_porch;
-
- u32 vdisplay;
- u16 vfront_porch;
- u16 vsync_len;
- u16 vback_porch;
-
bool yc_en;
bool dac3_en;
bool dac_bit25_en;
@@ -212,7 +204,8 @@ static const struct resync_parameters pal_resync_parameters = {

static const struct tv_mode tv_modes[] = {
{
- .name = "NTSC",
+ .tv_mode = DRM_MODE_TV_NORM_NTSC_M,
+ .display_mode = &drm_mode_480i,
.mode = SUN4I_TVE_CFG0_RES_480i,
.chroma_freq = 0x21f07c1f,
.yc_en = true,
@@ -221,17 +214,6 @@ static const struct tv_mode tv_modes[] = {

.back_porch = 118,
.front_porch = 32,
- .line_number = 525,
-
- .hdisplay = 720,
- .hfront_porch = 18,
- .hsync_len = 2,
- .hback_porch = 118,
-
- .vdisplay = 480,
- .vfront_porch = 26,
- .vsync_len = 2,
- .vback_porch = 17,

.vblank_level = 240,

@@ -241,23 +223,13 @@ static const struct tv_mode tv_modes[] = {
.resync_params = &ntsc_resync_parameters,
},
{
- .name = "PAL",
+ .tv_mode = DRM_MODE_TV_NORM_PAL_B,
+ .display_mode = &drm_mode_576i,
.mode = SUN4I_TVE_CFG0_RES_576i,
.chroma_freq = 0x2a098acb,

.back_porch = 138,
.front_porch = 24,
- .line_number = 625,
-
- .hdisplay = 720,
- .hfront_porch = 3,
- .hsync_len = 2,
- .hback_porch = 139,
-
- .vdisplay = 576,
- .vfront_porch = 28,
- .vsync_len = 2,
- .vback_porch = 19,

.vblank_level = 252,

@@ -275,63 +247,21 @@ drm_encoder_to_sun4i_tv(struct drm_encoder *encoder)
encoder);
}

-/*
- * FIXME: If only the drm_display_mode private field was usable, this
- * could go away...
- *
- * So far, it doesn't seem to be preserved when the mode is passed by
- * to mode_set for some reason.
- */
-static const struct tv_mode *sun4i_tv_find_tv_by_mode(const struct drm_display_mode *mode)
+static const struct tv_mode *
+sun4i_tv_find_tv_by_mode(unsigned int mode)
{
int i;

- /* First try to identify the mode by name */
for (i = 0; i < ARRAY_SIZE(tv_modes); i++) {
const struct tv_mode *tv_mode = &tv_modes[i];

- DRM_DEBUG_DRIVER("Comparing mode %s vs %s",
- mode->name, tv_mode->name);
-
- if (!strcmp(mode->name, tv_mode->name))
- return tv_mode;
- }
-
- /* Then by number of lines */
- for (i = 0; i < ARRAY_SIZE(tv_modes); i++) {
- const struct tv_mode *tv_mode = &tv_modes[i];
-
- DRM_DEBUG_DRIVER("Comparing mode %s vs %s (X: %d vs %d)",
- mode->name, tv_mode->name,
- mode->vdisplay, tv_mode->vdisplay);
-
- if (mode->vdisplay == tv_mode->vdisplay)
+ if (tv_mode->tv_mode == mode)
return tv_mode;
}

return NULL;
}

-static void sun4i_tv_mode_to_drm_mode(const struct tv_mode *tv_mode,
- struct drm_display_mode *mode)
-{
- DRM_DEBUG_DRIVER("Creating mode %s\n", mode->name);
-
- mode->type = DRM_MODE_TYPE_DRIVER;
- mode->clock = 13500;
- mode->flags = DRM_MODE_FLAG_INTERLACE;
-
- mode->hdisplay = tv_mode->hdisplay;
- mode->hsync_start = mode->hdisplay + tv_mode->hfront_porch;
- mode->hsync_end = mode->hsync_start + tv_mode->hsync_len;
- mode->htotal = mode->hsync_end + tv_mode->hback_porch;
-
- mode->vdisplay = tv_mode->vdisplay;
- mode->vsync_start = mode->vdisplay + tv_mode->vfront_porch;
- mode->vsync_end = mode->vsync_start + tv_mode->vsync_len;
- mode->vtotal = mode->vsync_end + tv_mode->vback_porch;
-}
-
static void sun4i_tv_disable(struct drm_encoder *encoder,
struct drm_atomic_state *state)
{
@@ -355,7 +285,11 @@ static void sun4i_tv_enable(struct drm_encoder *encoder,
struct drm_crtc_state *crtc_state =
drm_atomic_get_new_crtc_state(state, encoder->crtc);
struct drm_display_mode *mode = &crtc_state->mode;
- const struct tv_mode *tv_mode = sun4i_tv_find_tv_by_mode(mode);
+ struct drm_connector *connector = &tv->connector;
+ struct drm_connector_state *conn_state =
+ drm_atomic_get_new_connector_state(state, connector);
+ const struct tv_mode *tv_mode =
+ sun4i_tv_find_tv_by_mode(conn_state->tv.norm);

DRM_DEBUG_DRIVER("Enabling the TV Output\n");

@@ -403,7 +337,7 @@ static void sun4i_tv_enable(struct drm_encoder *encoder,
/* Set the lines setup */
regmap_write(tv->regs, SUN4I_TVE_LINE_REG,
SUN4I_TVE_LINE_FIRST(22) |
- SUN4I_TVE_LINE_NUMBER(tv_mode->line_number));
+ SUN4I_TVE_LINE_NUMBER(mode->vtotal));

regmap_write(tv->regs, SUN4I_TVE_LEVEL_REG,
SUN4I_TVE_LEVEL_BLANK(tv_mode->video_levels->blank) |
@@ -472,15 +406,12 @@ static int sun4i_tv_comp_get_modes(struct drm_connector *connector)
struct drm_display_mode *mode;
const struct tv_mode *tv_mode = &tv_modes[i];

- mode = drm_mode_create(connector->dev);
+ mode = drm_mode_duplicate(connector->dev, tv_mode->display_mode);
if (!mode) {
DRM_ERROR("Failed to create a new display mode\n");
return 0;
}

- strcpy(mode->name, tv_mode->name);
-
- sun4i_tv_mode_to_drm_mode(tv_mode, mode);
drm_mode_probed_add(connector, mode);
}

@@ -488,13 +419,20 @@ static int sun4i_tv_comp_get_modes(struct drm_connector *connector)
}

static const struct drm_connector_helper_funcs sun4i_tv_comp_connector_helper_funcs = {
+ .atomic_check = drm_atomic_helper_connector_tv_check,
.get_modes = sun4i_tv_comp_get_modes,
};

+static void sun4i_tv_connector_reset(struct drm_connector *connector)
+{
+ drm_atomic_helper_connector_reset(connector);
+ drm_atomic_helper_connector_tv_reset(connector);
+}
+
static const struct drm_connector_funcs sun4i_tv_comp_connector_funcs = {
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = drm_connector_cleanup,
- .reset = drm_atomic_helper_connector_reset,
+ .reset = sun4i_tv_connector_reset,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
};
@@ -586,8 +524,17 @@ static int sun4i_tv_bind(struct device *dev, struct device *master,

drm_connector_attach_encoder(&tv->connector, &tv->encoder);

+ ret = drm_mode_create_tv_properties(drm,
+ DRM_MODE_TV_NORM_NTSC_M |
+ DRM_MODE_TV_NORM_PAL_B,
+ 0, NULL);
+ if (ret)
+ goto err_cleanup_connector;
+
return 0;

+err_cleanup_connector:
+ drm_connector_cleanup(&tv->connector);
err_cleanup_encoder:
drm_encoder_cleanup(&tv->encoder);
err_disable_clk:

--
b4 0.10.0-dev-49460

2022-07-29 17:24:55

by Mateusz Kwiatkowski

[permalink] [raw]
Subject: Re: [PATCH v1 14/35] drm/atomic-helper: Add an analog TV atomic_check implementation

Hi Maxime,

I'm pretty sure that PAL-60 and SECAM-60 should be tied to the 480i
mode. Those are non-standard "norms" that use 60 Hz sync (which is
largely synonymous with 480i in the analog TV world) with PAL/SECAM
color encoding.

Best regards,
Mateusz Kwiatkowski

W dniu 29.07.2022 o 18:34, Maxime Ripard pisze:
> The analog TV connector drivers share some atomic_check logic, and the new
> TV standard property have created a bunch of new constraints that needs to
> be shared across drivers too.
>
> Let's create an atomic_check helper for those use cases.
>
> Signed-off-by: Maxime Ripard <[email protected]>
>
> diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
> index 6d14cb0c64b1..fce5569bd66a 100644
> --- a/drivers/gpu/drm/drm_atomic_state_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_state_helper.c
> @@ -552,6 +552,93 @@ void drm_atomic_helper_connector_tv_reset(struct drm_connector *connector)
> }
> EXPORT_SYMBOL(drm_atomic_helper_connector_tv_reset);
>
> +/**
> + * @drm_atomic_helper_connector_tv_check: Validate an analog TV connector state
> + * @connector: DRM Connector
> + * @state: the DRM State object
> + *
> + * Checks the state object to see if the requested state is valid for an
> + * analog TV connector.
> + *
> + * Returns:
> + * Zero for success, a negative error code on error.
> + */
> +int drm_atomic_helper_connector_tv_check(struct drm_connector *connector,
> + struct drm_atomic_state *state)
> +{
> + struct drm_connector_state *old_conn_state =
> + drm_atomic_get_old_connector_state(state, connector);
> + struct drm_connector_state *new_conn_state =
> + drm_atomic_get_new_connector_state(state, connector);
> + const struct drm_display_mode *mode;
> + struct drm_crtc_state *crtc_state;
> + struct drm_crtc *crtc;
> +
> + crtc = new_conn_state->crtc;
> + if (!crtc)
> + return 0;
> +
> + crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
> + if (!crtc_state)
> + return -EINVAL;
> +
> + switch (new_conn_state->tv.norm) {
> + case DRM_MODE_TV_NORM_NTSC_443:
> + fallthrough;
> + case DRM_MODE_TV_NORM_NTSC_J:
> + fallthrough;
> + case DRM_MODE_TV_NORM_NTSC_M:
> + fallthrough;
> + case DRM_MODE_TV_NORM_PAL_M:
> + mode = &drm_mode_480i;
> + break;
> +
> + case DRM_MODE_TV_NORM_PAL_60:
> + fallthrough;
> + case DRM_MODE_TV_NORM_PAL_B:
> + fallthrough;
> + case DRM_MODE_TV_NORM_PAL_D:
> + fallthrough;
> + case DRM_MODE_TV_NORM_PAL_G:
> + fallthrough;
> + case DRM_MODE_TV_NORM_PAL_H:
> + fallthrough;
> + case DRM_MODE_TV_NORM_PAL_I:
> + fallthrough;
> + case DRM_MODE_TV_NORM_PAL_N:
> + fallthrough;
> + case DRM_MODE_TV_NORM_PAL_NC:
> + fallthrough;
> + case DRM_MODE_TV_NORM_SECAM_60:
> + fallthrough;
> + case DRM_MODE_TV_NORM_SECAM_B:
> + fallthrough;
> + case DRM_MODE_TV_NORM_SECAM_D:
> + fallthrough;
> + case DRM_MODE_TV_NORM_SECAM_G:
> + fallthrough;
> + case DRM_MODE_TV_NORM_SECAM_K:
> + fallthrough;
> + case DRM_MODE_TV_NORM_SECAM_K1:
> + fallthrough;
> + case DRM_MODE_TV_NORM_SECAM_L:
> + mode = &drm_mode_576i;
> + break;
> +
> + default:
> + return -EINVAL;
> + }
> +
> + if (!drm_mode_equal(mode, &crtc_state->mode))
> + return -EINVAL;
> +
> + if (old_conn_state->tv.norm != new_conn_state->tv.norm)
> + crtc_state->mode_changed = true;
> +
> + return 0;
> +}
> +EXPORT_SYMBOL(drm_atomic_helper_connector_tv_check);
> +
> /**
> * __drm_atomic_helper_connector_duplicate_state - copy atomic connector state
> * @connector: connector object
> diff --git a/include/drm/drm_atomic_state_helper.h b/include/drm/drm_atomic_state_helper.h
> index c8fbce795ee7..b9740edb2658 100644
> --- a/include/drm/drm_atomic_state_helper.h
> +++ b/include/drm/drm_atomic_state_helper.h
> @@ -26,6 +26,7 @@
>
> #include <linux/types.h>
>
> +struct drm_atomic_state;
> struct drm_bridge;
> struct drm_bridge_state;
> struct drm_crtc;
> @@ -71,6 +72,8 @@ void __drm_atomic_helper_connector_reset(struct drm_connector *connector,
> struct drm_connector_state *conn_state);
> void drm_atomic_helper_connector_reset(struct drm_connector *connector);
> void drm_atomic_helper_connector_tv_reset(struct drm_connector *connector);
> +int drm_atomic_helper_connector_tv_check(struct drm_connector *connector,
> + struct drm_atomic_state *state);
> void drm_atomic_helper_connector_tv_margins_reset(struct drm_connector *connector);
> void
> __drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector,
>

2022-07-29 17:25:50

by Maxime Ripard

[permalink] [raw]
Subject: [PATCH v1 12/35] drmi/modes: Properly generate a drm_display_mode from a named mode

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 <[email protected]>

diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index 78ea520f2822..ecb2e83cf860 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -1967,6 +1967,28 @@ 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;
+
+ mode = drm_mode_duplicate(dev, named_mode->mode);
+ 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
@@ -1984,7 +2006,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);
+ else if (cmd->cvt)
mode = drm_cvt_mode(dev,
cmd->xres, cmd->yres,
cmd->refresh_specified ? cmd->refresh : 60,
diff --git a/drivers/gpu/drm/tests/drm_mode_test.c b/drivers/gpu/drm/tests/drm_mode_test.c
index 0f71519788a7..006b73a61fd4 100644
--- a/drivers/gpu/drm/tests/drm_mode_test.c
+++ b/drivers/gpu/drm/tests/drm_mode_test.c
@@ -34,6 +34,18 @@ static int drm_mode_connector_get_modes(struct drm_connector *connector)
if (ret)
return ret;

+ mode = drm_mode_duplicate(connector->dev, &drm_mode_480i);
+ if (!mode)
+ return -ENOMEM;
+
+ drm_mode_probed_add(connector, mode);
+
+ mode = drm_mode_duplicate(connector->dev, &drm_mode_576i);
+ if (!mode)
+ return -ENOMEM;
+
+ drm_mode_probed_add(connector, mode);
+
return 0;
}

@@ -75,6 +87,9 @@ static int drm_mode_test_init(struct kunit *test)
return ret;
drm_connector_helper_add(&priv->connector, &drm_mode_connector_helper_funcs);

+ priv->connector.interlace_allowed = true;
+ priv->connector.doublescan_allowed = true;
+
return 0;
}

@@ -115,8 +130,62 @@ static void drm_mode_res_1920_1080_60(struct kunit *test)
KUNIT_EXPECT_TRUE(test, drm_mode_equal(expected_mode, mode));
}

+static void drm_mode_named_ntsc(struct kunit *test)
+{
+ struct drm_mode_test_priv *priv = test->priv;
+ struct drm_device *drm = priv->drm;
+ struct drm_connector *connector = &priv->connector;
+ struct drm_cmdline_mode *cmdline_mode = &connector->cmdline_mode;
+ struct drm_display_mode *mode;
+ const char *cmdline = "NTSC";
+ int ret;
+
+ KUNIT_ASSERT_TRUE(test,
+ drm_mode_parse_command_line_for_connector(cmdline,
+ connector,
+ cmdline_mode));
+
+ mutex_lock(&drm->mode_config.mutex);
+ ret = drm_helper_probe_single_connector_modes(connector, 1920, 1080);
+ mutex_unlock(&drm->mode_config.mutex);
+ KUNIT_ASSERT_GT(test, ret, 0);
+
+ mode = drm_connector_pick_cmdline_mode(connector);
+ KUNIT_ASSERT_PTR_NE(test, mode, NULL);
+
+ KUNIT_EXPECT_TRUE(test, drm_mode_equal(&drm_mode_480i, mode));
+}
+
+static void drm_mode_named_pal(struct kunit *test)
+{
+ struct drm_mode_test_priv *priv = test->priv;
+ struct drm_device *drm = priv->drm;
+ struct drm_connector *connector = &priv->connector;
+ struct drm_cmdline_mode *cmdline_mode = &connector->cmdline_mode;
+ struct drm_display_mode *mode;
+ const char *cmdline = "PAL";
+ int ret;
+
+ KUNIT_ASSERT_TRUE(test,
+ drm_mode_parse_command_line_for_connector(cmdline,
+ connector,
+ cmdline_mode));
+
+ mutex_lock(&drm->mode_config.mutex);
+ ret = drm_helper_probe_single_connector_modes(connector, 1920, 1080);
+ mutex_unlock(&drm->mode_config.mutex);
+ KUNIT_ASSERT_GT(test, ret, 0);
+
+ mode = drm_connector_pick_cmdline_mode(connector);
+ KUNIT_ASSERT_PTR_NE(test, mode, NULL);
+
+ KUNIT_EXPECT_TRUE(test, drm_mode_equal(&drm_mode_576i, mode));
+}
+
static struct kunit_case drm_mode_tests[] = {
KUNIT_CASE(drm_mode_res_1920_1080_60),
+ KUNIT_CASE(drm_mode_named_ntsc),
+ KUNIT_CASE(drm_mode_named_pal),
{}
};


--
b4 0.10.0-dev-49460

2022-07-29 17:25:51

by Maxime Ripard

[permalink] [raw]
Subject: [PATCH v1 13/35] drm/atomic-helper: Add a TV properties reset helper

The drm_tv_create_properties() function will create a bunch of properties,
but it's up to each and every driver using that function to properly reset
the state of these properties leading to inconsistent behaviours.

Let's create a helper that will take care of it.

Signed-off-by: Maxime Ripard <[email protected]>

diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
index dfb57217253b..6d14cb0c64b1 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -481,6 +481,77 @@ void drm_atomic_helper_connector_tv_margins_reset(struct drm_connector *connecto
}
EXPORT_SYMBOL(drm_atomic_helper_connector_tv_margins_reset);

+/**
+ * drm_atomic_helper_connector_tv_reset - Resets Analog TV connector properties
+ * @connector: DRM connector
+ *
+ * Resets the analog TV properties attached to a connector
+ */
+void drm_atomic_helper_connector_tv_reset(struct drm_connector *connector)
+{
+ struct drm_device *dev = connector->dev;
+ struct drm_connector_state *state = connector->state;
+ struct drm_property *prop;
+ uint64_t val;
+
+ prop = dev->mode_config.tv_norm_property;
+ if (prop)
+ if (!drm_object_property_get_default_value(&connector->base,
+ prop, &val))
+ state->tv.norm = val;
+
+ prop = dev->mode_config.tv_select_subconnector_property;
+ if (prop)
+ if (!drm_object_property_get_default_value(&connector->base,
+ prop, &val))
+ state->tv.select_subconnector = val;
+
+ prop = dev->mode_config.tv_subconnector_property;
+ if (prop)
+ if (!drm_object_property_get_default_value(&connector->base,
+ prop, &val))
+ state->tv.subconnector = val;
+
+ prop = dev->mode_config.tv_brightness_property;
+ if (prop)
+ if (!drm_object_property_get_default_value(&connector->base,
+ prop, &val))
+ state->tv.brightness = val;
+
+ prop = dev->mode_config.tv_contrast_property;
+ if (prop)
+ if (!drm_object_property_get_default_value(&connector->base,
+ prop, &val))
+ state->tv.contrast = val;
+
+ prop = dev->mode_config.tv_flicker_reduction_property;
+ if (prop)
+ if (!drm_object_property_get_default_value(&connector->base,
+ prop, &val))
+ state->tv.flicker_reduction = val;
+
+ prop = dev->mode_config.tv_overscan_property;
+ if (prop)
+ if (!drm_object_property_get_default_value(&connector->base,
+ prop, &val))
+ state->tv.overscan = val;
+
+ prop = dev->mode_config.tv_saturation_property;
+ if (prop)
+ if (!drm_object_property_get_default_value(&connector->base,
+ prop, &val))
+ state->tv.saturation = val;
+
+ prop = dev->mode_config.tv_hue_property;
+ if (prop)
+ if (!drm_object_property_get_default_value(&connector->base,
+ prop, &val))
+ state->tv.hue = val;
+
+ drm_atomic_helper_connector_tv_margins_reset(connector);
+}
+EXPORT_SYMBOL(drm_atomic_helper_connector_tv_reset);
+
/**
* __drm_atomic_helper_connector_duplicate_state - copy atomic connector state
* @connector: connector object
diff --git a/include/drm/drm_atomic_state_helper.h b/include/drm/drm_atomic_state_helper.h
index 192766656b88..c8fbce795ee7 100644
--- a/include/drm/drm_atomic_state_helper.h
+++ b/include/drm/drm_atomic_state_helper.h
@@ -70,6 +70,7 @@ void __drm_atomic_helper_connector_state_reset(struct drm_connector_state *conn_
void __drm_atomic_helper_connector_reset(struct drm_connector *connector,
struct drm_connector_state *conn_state);
void drm_atomic_helper_connector_reset(struct drm_connector *connector);
+void drm_atomic_helper_connector_tv_reset(struct drm_connector *connector);
void drm_atomic_helper_connector_tv_margins_reset(struct drm_connector *connector);
void
__drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector,

--
b4 0.10.0-dev-49460

2022-07-29 18:36:30

by Mateusz Kwiatkowski

[permalink] [raw]
Subject: Re: [PATCH v1 24/35] drm/vc4: vec: Add support for more analog TV standards

Hi Maxime,

I think that declaring PAL-B and SECAM-B as the only supported 576i
norms is a bit random.

Norms B, D, G, H, I, K, K1 and L (for both PAL and SECAM) are
essentially identical if we're talking about baseband signals, AFAIK
they only differ when those are modulated as RF signals. I'm not sure if
there's a point to differentiating those (that's more about patch 05/35)
unless we need to deal with some device that actually features an RF
modulator.

But if we do want to have all those norms separate, then I'd say that
VC4 should declare support for all of those, and all should map to the
same VEC settings. Some users from e.g. the UK might think that they
won't get proper picture if PAL-I is not on the list of supported norms.
Same goes for e.g. SECAM-D/K in the former Soviet territories, and so on.

Best regards,
Mateusz Kwiatkowski

W dniu 29.07.2022 o 18:35, Maxime Ripard pisze:
> From: Mateusz Kwiatkowski <[email protected]>
>
> 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.
>
> Signed-off-by: Mateusz Kwiatkowski <[email protected]>
> Signed-off-by: Maxime Ripard <[email protected]>
>
> diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c
> index e40b55de1b3c..91d343238b0f 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
>
> @@ -194,9 +224,13 @@ connector_to_vc4_vec(struct drm_connector *connector)
>
> enum vc4_vec_tv_mode_id {
> VC4_VEC_TV_MODE_NTSC,
> + VC4_VEC_TV_MODE_NTSC_443,
> VC4_VEC_TV_MODE_NTSC_J,
> VC4_VEC_TV_MODE_PAL,
> + VC4_VEC_TV_MODE_PAL_60,
> VC4_VEC_TV_MODE_PAL_M,
> + VC4_VEC_TV_MODE_PAL_N,
> + VC4_VEC_TV_MODE_SECAM,
> };
>
> struct vc4_vec_tv_mode {
> @@ -234,6 +268,12 @@ static const struct debugfs_reg32 vec_regs[] = {
> };
>
> static const struct vc4_vec_tv_mode vc4_vec_tv_modes[] = {
> + {
> + .mode = DRM_MODE_TV_NORM_NTSC_443,
> + .config0 = VEC_CONFIG0_NTSC_STD,
> + .config1 = VEC_CONFIG1_C_CVBS_CVBS | VEC_CONFIG1_CUSTOM_FREQ,
> + .custom_freq = 0x2a098acb,
> + },
> {
> .mode = DRM_MODE_TV_NORM_NTSC_M,
> .config0 = VEC_CONFIG0_NTSC_STD | VEC_CONFIG0_PDEN,
> @@ -244,6 +284,12 @@ static const struct vc4_vec_tv_mode vc4_vec_tv_modes[] = {
> .config0 = VEC_CONFIG0_NTSC_STD,
> .config1 = VEC_CONFIG1_C_CVBS_CVBS,
> },
> + {
> + .mode = DRM_MODE_TV_NORM_PAL_60,
> + .config0 = VEC_CONFIG0_PAL_M_STD,
> + .config1 = VEC_CONFIG1_C_CVBS_CVBS | VEC_CONFIG1_CUSTOM_FREQ,
> + .custom_freq = 0x2a098acb,
> + },
> {
> .mode = DRM_MODE_TV_NORM_PAL_B,
> .config0 = VEC_CONFIG0_PAL_BDGHI_STD,
> @@ -254,6 +300,17 @@ static const struct vc4_vec_tv_mode vc4_vec_tv_modes[] = {
> .config0 = VEC_CONFIG0_PAL_M_STD,
> .config1 = VEC_CONFIG1_C_CVBS_CVBS,
> },
> + {
> + .mode = DRM_MODE_TV_NORM_PAL_N,
> + .config0 = VEC_CONFIG0_PAL_N_STD,
> + .config1 = VEC_CONFIG1_C_CVBS_CVBS,
> + },
> + {
> + .mode = DRM_MODE_TV_NORM_SECAM_B,
> + .config0 = VEC_CONFIG0_SECAM_STD,
> + .config1 = VEC_CONFIG1_C_CVBS_CVBS,
> + .custom_freq = 0x29c71c72,
> + },
> };
>
> static inline const struct vc4_vec_tv_mode *
> @@ -273,9 +330,13 @@ vc4_vec_tv_mode_lookup(unsigned int mode)
>
> static const struct drm_prop_enum_list 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
> @@ -329,6 +390,10 @@ vc4_vec_connector_set_property(struct drm_connector *connector,
> state->tv.norm = DRM_MODE_TV_NORM_NTSC_M;
> break;
>
> + case VC4_VEC_TV_MODE_NTSC_443:
> + state->tv.norm = DRM_MODE_TV_NORM_NTSC_443;
> + break;
> +
> case VC4_VEC_TV_MODE_NTSC_J:
> state->tv.norm = DRM_MODE_TV_NORM_NTSC_J;
> break;
> @@ -337,10 +402,22 @@ vc4_vec_connector_set_property(struct drm_connector *connector,
> state->tv.norm = DRM_MODE_TV_NORM_PAL_B;
> break;
>
> + case VC4_VEC_TV_MODE_PAL_60:
> + state->tv.norm = DRM_MODE_TV_NORM_PAL_60;
> + break;
> +
> case VC4_VEC_TV_MODE_PAL_M:
> state->tv.norm = DRM_MODE_TV_NORM_PAL_M;
> break;
>
> + case VC4_VEC_TV_MODE_PAL_N:
> + state->tv.norm = DRM_MODE_TV_NORM_PAL_N;
> + break;
> +
> + case VC4_VEC_TV_MODE_SECAM:
> + state->tv.norm = DRM_MODE_TV_NORM_SECAM_B;
> + break;
> +
> default:
> return -EINVAL;
> }
> @@ -360,6 +437,10 @@ vc4_vec_connector_get_property(struct drm_connector *connector,
> return -EINVAL;
>
> switch (state->tv.norm) {
> + case DRM_MODE_TV_NORM_NTSC_443:
> + *val = VC4_VEC_TV_MODE_NTSC_443;
> + break;
> +
> case DRM_MODE_TV_NORM_NTSC_J:
> *val = VC4_VEC_TV_MODE_NTSC_J;
> break;
> @@ -368,6 +449,10 @@ vc4_vec_connector_get_property(struct drm_connector *connector,
> *val = VC4_VEC_TV_MODE_NTSC;
> break;
>
> + case DRM_MODE_TV_NORM_PAL_60:
> + *val = VC4_VEC_TV_MODE_PAL_60;
> + break;
> +
> case DRM_MODE_TV_NORM_PAL_B:
> *val = VC4_VEC_TV_MODE_PAL;
> break;
> @@ -376,6 +461,14 @@ vc4_vec_connector_get_property(struct drm_connector *connector,
> *val = VC4_VEC_TV_MODE_PAL_M;
> break;
>
> + case DRM_MODE_TV_NORM_PAL_N:
> + *val = VC4_VEC_TV_MODE_PAL_N;
> + break;
> +
> + case DRM_MODE_TV_NORM_SECAM_B:
> + *val = VC4_VEC_TV_MODE_SECAM;
> + break;
> +
> default:
> return -EINVAL;
> }
> @@ -605,10 +698,13 @@ static int vc4_vec_bind(struct device *dev, struct device *master, void *data)
> int ret;
>
> ret = drm_mode_create_tv_properties(drm,
> + DRM_MODE_TV_NORM_NTSC_443 |
> DRM_MODE_TV_NORM_NTSC_J |
> DRM_MODE_TV_NORM_NTSC_M |
> DRM_MODE_TV_NORM_PAL_B |
> - DRM_MODE_TV_NORM_PAL_M,
> + DRM_MODE_TV_NORM_PAL_M |
> + DRM_MODE_TV_NORM_PAL_N |
> + DRM_MODE_TV_NORM_SECAM_B,
> 0, NULL);
> if (ret)
> return ret;
>

2022-07-30 09:19:14

by Jernej Škrabec

[permalink] [raw]
Subject: Re: [PATCH v1 29/35] drm/sun4i: tv: Remove useless destroy function

Dne petek, 29. julij 2022 ob 18:35:12 CEST je Maxime Ripard napisal(a):
> Our destroy implementation is just calling the generic helper, so let's
> just remove our function and directly use the helper.
>
> Signed-off-by: Maxime Ripard <[email protected]>

Reviewed-by: Jernej Skrabec <[email protected]>

Best regards,
Jernej

>
> diff --git a/drivers/gpu/drm/sun4i/sun4i_tv.c
> b/drivers/gpu/drm/sun4i/sun4i_tv.c index 52bbba8f19dc..6d7e1d51569a 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_tv.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_tv.c
> @@ -491,15 +491,9 @@ static const struct drm_connector_helper_funcs
> sun4i_tv_comp_connector_helper_fu .get_modes = sun4i_tv_comp_get_modes,
> };
>
> -static void
> -sun4i_tv_comp_connector_destroy(struct drm_connector *connector)
> -{
> - drm_connector_cleanup(connector);
> -}
> -
> static const struct drm_connector_funcs sun4i_tv_comp_connector_funcs = {
> .fill_modes = drm_helper_probe_single_connector_modes,
> - .destroy = sun4i_tv_comp_connector_destroy,
> + .destroy = drm_connector_cleanup,
> .reset =
drm_atomic_helper_connector_reset,
> .atomic_duplicate_state =
drm_atomic_helper_connector_duplicate_state,
> .atomic_destroy_state =
drm_atomic_helper_connector_destroy_state,





2022-07-30 09:20:11

by Jernej Škrabec

[permalink] [raw]
Subject: Re: [PATCH v1 31/35] drm/sun4i: tv: Add missing reset assertion

Dne petek, 29. julij 2022 ob 18:35:14 CEST je Maxime Ripard napisal(a):
> The reset line is deasserted at bind, and asserted if we ever encounter an
> error there. However, it's never deasserted in unbind which will lead to a

s/deasserted/asserted/

Once fixed:
Reviewed-by: Jernej Skrabec <[email protected]>

Best regards,
Jernej

> resource unbalance.
>
> Signed-off-by: Maxime Ripard <[email protected]>
>
> diff --git a/drivers/gpu/drm/sun4i/sun4i_tv.c
> b/drivers/gpu/drm/sun4i/sun4i_tv.c index ad6a3739bfa9..74ff5ad6a8b9 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_tv.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_tv.c
> @@ -605,6 +605,7 @@ static void sun4i_tv_unbind(struct device *dev, struct
> device *master, drm_connector_cleanup(&tv->connector);
> drm_encoder_cleanup(&tv->encoder);
> clk_disable_unprepare(tv->clk);
> + reset_control_assert(tv->reset);
> }
>
> static const struct component_ops sun4i_tv_ops = {





2022-08-02 10:17:36

by Thomas Zimmermann

[permalink] [raw]
Subject: Re: [PATCH v1 08/35] drm/client: Add some tests for drm_connector_pick_cmdline_mode()

Hi Maxime

Am 29.07.22 um 18:34 schrieb Maxime Ripard:
> drm_connector_pick_cmdline_mode() is in charge of finding a proper
> drm_display_mode from the definition we got in the video= command line
> argument.
>
> Let's add some unit tests to make sure we're not getting any regressions
> there.
>
> Signed-off-by: Maxime Ripard <[email protected]>
>
> diff --git a/drivers/gpu/drm/drm_client_modeset.c b/drivers/gpu/drm/drm_client_modeset.c
> index bbc535cc50dd..ee6b8f193c24 100644
> --- a/drivers/gpu/drm/drm_client_modeset.c
> +++ b/drivers/gpu/drm/drm_client_modeset.c
> @@ -1237,3 +1237,7 @@ int drm_client_modeset_dpms(struct drm_client_dev *client, int mode)
> return ret;
> }
> EXPORT_SYMBOL(drm_client_modeset_dpms);
> +
> +#ifdef CONFIG_DRM_KUNIT_TEST
> +#include "tests/drm_mode_test.c"
> +#endif

Including source files is somewhat ugly, prolongs compile times and
could even interfere with the actual source code. Can we do this in some
other way?

I suggest to add the tests here and export them for use in the test
case. Something like

#ifdef CONFIG_DRM_KUNIT_TEST
static drm_mode_res_1920_1080_60()
{
...
}

struct kunit_case drm_mode_tests[] = {
drm_mode_res_1920_1080_60
};
EXPORT_SYMBOL(drm_mode_tests);
#endif

This would add the tests next to the tested code, but leave the test
driver in drm_mode_test.c.

Best regards
Thomas

> diff --git a/drivers/gpu/drm/tests/drm_mode_test.c b/drivers/gpu/drm/tests/drm_mode_test.c
> new file mode 100644
> index 000000000000..0f71519788a7
> --- /dev/null
> +++ b/drivers/gpu/drm/tests/drm_mode_test.c
> @@ -0,0 +1,132 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2022 Maxime Ripard <[email protected]>
> + */
> +
> +#include <drm/drm_mode.h>
> +#include <kunit/test.h>
> +
> +#include <drm/drm_connector.h>
> +#include <drm/drm_edid.h>
> +#include <drm/drm_drv.h>
> +#include <drm/drm_modes.h>
> +#include <drm/drm_modeset_helper_vtables.h>
> +#include <drm/drm_probe_helper.h>
> +
> +struct drm_mode_test_priv {
> + struct device *dev;
> + struct drm_device *drm;
> + struct drm_connector connector;
> +};
> +
> +static const struct drm_mode_config_funcs drm_mode_config_funcs = {
> +};
> +
> +static const struct drm_driver drm_mode_driver = {
> +};
> +
> +static int drm_mode_connector_get_modes(struct drm_connector *connector)
> +{
> + struct drm_display_mode *mode;
> + int ret;
> +
> + ret = drm_add_modes_noedid(connector, 1920, 1200);
> + if (ret)
> + return ret;
> +
> + return 0;
> +}
> +
> +static const struct drm_connector_helper_funcs drm_mode_connector_helper_funcs = {
> + .get_modes = drm_mode_connector_get_modes,
> +};
> +
> +static const struct drm_connector_funcs drm_mode_connector_funcs = {
> +};
> +
> +static int drm_mode_test_init(struct kunit *test)
> +{
> + struct drm_mode_test_priv *priv;
> + int ret;
> +
> + priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);
> + if (!priv)
> + return -ENOMEM;
> + test->priv = priv;
> +
> + priv->dev = root_device_register("drm-mode-test");
> + if (IS_ERR(priv->dev))
> + return PTR_ERR(priv->dev);
> +
> + priv->drm = drm_dev_alloc(&drm_mode_driver, priv->dev);
> + if (IS_ERR(priv->drm))
> + return PTR_ERR(priv->drm);
> + priv->drm->mode_config.funcs = &drm_mode_config_funcs;
> +
> + ret = drmm_mode_config_init(priv->drm);
> + if (ret)
> + return ret;
> +
> + ret = drmm_connector_init(priv->drm, &priv->connector,
> + &drm_mode_connector_funcs,
> + DRM_MODE_CONNECTOR_Unknown,
> + NULL);
> + if (ret)
> + return ret;
> + drm_connector_helper_add(&priv->connector, &drm_mode_connector_helper_funcs);
> +
> + return 0;
> +}
> +
> +static void drm_mode_test_exit(struct kunit *test)
> +{
> + struct drm_mode_test_priv *priv = test->priv;
> +
> + drm_dev_put(priv->drm);
> + root_device_unregister(priv->dev);
> +}
> +
> +static void drm_mode_res_1920_1080_60(struct kunit *test)
> +{
> + struct drm_mode_test_priv *priv = test->priv;
> + struct drm_device *drm = priv->drm;
> + struct drm_connector *connector = &priv->connector;
> + struct drm_cmdline_mode *cmdline_mode = &connector->cmdline_mode;
> + struct drm_display_mode *expected_mode, *mode;
> + const char *cmdline = "1920x1080@60";
> + int ret;
> +
> + expected_mode = drm_mode_find_dmt(priv->drm, 1920, 1080, 60, false);
> + KUNIT_ASSERT_PTR_NE(test, expected_mode, NULL);
> +
> + KUNIT_ASSERT_TRUE(test,
> + drm_mode_parse_command_line_for_connector(cmdline,
> + connector,
> + cmdline_mode));
> +
> + mutex_lock(&drm->mode_config.mutex);
> + ret = drm_helper_probe_single_connector_modes(connector, 1920, 1080);
> + mutex_unlock(&drm->mode_config.mutex);
> + KUNIT_ASSERT_GT(test, ret, 0);
> +
> + mode = drm_connector_pick_cmdline_mode(connector);
> + KUNIT_ASSERT_PTR_NE(test, mode, NULL);
> +
> + KUNIT_EXPECT_TRUE(test, drm_mode_equal(expected_mode, mode));
> +}
> +
> +static struct kunit_case drm_mode_tests[] = {
> + KUNIT_CASE(drm_mode_res_1920_1080_60),
> + {}
> +};
> +
> +static struct kunit_suite drm_mode_test_suite = {
> + .name = "drm_mode",
> + .init = drm_mode_test_init,
> + .exit = drm_mode_test_exit,
> + .test_cases = drm_mode_tests
> +};
> +
> +kunit_test_suite(drm_mode_test_suite);
> +MODULE_AUTHOR("Maxime Ripard <[email protected]>");
> +MODULE_LICENSE("GPL");
>

--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Ivo Totev


Attachments:
OpenPGP_signature (855.00 B)
OpenPGP digital signature

2022-08-02 14:03:52

by Jani Nikula

[permalink] [raw]
Subject: Re: [PATCH v1 04/35] drm/modes: Introduce 480i and 576i modes

On Fri, 29 Jul 2022, Maxime Ripard <[email protected]> wrote:
> Multiple drivers (meson, vc4) define the analog TV 525-lines and 625-lines
> modes in the drivers.
>
> Since those modes are fairly standards, and that we'll need to use them in
> more places in the future, let's move the meson definition into the
> framework.

I think you should always expose interfaces, not data. Data is not an
interface, and I think this sets a bad example that will be cargo
culted.


BR,
Jani.

>
> The meson one was chosen because vc4's isn't accurate and doesn't amount to
> 525 and 625 lines.
>
> Signed-off-by: Maxime Ripard <[email protected]>
>
> diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
> index 304004fb80aa..a4c1bd688338 100644
> --- a/drivers/gpu/drm/drm_modes.c
> +++ b/drivers/gpu/drm/drm_modes.c
> @@ -48,6 +48,24 @@
>
> #include "drm_crtc_internal.h"
>
> +const struct drm_display_mode drm_mode_480i = {
> + DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 13500,
> + 720, 739, 801, 858, 0,
> + 480, 488, 494, 525, 0,
> + DRM_MODE_FLAG_INTERLACE),
> + .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3,
> +};
> +EXPORT_SYMBOL_GPL(drm_mode_480i);
> +
> +const struct drm_display_mode drm_mode_576i = {
> + DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 13500,
> + 720, 732, 795, 864, 0,
> + 576, 580, 586, 625, 0,
> + DRM_MODE_FLAG_INTERLACE),
> + .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3,
> +};
> +EXPORT_SYMBOL_GPL(drm_mode_576i);
> +
> /**
> * drm_mode_debug_printmodeline - print a mode to dmesg
> * @mode: mode to print
> diff --git a/drivers/gpu/drm/meson/meson_encoder_cvbs.c b/drivers/gpu/drm/meson/meson_encoder_cvbs.c
> index 8110a6e39320..98ec3e563155 100644
> --- a/drivers/gpu/drm/meson/meson_encoder_cvbs.c
> +++ b/drivers/gpu/drm/meson/meson_encoder_cvbs.c
> @@ -45,21 +45,11 @@ struct meson_encoder_cvbs {
> struct meson_cvbs_mode meson_cvbs_modes[MESON_CVBS_MODES_COUNT] = {
> { /* PAL */
> .enci = &meson_cvbs_enci_pal,
> - .mode = {
> - DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 13500,
> - 720, 732, 795, 864, 0, 576, 580, 586, 625, 0,
> - DRM_MODE_FLAG_INTERLACE),
> - .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3,
> - },
> + .mode = &drm_mode_576i,
> },
> { /* NTSC */
> .enci = &meson_cvbs_enci_ntsc,
> - .mode = {
> - DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 13500,
> - 720, 739, 801, 858, 0, 480, 488, 494, 525, 0,
> - DRM_MODE_FLAG_INTERLACE),
> - .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3,
> - },
> + .mode = &drm_mode_480i,
> },
> };
>
> @@ -71,7 +61,7 @@ meson_cvbs_get_mode(const struct drm_display_mode *req_mode)
> for (i = 0; i < MESON_CVBS_MODES_COUNT; ++i) {
> struct meson_cvbs_mode *meson_mode = &meson_cvbs_modes[i];
>
> - if (drm_mode_match(req_mode, &meson_mode->mode,
> + if (drm_mode_match(req_mode, meson_mode->mode,
> DRM_MODE_MATCH_TIMINGS |
> DRM_MODE_MATCH_CLOCK |
> DRM_MODE_MATCH_FLAGS |
> @@ -104,7 +94,7 @@ static int meson_encoder_cvbs_get_modes(struct drm_bridge *bridge,
> for (i = 0; i < MESON_CVBS_MODES_COUNT; ++i) {
> struct meson_cvbs_mode *meson_mode = &meson_cvbs_modes[i];
>
> - mode = drm_mode_duplicate(priv->drm, &meson_mode->mode);
> + mode = drm_mode_duplicate(priv->drm, meson_mode->mode);
> if (!mode) {
> dev_err(priv->dev, "Failed to create a new display mode\n");
> return 0;
> diff --git a/drivers/gpu/drm/meson/meson_encoder_cvbs.h b/drivers/gpu/drm/meson/meson_encoder_cvbs.h
> index 61d9d183ce7f..26cefb202924 100644
> --- a/drivers/gpu/drm/meson/meson_encoder_cvbs.h
> +++ b/drivers/gpu/drm/meson/meson_encoder_cvbs.h
> @@ -16,7 +16,7 @@
>
> struct meson_cvbs_mode {
> struct meson_cvbs_enci_mode *enci;
> - struct drm_display_mode mode;
> + const struct drm_display_mode *mode;
> };
>
> #define MESON_CVBS_MODES_COUNT 2
> diff --git a/include/drm/drm_modes.h b/include/drm/drm_modes.h
> index a80ae9639e96..b4a440e2688c 100644
> --- a/include/drm/drm_modes.h
> +++ b/include/drm/drm_modes.h
> @@ -394,6 +394,9 @@ struct drm_display_mode {
>
> };
>
> +extern const struct drm_display_mode drm_mode_480i;
> +extern const struct drm_display_mode drm_mode_576i;
> +
> /**
> * DRM_MODE_FMT - printf string for &struct drm_display_mode
> */

--
Jani Nikula, Intel Open Source Graphics Center

2022-08-02 14:24:04

by Thomas Zimmermann

[permalink] [raw]
Subject: Re: [PATCH v1 04/35] drm/modes: Introduce 480i and 576i modes

Hi

Am 02.08.22 um 15:58 schrieb Jani Nikula:
> On Fri, 29 Jul 2022, Maxime Ripard <[email protected]> wrote:
>> Multiple drivers (meson, vc4) define the analog TV 525-lines and 625-lines
>> modes in the drivers.
>>
>> Since those modes are fairly standards, and that we'll need to use them in
>> more places in the future, let's move the meson definition into the
>> framework.
>
> I think you should always expose interfaces, not data. Data is not an
> interface, and I think this sets a bad example that will be cargo
> culted.

Although I wrote the opposite wrt patch 8, I agree with Jani here when
it comes to 'official' interfaces. The cases I've seen of exported data
structures often lead to intransparent code.

Best regards
Thomas

>
>
> BR,
> Jani.
>
>>
>> The meson one was chosen because vc4's isn't accurate and doesn't amount to
>> 525 and 625 lines.
>>
>> Signed-off-by: Maxime Ripard <[email protected]>
>>
>> diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
>> index 304004fb80aa..a4c1bd688338 100644
>> --- a/drivers/gpu/drm/drm_modes.c
>> +++ b/drivers/gpu/drm/drm_modes.c
>> @@ -48,6 +48,24 @@
>>
>> #include "drm_crtc_internal.h"
>>
>> +const struct drm_display_mode drm_mode_480i = {
>> + DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 13500,
>> + 720, 739, 801, 858, 0,
>> + 480, 488, 494, 525, 0,
>> + DRM_MODE_FLAG_INTERLACE),
>> + .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3,
>> +};
>> +EXPORT_SYMBOL_GPL(drm_mode_480i);
>> +
>> +const struct drm_display_mode drm_mode_576i = {
>> + DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 13500,
>> + 720, 732, 795, 864, 0,
>> + 576, 580, 586, 625, 0,
>> + DRM_MODE_FLAG_INTERLACE),
>> + .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3,
>> +};
>> +EXPORT_SYMBOL_GPL(drm_mode_576i);
>> +
>> /**
>> * drm_mode_debug_printmodeline - print a mode to dmesg
>> * @mode: mode to print
>> diff --git a/drivers/gpu/drm/meson/meson_encoder_cvbs.c b/drivers/gpu/drm/meson/meson_encoder_cvbs.c
>> index 8110a6e39320..98ec3e563155 100644
>> --- a/drivers/gpu/drm/meson/meson_encoder_cvbs.c
>> +++ b/drivers/gpu/drm/meson/meson_encoder_cvbs.c
>> @@ -45,21 +45,11 @@ struct meson_encoder_cvbs {
>> struct meson_cvbs_mode meson_cvbs_modes[MESON_CVBS_MODES_COUNT] = {
>> { /* PAL */
>> .enci = &meson_cvbs_enci_pal,
>> - .mode = {
>> - DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 13500,
>> - 720, 732, 795, 864, 0, 576, 580, 586, 625, 0,
>> - DRM_MODE_FLAG_INTERLACE),
>> - .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3,
>> - },
>> + .mode = &drm_mode_576i,
>> },
>> { /* NTSC */
>> .enci = &meson_cvbs_enci_ntsc,
>> - .mode = {
>> - DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 13500,
>> - 720, 739, 801, 858, 0, 480, 488, 494, 525, 0,
>> - DRM_MODE_FLAG_INTERLACE),
>> - .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3,
>> - },
>> + .mode = &drm_mode_480i,
>> },
>> };
>>
>> @@ -71,7 +61,7 @@ meson_cvbs_get_mode(const struct drm_display_mode *req_mode)
>> for (i = 0; i < MESON_CVBS_MODES_COUNT; ++i) {
>> struct meson_cvbs_mode *meson_mode = &meson_cvbs_modes[i];
>>
>> - if (drm_mode_match(req_mode, &meson_mode->mode,
>> + if (drm_mode_match(req_mode, meson_mode->mode,
>> DRM_MODE_MATCH_TIMINGS |
>> DRM_MODE_MATCH_CLOCK |
>> DRM_MODE_MATCH_FLAGS |
>> @@ -104,7 +94,7 @@ static int meson_encoder_cvbs_get_modes(struct drm_bridge *bridge,
>> for (i = 0; i < MESON_CVBS_MODES_COUNT; ++i) {
>> struct meson_cvbs_mode *meson_mode = &meson_cvbs_modes[i];
>>
>> - mode = drm_mode_duplicate(priv->drm, &meson_mode->mode);
>> + mode = drm_mode_duplicate(priv->drm, meson_mode->mode);
>> if (!mode) {
>> dev_err(priv->dev, "Failed to create a new display mode\n");
>> return 0;
>> diff --git a/drivers/gpu/drm/meson/meson_encoder_cvbs.h b/drivers/gpu/drm/meson/meson_encoder_cvbs.h
>> index 61d9d183ce7f..26cefb202924 100644
>> --- a/drivers/gpu/drm/meson/meson_encoder_cvbs.h
>> +++ b/drivers/gpu/drm/meson/meson_encoder_cvbs.h
>> @@ -16,7 +16,7 @@
>>
>> struct meson_cvbs_mode {
>> struct meson_cvbs_enci_mode *enci;
>> - struct drm_display_mode mode;
>> + const struct drm_display_mode *mode;
>> };
>>
>> #define MESON_CVBS_MODES_COUNT 2
>> diff --git a/include/drm/drm_modes.h b/include/drm/drm_modes.h
>> index a80ae9639e96..b4a440e2688c 100644
>> --- a/include/drm/drm_modes.h
>> +++ b/include/drm/drm_modes.h
>> @@ -394,6 +394,9 @@ struct drm_display_mode {
>>
>> };
>>
>> +extern const struct drm_display_mode drm_mode_480i;
>> +extern const struct drm_display_mode drm_mode_576i;
>> +
>> /**
>> * DRM_MODE_FMT - printf string for &struct drm_display_mode
>> */
>

--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Ivo Totev


Attachments:
OpenPGP_signature (855.00 B)
OpenPGP digital signature

2022-08-08 12:38:32

by Noralf Trønnes

[permalink] [raw]
Subject: Re: [PATCH v1 02/35] drm/connector: Rename subconnector state variable



Den 29.07.2022 18.34, skrev Maxime Ripard:
> There is two TV subconnector related properties registered by
> drm_mode_create_tv_properties(): subconnector and select subconnector.
>
> While the select subconnector property is stored in the kernel by the
> drm_tv_connector_state structure, the subconnector property isn't stored
> anywhere.
>
> Worse, the select subconnector property is stored in a field called
> subconnector, creating some ambiguity about which property content we're
> accessing.
>
> Let's rename that field to one called select_subconnector to make it move
> obvious what it's about.
>
> Signed-off-by: Maxime Ripard <[email protected]>
>

Reviewed-by: Noralf Trønnes <[email protected]>

2022-08-08 12:54:41

by Noralf Trønnes

[permalink] [raw]
Subject: Re: [PATCH v1 05/35] drm/connector: Add TV standard property



Den 29.07.2022 18.34, skrev Maxime Ripard:
> 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 <[email protected]>
>

Please also update Documentation/gpu/kms-properties.csv

Requirements for adding a new property is found in
Documentation/gpu/drm-kms.rst

> diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
> index c06d0639d552..d7ff6c644c2f 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->tv_mode_property) {
> state->tv.mode = val;
> + } else if (property == config->tv_norm_property) {
> + state->tv.norm = 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->tv_mode_property) {
> *val = state->tv.mode;
> + } else if (property == config->tv_norm_property) {
> + *val = state->tv.norm;
> } 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 e3142c8142b3..68a4e47f85a9 100644
> --- a/drivers/gpu/drm/drm_connector.c
> +++ b/drivers/gpu/drm/drm_connector.c
> @@ -1637,6 +1637,7 @@ EXPORT_SYMBOL(drm_mode_create_tv_margin_properties);
> /**
> * drm_mode_create_tv_properties - create TV specific connector properties
> * @dev: DRM device
> + * @supported_tv_norms: Bitmask of TV norms supported (See DRM_MODE_TV_NORM_*)
> * @num_modes: number of different TV formats (modes) supported
> * @modes: array of pointers to strings containing name of each format
> *
> @@ -1649,11 +1650,40 @@ EXPORT_SYMBOL(drm_mode_create_tv_margin_properties);
> * 0 on success or a negative error code on failure.
> */
> int drm_mode_create_tv_properties(struct drm_device *dev,
> + unsigned int supported_tv_norms,
> unsigned int num_modes,
> const char * const modes[])
> {
> + static const struct drm_prop_enum_list tv_norm_values[] = {
> + { __builtin_ffs(DRM_MODE_TV_NORM_NTSC_443) - 1, "NTSC-443" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_NTSC_J) - 1, "NTSC-J" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_NTSC_M) - 1, "NTSC-M" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_60) - 1, "PAL-60" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_B) - 1, "PAL-B" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_D) - 1, "PAL-D" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_G) - 1, "PAL-G" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_H) - 1, "PAL-H" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_I) - 1, "PAL-I" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_M) - 1, "PAL-M" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_N) - 1, "PAL-N" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_NC) - 1, "PAL-Nc" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_60) - 1, "SECAM-60" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_B) - 1, "SECAM-B" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_D) - 1, "SECAM-D" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_G) - 1, "SECAM-G" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_K) - 1, "SECAM-K" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_K1) - 1, "SECAM-K1" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_L) - 1, "SECAM-L" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_HD480I) - 1, "hd480i" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_HD480P) - 1, "hd480p" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_HD576I) - 1, "hd576i" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_HD576P) - 1, "hd576p" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_HD720P) - 1, "hd720p" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_HD1080I) - 1, "hd1080i" },
> + };
> struct drm_property *tv_selector;
> struct drm_property *tv_subconnector;
> + struct drm_property *tv_norm;
> unsigned int i;
>
> if (dev->mode_config.tv_select_subconnector_property)
> @@ -1686,6 +1716,13 @@ int drm_mode_create_tv_properties(struct drm_device *dev,
> if (drm_mode_create_tv_margin_properties(dev))
> goto nomem;
>
> + tv_norm = drm_property_create_bitmask(dev, 0, "tv norm",
> + tv_norm_values, ARRAY_SIZE(tv_norm_values),
> + supported_tv_norms);

I expected this to be an enum, why a bitmask? Userspace can set multiple
bits in a bitmask.

Noralf.

> + if (!tv_norm)
> + goto nomem;
> + dev->mode_config.tv_norm_property = tv_norm;
> +
> dev->mode_config.tv_mode_property =
> drm_property_create(dev, DRM_MODE_PROP_ENUM,
> "mode", num_modes);
> diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c
> index 4a788c1c9058..457529e5d857 100644
> --- a/drivers/gpu/drm/vc4/vc4_vec.c
> +++ b/drivers/gpu/drm/vc4/vc4_vec.c
> @@ -573,7 +573,9 @@ 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(drm, ARRAY_SIZE(tv_mode_names),
> + ret = drm_mode_create_tv_properties(drm,
> + 0,
> + ARRAY_SIZE(tv_mode_names),
> tv_mode_names);
> if (ret)
> return ret;
> diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
> index 1e9996b33cc8..78275e68ff66 100644
> --- a/include/drm/drm_connector.h
> +++ b/include/drm/drm_connector.h
> @@ -143,6 +143,32 @@ enum subpixel_order {
>
> };
>
> +#define DRM_MODE_TV_NORM_NTSC_443 (1 << 0)
> +#define DRM_MODE_TV_NORM_NTSC_J (1 << 1)
> +#define DRM_MODE_TV_NORM_NTSC_M (1 << 2)
> +#define DRM_MODE_TV_NORM_PAL_60 (1 << 3)
> +#define DRM_MODE_TV_NORM_PAL_B (1 << 4)
> +#define DRM_MODE_TV_NORM_PAL_D (1 << 5)
> +#define DRM_MODE_TV_NORM_PAL_G (1 << 6)
> +#define DRM_MODE_TV_NORM_PAL_H (1 << 7)
> +#define DRM_MODE_TV_NORM_PAL_I (1 << 8)
> +#define DRM_MODE_TV_NORM_PAL_M (1 << 9)
> +#define DRM_MODE_TV_NORM_PAL_N (1 << 10)
> +#define DRM_MODE_TV_NORM_PAL_NC (1 << 11)
> +#define DRM_MODE_TV_NORM_SECAM_60 (1 << 12)
> +#define DRM_MODE_TV_NORM_SECAM_B (1 << 13)
> +#define DRM_MODE_TV_NORM_SECAM_D (1 << 14)
> +#define DRM_MODE_TV_NORM_SECAM_G (1 << 15)
> +#define DRM_MODE_TV_NORM_SECAM_K (1 << 16)
> +#define DRM_MODE_TV_NORM_SECAM_K1 (1 << 17)
> +#define DRM_MODE_TV_NORM_SECAM_L (1 << 18)
> +#define DRM_MODE_TV_NORM_HD480I (1 << 19)
> +#define DRM_MODE_TV_NORM_HD480P (1 << 20)
> +#define DRM_MODE_TV_NORM_HD576I (1 << 21)
> +#define DRM_MODE_TV_NORM_HD576P (1 << 22)
> +#define DRM_MODE_TV_NORM_HD720P (1 << 23)
> +#define DRM_MODE_TV_NORM_HD1080I (1 << 24)
> +
> /**
> * struct drm_scrambling: sink's scrambling support.
> */
> @@ -687,6 +713,7 @@ struct drm_tv_connector_state {
> enum drm_mode_subconnector subconnector;
> struct drm_connector_tv_margins margins;
> unsigned int mode;
> + unsigned int norm;
> unsigned int brightness;
> unsigned int contrast;
> unsigned int flicker_reduction;
> @@ -1779,6 +1806,7 @@ void drm_connector_attach_dp_subconnector_property(struct drm_connector *connect
>
> int drm_mode_create_tv_margin_properties(struct drm_device *dev);
> int drm_mode_create_tv_properties(struct drm_device *dev,
> + unsigned int supported_tv_norms,
> unsigned int num_modes,
> const char * const modes[]);
> void drm_connector_attach_tv_margin_properties(struct drm_connector *conn);
> diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
> index 6b5e01295348..d9e79def8b92 100644
> --- a/include/drm/drm_mode_config.h
> +++ b/include/drm/drm_mode_config.h
> @@ -704,6 +704,12 @@ struct drm_mode_config {
> */
> struct drm_property *dp_subconnector_property;
>
> + /**
> + * @tv_norm_property: Optional TV property to select the TV
> + * standard output on the connector.
> + */
> + struct drm_property *tv_norm_property;
> +
> /**
> * @tv_subconnector_property: Optional TV property to differentiate
> * between different TV connector types.
>

2022-08-08 12:57:00

by Noralf Trønnes

[permalink] [raw]
Subject: Re: [PATCH v1 03/35] drm/atomic: Add TV subconnector property to get/set_property



Den 29.07.2022 18.34, skrev Maxime Ripard:
> The subconnector property was created by drm_mode_create_tv_properties(),
> but wasn't exposed to the userspace through the generic
> atomic_get/set_property implementation, and wasn't stored in any generic
> state structure.
>
> Let's solve this.
>
> Signed-off-by: Maxime Ripard <[email protected]>
>

I just realised that this and the select_subconnector property isn't
used by any drivers. Do you plan to use them? Maybe they don't need to
be wired up at all.

Anyways, up to you:

Reviewed-by: Noralf Trønnes <[email protected]>

> diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
> index c74c78a28171..c06d0639d552 100644
> --- a/drivers/gpu/drm/drm_atomic_uapi.c
> +++ b/drivers/gpu/drm/drm_atomic_uapi.c
> @@ -688,6 +688,8 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector,
> return -EINVAL;
> } else if (property == config->tv_select_subconnector_property) {
> state->tv.select_subconnector = val;
> + } else if (property == config->tv_subconnector_property) {
> + state->tv.subconnector = val;
> } else if (property == config->tv_left_margin_property) {
> state->tv.margins.left = val;
> } else if (property == config->tv_right_margin_property) {
> @@ -796,6 +798,8 @@ drm_atomic_connector_get_property(struct drm_connector *connector,
> *val = connector->dpms;
> } else if (property == config->tv_select_subconnector_property) {
> *val = state->tv.select_subconnector;
> + } else if (property == config->tv_subconnector_property) {
> + *val = state->tv.subconnector;
> } else if (property == config->tv_left_margin_property) {
> *val = state->tv.margins.left;
> } else if (property == config->tv_right_margin_property) {
> diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
> index f8091edf9a33..1e9996b33cc8 100644
> --- a/include/drm/drm_connector.h
> +++ b/include/drm/drm_connector.h
> @@ -672,6 +672,7 @@ struct drm_connector_tv_margins {
> /**
> * struct drm_tv_connector_state - TV connector related states
> * @select_subconnector: selected subconnector
> + * @subconnector: detected subconnector
> * @margins: TV margins
> * @mode: TV mode
> * @brightness: brightness in percent
> @@ -683,6 +684,7 @@ struct drm_connector_tv_margins {
> */
> struct drm_tv_connector_state {
> enum drm_mode_subconnector select_subconnector;
> + enum drm_mode_subconnector subconnector;
> struct drm_connector_tv_margins margins;
> unsigned int mode;
> unsigned int brightness;
>

2022-08-08 13:21:45

by Noralf Trønnes

[permalink] [raw]
Subject: Re: [PATCH v1 06/35] drm/connector: Only register TV mode property if present



Den 29.07.2022 18.34, skrev Maxime Ripard:
> The drm_create_tv_properties() will create the TV mode property
> unconditionally.
>
> However, since we'll gradually phase it out, let's register it only if we
> have a list passed as an argument. This will make the transition easier.
>
> Signed-off-by: Maxime Ripard <[email protected]>
>

I don't understand why this makes the transition easier, but if you
think so:

Acked-by: Noralf Trønnes <[email protected]>

> diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> index 68a4e47f85a9..d73a68764b6e 100644
> --- a/drivers/gpu/drm/drm_connector.c
> +++ b/drivers/gpu/drm/drm_connector.c
> @@ -1684,7 +1684,6 @@ int drm_mode_create_tv_properties(struct drm_device *dev,
> struct drm_property *tv_selector;
> struct drm_property *tv_subconnector;
> struct drm_property *tv_norm;
> - unsigned int i;
>
> if (dev->mode_config.tv_select_subconnector_property)
> return 0;
> @@ -1723,15 +1722,19 @@ int drm_mode_create_tv_properties(struct drm_device *dev,
> goto nomem;
> dev->mode_config.tv_norm_property = tv_norm;
>
> - dev->mode_config.tv_mode_property =
> - drm_property_create(dev, DRM_MODE_PROP_ENUM,
> - "mode", num_modes);
> - if (!dev->mode_config.tv_mode_property)
> - goto nomem;
> + if (num_modes) {
> + unsigned int i;
>
> - for (i = 0; i < num_modes; i++)
> - drm_property_add_enum(dev->mode_config.tv_mode_property,
> - i, modes[i]);
> + dev->mode_config.tv_mode_property =
> + drm_property_create(dev, DRM_MODE_PROP_ENUM,
> + "mode", num_modes);
> + if (!dev->mode_config.tv_mode_property)
> + goto nomem;
> +
> + for (i = 0; i < num_modes; i++)
> + drm_property_add_enum(dev->mode_config.tv_mode_property,
> + i, modes[i]);
> + }
>
> dev->mode_config.tv_brightness_property =
> drm_property_create_range(dev, 0, "brightness", 0, 100);
>

2022-08-08 13:24:53

by Noralf Trønnes

[permalink] [raw]
Subject: Re: [PATCH v1 00/35] drm: Analog TV Improvements



Den 29.07.2022 18.34, skrev Maxime Ripard:
> Hi,
>
> Here's a series aiming at improving the command line named modes support,
> and more importantly how we deal with all the analog TV variants.
>
> The named modes support were initially introduced to allow to specify the
> analog TV mode to be used.
>
> However, this was causing multiple issues:
>
> * The mode name parsed on the command line was passed directly to the
> driver, which had to figure out which mode it was suppose to match;
>
> * Figuring that out wasn't really easy, since the video= argument or what
> the userspace might not even have a name in the first place, but
> instead could have passed a mode with the same timings;
>
> * The fallback to matching on the timings was mostly working as long as
> we were supporting one 525 lines (most likely NSTC) and one 625 lines
> (PAL), but couldn't differentiate between two modes with the same
> timings (NTSC vs PAL-M vs NSTC-J for example);
>
> * There was also some overlap with the tv mode property registered by
> drm_mode_create_tv_properties(), but named modes weren't interacting
> with that property at all.
>
> * Even though that property was generic, its possible values were
> specific to each drivers, which made some generic support difficult.
>
> Thus, I chose to tackle in multiple steps:
>
> * A new TV norm property was introduced, with generic values, each driver
> reporting through a bitmask what standard it supports to the userspace;
>
> * This option was added to the command line parsing code to be able to
> specify it on the kernel command line, and new atomic_check and reset
> helpers were created to integrate properly into atomic KMS;
>
> * The named mode parsing code is now creating a proper display mode for
> the given named mode, and the TV standard will thus be part of the
> connector state;
>
> * Two drivers were converted and tested for now (vc4 and sun4i), with
> some backward compatibility code to translate the old TV mode to the
> new TV mode;
>
> Unit tests were created along the way. Nouveau, ch7006 and gud are
> currently broken for now since I expect that work to be reworked fairly
> significantly. I'm also not entirely sure about how to migrate GUD to the
> new property.
>

I have looked at gud and I think the future proof solution is to add a
new TV_NORM property to the GUD protocol and add backwards compatibility
for the GUD_TV_MODE property (just for the modes that Raspberry Pi
supports since the gadget driver is out of tree). I don't bother
supporting the tv.mode property in userspace (I haven't seen anything
that uses the property).

I have written up most of the host driver changes but I have to do the
gadget side as well to make sure it works. I'll post some patches when
I'm done. In hindsight I should have used a bitmask for the TV standards
in the first place ;)

Noralf.

2022-08-12 13:33:03

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH v1 05/35] drm/connector: Add TV standard property

Hi Maxime,

On Fri, Jul 29, 2022 at 6:35 PM Maxime Ripard <[email protected]> wrote:
> 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 <[email protected]>

Thanks for your patch!

> --- a/drivers/gpu/drm/drm_connector.c
> +++ b/drivers/gpu/drm/drm_connector.c
> @@ -1649,11 +1650,40 @@ EXPORT_SYMBOL(drm_mode_create_tv_margin_properties);
> * 0 on success or a negative error code on failure.
> */
> int drm_mode_create_tv_properties(struct drm_device *dev,
> + unsigned int supported_tv_norms,
> unsigned int num_modes,
> const char * const modes[])
> {
> + static const struct drm_prop_enum_list tv_norm_values[] = {
> + { __builtin_ffs(DRM_MODE_TV_NORM_NTSC_443) - 1, "NTSC-443" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_NTSC_J) - 1, "NTSC-J" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_NTSC_M) - 1, "NTSC-M" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_60) - 1, "PAL-60" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_B) - 1, "PAL-B" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_D) - 1, "PAL-D" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_G) - 1, "PAL-G" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_H) - 1, "PAL-H" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_I) - 1, "PAL-I" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_M) - 1, "PAL-M" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_N) - 1, "PAL-N" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_NC) - 1, "PAL-Nc" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_60) - 1, "SECAM-60" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_B) - 1, "SECAM-B" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_D) - 1, "SECAM-D" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_G) - 1, "SECAM-G" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_K) - 1, "SECAM-K" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_K1) - 1, "SECAM-K1" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_L) - 1, "SECAM-L" },

The above are analog standards, with a variable horizontal resolution.

> + { __builtin_ffs(DRM_MODE_TV_NORM_HD480I) - 1, "hd480i" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_HD480P) - 1, "hd480p" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_HD576I) - 1, "hd576i" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_HD576P) - 1, "hd576p" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_HD720P) - 1, "hd720p" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_HD1080I) - 1, "hd1080i" },

The above are digital standards, with a fixed resolution.

You seem to have missed "hd1080p"?

In addition, "hd720p", "hd080i", and "hd1080p" are available in both 50
and 60 (actually 59.94) Hz, while "hd1080p" can also use 24 or 25 Hz.
Either you have to add them here (e.g. "hd720p50" and "hd720p60"), or
handle them through "@<refresh>". The latter would impact "[PATCH v1
09/35] drm/modes: Move named modes parsing to a separate function", as
currently a named mode and a refresh rate can't be specified both.

As "[PATCH v1 34/35] drm/modes: Introduce the tv_mode property as a
command-line option" uses a separate "tv_mode" option, and not the main
mode name, I think you want to add them here.

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

2022-08-12 13:52:34

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH v1 07/35] drm/modes: Only consider bpp and refresh before options

Hi Maxime,

On Fri, Jul 29, 2022 at 6:35 PM Maxime Ripard <[email protected]> wrote:
> Some video= options might have a value that contains a dash. However, the
> command line parsing mode considers all dashes as the separator between the
> mode and the bpp count.
>
> Let's rework the parsing code a bit to only consider a dash as the bpp
> separator if it before a comma, the options separator.
>
> A follow-up patch will add a unit-test for this once such an option is
> introduced.
>
> Signed-off-by: Maxime Ripard <[email protected]>

Thanks for your patch!

Reviewed-by: Geert Uytterhoeven <[email protected]>

> --- a/drivers/gpu/drm/drm_modes.c
> +++ b/drivers/gpu/drm/drm_modes.c
> @@ -1819,20 +1819,22 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option,
>
> name = mode_option;
>
> + /* Locate the start of named options */
> + options_ptr = strchr(name, ',');
> + if (options_ptr)
> + options_off = options_ptr - name;
> + else
> + options_off = strlen(name);
> +
> /* Try to locate the bpp and refresh specifiers, if any */
> - bpp_ptr = strchr(name, '-');
> + bpp_ptr = strnchr(name, options_off, '-');

Probably you still want to add a check that the next character
is actually a digit, cfr. my "[PATCH v2 5/5] drm/modes:
parse_cmdline: Add support for named modes containing dashes"
(https://lore.kernel.org/dri-devel/2eb205da88c3cb19ddf04d167ece4e16a330948b.1657788997.git.geert@linux-m68k.org)?

> if (bpp_ptr)
> bpp_off = bpp_ptr - name;
>
> - refresh_ptr = strchr(name, '@');
> + refresh_ptr = strnchr(name, options_off, '@');
> if (refresh_ptr)
> refresh_off = refresh_ptr - name;
>
> - /* Locate the start of named options */
> - options_ptr = strchr(name, ',');
> - if (options_ptr)
> - options_off = options_ptr - name;
> -
> /* Locate the end of the name / resolution, and parse it */
> if (bpp_ptr) {
> mode_end = bpp_off;

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

2022-08-12 13:52:34

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH v1 04/35] drm/modes: Introduce 480i and 576i modes

Hi Maxime,

Thanks for your patch!

On Fri, Jul 29, 2022 at 6:35 PM Maxime Ripard <[email protected]> wrote:
> Multiple drivers (meson, vc4) define the analog TV 525-lines and 625-lines
> modes in the drivers.

Nit: strictly speaking these are not analog modes, but the digital
variants (ITU-R BT.656 and DVD-Video D1) of NTSC and PAL, using a
13.5 MHz sampling frequency for pixels.

In analog modes, the only discrete values are the number of lines, and
the frame/field rate (fixing the horizontal sync rate when combined).

The number of (in)visible pixels per line depends on the available
bandwidth. In a digital variant (which is anything generated by a
digital computer system), the latter depends on the pixel clock, which
can wildly differ from the 13.5 MHz used in the BT.656 standard. (e.g.
Amiga uses 7.09/14.19/28.38 MHz (PAL) or 7.16/14.32/28.64 MHz (NTSC)).

So I think we probably need some way to generate a PAL/NTSC-compatible
mode based not only on resolution, but also on pixel clock.

>
> Since those modes are fairly standards, and that we'll need to use them in
> more places in the future, let's move the meson definition into the
> framework.
>
> The meson one was chosen because vc4's isn't accurate and doesn't amount to
> 525 and 625 lines.
>
> Signed-off-by: Maxime Ripard <[email protected]>

> --- a/drivers/gpu/drm/drm_modes.c
> +++ b/drivers/gpu/drm/drm_modes.c
> @@ -48,6 +48,24 @@
>
> #include "drm_crtc_internal.h"
>
> +const struct drm_display_mode drm_mode_480i = {
> + DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 13500,
> + 720, 739, 801, 858, 0,
> + 480, 488, 494, 525, 0,
> + DRM_MODE_FLAG_INTERLACE),
> + .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3,
> +};
> +EXPORT_SYMBOL_GPL(drm_mode_480i);
> +
> +const struct drm_display_mode drm_mode_576i = {
> + DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 13500,
> + 720, 732, 795, 864, 0,
> + 576, 580, 586, 625, 0,
> + DRM_MODE_FLAG_INTERLACE),
> + .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3,
> +};
> +EXPORT_SYMBOL_GPL(drm_mode_576i);
> +
> /**

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

2022-08-12 13:53:18

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH v1 09/35] drm/modes: Move named modes parsing to a separate function

Hi Maxime,

On Fri, Jul 29, 2022 at 6:36 PM Maxime Ripard <[email protected]> wrote:
> 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.
>
> Signed-off-by: Maxime Ripard <[email protected]>

Thanks for your patch, which looks similar to my "[PATCH v2 2/5]
drm/modes: Extract drm_mode_parse_cmdline_named_mode()"
(https://lore.kernel.org/dri-devel/1371554419ae63cb54c2a377db0c1016fcf200bb.1657788997.git.geert@linux-m68k.org
;-)

> --- a/drivers/gpu/drm/drm_modes.c
> +++ b/drivers/gpu/drm/drm_modes.c
> @@ -1773,6 +1773,28 @@ static const char * const drm_named_modes_whitelist[] = {
> "PAL",
> };
>
> +static bool drm_mode_parse_cmdline_named_mode(const char *name,
> + unsigned int name_end,
> + struct drm_cmdline_mode *cmdline_mode)
> +{
> + unsigned int i;
> +
> + for (i = 0; i < ARRAY_SIZE(drm_named_modes_whitelist); i++) {
> + int ret;
> +
> + ret = str_has_prefix(name, drm_named_modes_whitelist[i]);
> + if (ret != name_end)
> + continue;
> +
> + strcpy(cmdline_mode->name, drm_named_modes_whitelist[i]);
> + cmdline_mode->specified = true;
> +
> + return true;
> + }
> +
> + return false;

What's the point in returning a value, if it is never checked?
Just make this function return void?

> +}
> +
> /**
> * drm_mode_parse_command_line_for_connector - parse command line modeline for connector
> * @mode_option: optional per connector mode option
> @@ -1848,18 +1870,14 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option,
> parse_extras = true;
> }
>
> - /* First check for a named mode */
> - for (i = 0; i < ARRAY_SIZE(drm_named_modes_whitelist); i++) {
> - ret = str_has_prefix(name, drm_named_modes_whitelist[i]);
> - if (ret == mode_end) {
> - if (refresh_ptr)
> - return false; /* named + refresh is invalid */
> + /*
> + * Having a mode that starts by a letter (and thus is named) and
> + * an at-sign (used to specify a refresh rate) is disallowed.
> + */
> + if (!isdigit(name[0]) && refresh_ptr)

This condition may have to be relaxed, if we want to support e.g.
"hd720p@50", cfr. my comments on "[PATCH v1 05/35] drm/connector:
Add TV standard property".

> + return false;
>
> - strcpy(mode->name, drm_named_modes_whitelist[i]);
> - mode->specified = true;
> - break;
> - }
> - }
> + drm_mode_parse_cmdline_named_mode(name, mode_end, mode);

This call needs to be conditional on mode_end being non-zero, cfr. my
patch "[PATCH v2 1/5] drm/modes: parse_cmdline: Handle empty mode name
part" (https://lore.kernel.org/dri-devel/302d0737539daa2053134e8f24fdf37e3d939e1e.1657788997.git.geert@linux-m68k.org).

>
> /* No named mode? Check for a normal mode argument, e.g. 1024x768 */
> if (!mode->specified && isdigit(name[0])) {


Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

2022-08-15 08:07:22

by Maxime Ripard

[permalink] [raw]
Subject: Re: [PATCH v1 03/35] drm/atomic: Add TV subconnector property to get/set_property

Hi Noralf,

Thanks for your review

On Mon, Aug 08, 2022 at 02:30:42PM +0200, Noralf Tr?nnes wrote:
> Den 29.07.2022 18.34, skrev Maxime Ripard:
> > The subconnector property was created by drm_mode_create_tv_properties(),
> > but wasn't exposed to the userspace through the generic
> > atomic_get/set_property implementation, and wasn't stored in any generic
> > state structure.
> >
> > Let's solve this.
> >
> > Signed-off-by: Maxime Ripard <[email protected]>
>
> I just realised that this and the select_subconnector property isn't
> used by any drivers. Do you plan to use them? Maybe they don't need to
> be wired up at all.

I'm not sure really

It's true that the subconnector and select_subconnector fields in the TV
connector state aren't used by any driver, but the ch7006 and nouveau
will update the property content through a call to
drm_object_property_set_value

https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/i2c/ch7006_drv.c#L217
https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c#L185

I think it could still be useful to report it in the connector state, if
only for consistency?

Maxime


Attachments:
(No filename) (1.17 kB)
signature.asc (235.00 B)
Download all attachments

2022-08-15 08:43:11

by Maxime Ripard

[permalink] [raw]
Subject: Re: [PATCH v1 14/35] drm/atomic-helper: Add an analog TV atomic_check implementation

Hi,

On Fri, Jul 29, 2022 at 07:16:31PM +0200, Mateusz Kwiatkowski wrote:
> I'm pretty sure that PAL-60 and SECAM-60 should be tied to the 480i mode.
> Those are non-standard "norms" that use 60 Hz sync (which is largely
> synonymous with 480i in the analog TV world) with PAL/SECAM color encoding.

Understood, I've changed it.

Maxime


Attachments:
(No filename) (347.00 B)
signature.asc (235.00 B)
Download all attachments

2022-08-15 08:52:37

by Maxime Ripard

[permalink] [raw]
Subject: Re: [PATCH v1 08/35] drm/client: Add some tests for drm_connector_pick_cmdline_mode()

Hi Thomas,

On Tue, Aug 02, 2022 at 12:14:29PM +0200, Thomas Zimmermann wrote:
> Am 29.07.22 um 18:34 schrieb Maxime Ripard:
> > drm_connector_pick_cmdline_mode() is in charge of finding a proper
> > drm_display_mode from the definition we got in the video= command line
> > argument.
> >
> > Let's add some unit tests to make sure we're not getting any regressions
> > there.
> >
> > Signed-off-by: Maxime Ripard <[email protected]>
> >
> > diff --git a/drivers/gpu/drm/drm_client_modeset.c b/drivers/gpu/drm/drm_client_modeset.c
> > index bbc535cc50dd..ee6b8f193c24 100644
> > --- a/drivers/gpu/drm/drm_client_modeset.c
> > +++ b/drivers/gpu/drm/drm_client_modeset.c
> > @@ -1237,3 +1237,7 @@ int drm_client_modeset_dpms(struct drm_client_dev *client, int mode)
> > return ret;
> > }
> > EXPORT_SYMBOL(drm_client_modeset_dpms);
> > +
> > +#ifdef CONFIG_DRM_KUNIT_TEST
> > +#include "tests/drm_mode_test.c"
> > +#endif
>
> Including source files is somewhat ugly, prolongs compile times and could
> even interfere with the actual source code. Can we do this in some other
> way?

Yeah, this irks me a bit as well, but it's the preferred way of doing it
according to the kunit doc:
https://www.kernel.org/doc/html/latest/dev-tools/kunit/usage.html#testing-static-functions

> I suggest to add the tests here and export them for use in the test case.
> Something like
>
> #ifdef CONFIG_DRM_KUNIT_TEST
> static drm_mode_res_1920_1080_60()
> {
> ...
> }
>
> struct kunit_case drm_mode_tests[] = {
> drm_mode_res_1920_1080_60
> };
> EXPORT_SYMBOL(drm_mode_tests);
> #endif
>
> This would add the tests next to the tested code, but leave the test driver
> in drm_mode_test.c.

The test suite is fairly small for now, but if we end up with dozens of
tests like what is there for the command line parser (which could happen
for that kind of functions), I'm very afraid that the original source
file will become unreadable, while this has the advantage to keep the
original file readability.

Maxime


Attachments:
(No filename) (2.02 kB)
signature.asc (235.00 B)
Download all attachments

2022-08-15 08:53:53

by Maxime Ripard

[permalink] [raw]
Subject: Re: [PATCH v1 24/35] drm/vc4: vec: Add support for more analog TV standards

Hi,

On Fri, Jul 29, 2022 at 07:55:30PM +0200, Mateusz Kwiatkowski wrote:
> Hi Maxime,
>
> I think that declaring PAL-B and SECAM-B as the only supported 576i
> norms is a bit random.

Starting with this patch, PAL-N should be supported as well, right?

> Norms B, D, G, H, I, K, K1 and L (for both PAL and SECAM) are
> essentially identical if we're talking about baseband signals, AFAIK
> they only differ when those are modulated as RF signals. I'm not sure
> if there's a point to differentiating those (that's more about patch
> 05/35) unless we need to deal with some device that actually features
> an RF modulator.

What I was aiming for is to have all the cases we have in all the
drivers covered so that we can make that property generic. i915
declares and uses all those variants:

https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/i915/display/intel_sdvo.c#L68

Especially since it's i915 and it's pretty much the standard as far as
the uAPI goes, I'd rather avoid any regression there.

> But if we do want to have all those norms separate, then I'd say that
> VC4 should declare support for all of those, and all should map to the
> same VEC settings. Some users from e.g. the UK might think that they
> won't get proper picture if PAL-I is not on the list of supported
> norms. Same goes for e.g. SECAM-D/K in the former Soviet territories,
> and so on.

I'd be open to it, but we can always extend vc4 to support those modes
later on. The work you did to make that easier should make it trivial.

Maxime


Attachments:
(No filename) (1.53 kB)
signature.asc (235.00 B)
Download all attachments

2022-08-15 10:45:35

by Maxime Ripard

[permalink] [raw]
Subject: Re: [PATCH v1 06/35] drm/connector: Only register TV mode property if present

Hi,

On Mon, Aug 08, 2022 at 02:49:08PM +0200, Noralf Tr?nnes wrote:
> Den 29.07.2022 18.34, skrev Maxime Ripard:
> > The drm_create_tv_properties() will create the TV mode property
> > unconditionally.
> >
> > However, since we'll gradually phase it out, let's register it only if we
> > have a list passed as an argument. This will make the transition easier.
> >
> > Signed-off-by: Maxime Ripard <[email protected]>
> >
>
> I don't understand why this makes the transition easier, but if you
> think so:

So the basic idea behind this series was to introduce the new property,
gradually convert the old drivers to the new one, and finally remove the
old one.

In order to keep the backward compatibility, we need to add to the
drivers some custom get/set_property hook to expose the old property and
fill the new one if needed.

That means that each driver would have to create the old property, which
will conflict with that code

Maxime


Attachments:
(No filename) (974.00 B)
signature.asc (235.00 B)
Download all attachments

2022-08-15 10:51:21

by Noralf Trønnes

[permalink] [raw]
Subject: Re: [PATCH v1 03/35] drm/atomic: Add TV subconnector property to get/set_property



Den 15.08.2022 09.35, skrev Maxime Ripard:
> Hi Noralf,
>
> Thanks for your review
>
> On Mon, Aug 08, 2022 at 02:30:42PM +0200, Noralf Trønnes wrote:
>> Den 29.07.2022 18.34, skrev Maxime Ripard:
>>> The subconnector property was created by drm_mode_create_tv_properties(),
>>> but wasn't exposed to the userspace through the generic
>>> atomic_get/set_property implementation, and wasn't stored in any generic
>>> state structure.
>>>
>>> Let's solve this.
>>>
>>> Signed-off-by: Maxime Ripard <[email protected]>
>>
>> I just realised that this and the select_subconnector property isn't
>> used by any drivers. Do you plan to use them? Maybe they don't need to
>> be wired up at all.
>
> I'm not sure really
>
> It's true that the subconnector and select_subconnector fields in the TV
> connector state aren't used by any driver, but the ch7006 and nouveau
> will update the property content through a call to
> drm_object_property_set_value
>
> https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/i2c/ch7006_drv.c#L217
> https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c#L185
>
> I think it could still be useful to report it in the connector state, if
> only for consistency?
>

Yeah maybe.

I just realised that I have support in the GUD protocol for these
properties so any future devices that rely on them them will need this
patch, so I'm now suddenly in favor of this :)

Noralf.

2022-08-15 11:20:27

by Noralf Trønnes

[permalink] [raw]
Subject: Re: [PATCH v1 06/35] drm/connector: Only register TV mode property if present



Den 15.08.2022 12.40, skrev Maxime Ripard:
> Hi,
>
> On Mon, Aug 08, 2022 at 02:49:08PM +0200, Noralf Trønnes wrote:
>> Den 29.07.2022 18.34, skrev Maxime Ripard:
>>> The drm_create_tv_properties() will create the TV mode property
>>> unconditionally.
>>>
>>> However, since we'll gradually phase it out, let's register it only if we
>>> have a list passed as an argument. This will make the transition easier.
>>>
>>> Signed-off-by: Maxime Ripard <[email protected]>
>>>
>>
>> I don't understand why this makes the transition easier, but if you
>> think so:
>
> So the basic idea behind this series was to introduce the new property,
> gradually convert the old drivers to the new one, and finally remove the
> old one.
>
> In order to keep the backward compatibility, we need to add to the
> drivers some custom get/set_property hook to expose the old property and
> fill the new one if needed.
>
> That means that each driver would have to create the old property, which
> will conflict with that code
>

Got it.

Noralf.

2022-08-16 10:52:35

by Maxime Ripard

[permalink] [raw]
Subject: Re: [PATCH v1 05/35] drm/connector: Add TV standard property

Hi,

On Mon, Aug 08, 2022 at 02:44:56PM +0200, Noralf Tr?nnes wrote:
> Den 29.07.2022 18.34, skrev Maxime Ripard:
> > 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 <[email protected]>
> >
>
> Please also update Documentation/gpu/kms-properties.csv
>
> Requirements for adding a new property is found in
> Documentation/gpu/drm-kms.rst

I knew this was going to be raised at some point, so I'm glad it's that
early :)

I really don't know what to do there. If we stick by our usual rules,
then we can't have any of that work merged.

However, I think the status quo is not really satisfactory either.
Indeed, we have a property, that doesn't follow those requirements
either, with a driver-specific content, and that stands in the way of
fixes and further improvements at both the core framework and driver
levels.

So having that new property still seems like a net improvement at the
driver, framework and uAPI levels, even if it's not entirely following
the requirements we have in place.

Even more so since, realistically, those kind of interfaces will never
get any new development on the user-space side of things, it's
considered by everyone as legacy.

This also is something we need to support at some point if we want to
completely deprecate the fbdev drivers and provide decent alternatives
in KMS.

So yeah, strictly speaking, we would not qualify for our requirements
there. I still think we have a strong case for an exception though.

> > diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
> > index c06d0639d552..d7ff6c644c2f 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->tv_mode_property) {
> > state->tv.mode = val;
> > + } else if (property == config->tv_norm_property) {
> > + state->tv.norm = 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->tv_mode_property) {
> > *val = state->tv.mode;
> > + } else if (property == config->tv_norm_property) {
> > + *val = state->tv.norm;
> > } 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 e3142c8142b3..68a4e47f85a9 100644
> > --- a/drivers/gpu/drm/drm_connector.c
> > +++ b/drivers/gpu/drm/drm_connector.c
> > @@ -1637,6 +1637,7 @@ EXPORT_SYMBOL(drm_mode_create_tv_margin_properties);
> > /**
> > * drm_mode_create_tv_properties - create TV specific connector properties
> > * @dev: DRM device
> > + * @supported_tv_norms: Bitmask of TV norms supported (See DRM_MODE_TV_NORM_*)
> > * @num_modes: number of different TV formats (modes) supported
> > * @modes: array of pointers to strings containing name of each format
> > *
> > @@ -1649,11 +1650,40 @@ EXPORT_SYMBOL(drm_mode_create_tv_margin_properties);
> > * 0 on success or a negative error code on failure.
> > */
> > int drm_mode_create_tv_properties(struct drm_device *dev,
> > + unsigned int supported_tv_norms,
> > unsigned int num_modes,
> > const char * const modes[])
> > {
> > + static const struct drm_prop_enum_list tv_norm_values[] = {
> > + { __builtin_ffs(DRM_MODE_TV_NORM_NTSC_443) - 1, "NTSC-443" },
> > + { __builtin_ffs(DRM_MODE_TV_NORM_NTSC_J) - 1, "NTSC-J" },
> > + { __builtin_ffs(DRM_MODE_TV_NORM_NTSC_M) - 1, "NTSC-M" },
> > + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_60) - 1, "PAL-60" },
> > + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_B) - 1, "PAL-B" },
> > + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_D) - 1, "PAL-D" },
> > + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_G) - 1, "PAL-G" },
> > + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_H) - 1, "PAL-H" },
> > + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_I) - 1, "PAL-I" },
> > + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_M) - 1, "PAL-M" },
> > + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_N) - 1, "PAL-N" },
> > + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_NC) - 1, "PAL-Nc" },
> > + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_60) - 1, "SECAM-60" },
> > + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_B) - 1, "SECAM-B" },
> > + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_D) - 1, "SECAM-D" },
> > + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_G) - 1, "SECAM-G" },
> > + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_K) - 1, "SECAM-K" },
> > + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_K1) - 1, "SECAM-K1" },
> > + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_L) - 1, "SECAM-L" },
> > + { __builtin_ffs(DRM_MODE_TV_NORM_HD480I) - 1, "hd480i" },
> > + { __builtin_ffs(DRM_MODE_TV_NORM_HD480P) - 1, "hd480p" },
> > + { __builtin_ffs(DRM_MODE_TV_NORM_HD576I) - 1, "hd576i" },
> > + { __builtin_ffs(DRM_MODE_TV_NORM_HD576P) - 1, "hd576p" },
> > + { __builtin_ffs(DRM_MODE_TV_NORM_HD720P) - 1, "hd720p" },
> > + { __builtin_ffs(DRM_MODE_TV_NORM_HD1080I) - 1, "hd1080i" },
> > + };
> > struct drm_property *tv_selector;
> > struct drm_property *tv_subconnector;
> > + struct drm_property *tv_norm;
> > unsigned int i;
> >
> > if (dev->mode_config.tv_select_subconnector_property)
> > @@ -1686,6 +1716,13 @@ int drm_mode_create_tv_properties(struct drm_device *dev,
> > if (drm_mode_create_tv_margin_properties(dev))
> > goto nomem;
> >
> > + tv_norm = drm_property_create_bitmask(dev, 0, "tv norm",
> > + tv_norm_values, ARRAY_SIZE(tv_norm_values),
> > + supported_tv_norms);
>
> I expected this to be an enum, why a bitmask? Userspace can set multiple
> bits in a bitmask.

I went for a bitmask since it allowed to report the capabilities of a
driver, but I just realised that you can do that with an enum too, like
we do for color encodings.

I'll switch for an enum, thanks!
Maxime


Attachments:
(No filename) (6.72 kB)
signature.asc (235.00 B)
Download all attachments

2022-08-16 11:29:31

by Maxime Ripard

[permalink] [raw]
Subject: Re: [PATCH v1 05/35] drm/connector: Add TV standard property

On Tue, Aug 16, 2022 at 11:42:20AM +0200, Noralf Tr?nnes wrote:
>
>
> Den 16.08.2022 10.26, skrev Maxime Ripard:
> > Hi,
> >
> > On Mon, Aug 08, 2022 at 02:44:56PM +0200, Noralf Tr?nnes wrote:
> >> Den 29.07.2022 18.34, skrev Maxime Ripard:
> >>> 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 <[email protected]>
> >>>
> >>
> >> Please also update Documentation/gpu/kms-properties.csv
> >>
> >> Requirements for adding a new property is found in
> >> Documentation/gpu/drm-kms.rst
> >
> > I knew this was going to be raised at some point, so I'm glad it's that
> > early :)
> >
> > I really don't know what to do there. If we stick by our usual rules,
> > then we can't have any of that work merged.
> >
> > However, I think the status quo is not really satisfactory either.
> > Indeed, we have a property, that doesn't follow those requirements
> > either, with a driver-specific content, and that stands in the way of
> > fixes and further improvements at both the core framework and driver
> > levels.
> >
> > So having that new property still seems like a net improvement at the
> > driver, framework and uAPI levels, even if it's not entirely following
> > the requirements we have in place.
> >
> > Even more so since, realistically, those kind of interfaces will never
> > get any new development on the user-space side of things, it's
> > considered by everyone as legacy.
> >
> > This also is something we need to support at some point if we want to
> > completely deprecate the fbdev drivers and provide decent alternatives
> > in KMS.
> >
> > So yeah, strictly speaking, we would not qualify for our requirements
> > there. I still think we have a strong case for an exception though.
>
> Which requirements would that be? The only one I can see is the
> documentation and maybe an IGT test.

This is the one I had in mind
https://dri.freedesktop.org/docs/drm/gpu/drm-uapi.html#open-source-userspace-requirements

I overlooked yours obviously, so I'll update my patches to fix it.

Maxime


Attachments:
(No filename) (2.64 kB)
signature.asc (235.00 B)
Download all attachments

2022-08-16 11:47:58

by Noralf Trønnes

[permalink] [raw]
Subject: Re: [PATCH v1 05/35] drm/connector: Add TV standard property



Den 16.08.2022 10.26, skrev Maxime Ripard:
> Hi,
>
> On Mon, Aug 08, 2022 at 02:44:56PM +0200, Noralf Trønnes wrote:
>> Den 29.07.2022 18.34, skrev Maxime Ripard:
>>> 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 <[email protected]>
>>>
>>
>> Please also update Documentation/gpu/kms-properties.csv
>>
>> Requirements for adding a new property is found in
>> Documentation/gpu/drm-kms.rst
>
> I knew this was going to be raised at some point, so I'm glad it's that
> early :)
>
> I really don't know what to do there. If we stick by our usual rules,
> then we can't have any of that work merged.
>
> However, I think the status quo is not really satisfactory either.
> Indeed, we have a property, that doesn't follow those requirements
> either, with a driver-specific content, and that stands in the way of
> fixes and further improvements at both the core framework and driver
> levels.
>
> So having that new property still seems like a net improvement at the
> driver, framework and uAPI levels, even if it's not entirely following
> the requirements we have in place.
>
> Even more so since, realistically, those kind of interfaces will never
> get any new development on the user-space side of things, it's
> considered by everyone as legacy.
>
> This also is something we need to support at some point if we want to
> completely deprecate the fbdev drivers and provide decent alternatives
> in KMS.
>
> So yeah, strictly speaking, we would not qualify for our requirements
> there. I still think we have a strong case for an exception though.
>

Which requirements would that be? The only one I can see is the
documentation and maybe an IGT test.

Noralf.

>>> diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
>>> index c06d0639d552..d7ff6c644c2f 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->tv_mode_property) {
>>> state->tv.mode = val;
>>> + } else if (property == config->tv_norm_property) {
>>> + state->tv.norm = 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->tv_mode_property) {
>>> *val = state->tv.mode;
>>> + } else if (property == config->tv_norm_property) {
>>> + *val = state->tv.norm;
>>> } 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 e3142c8142b3..68a4e47f85a9 100644
>>> --- a/drivers/gpu/drm/drm_connector.c
>>> +++ b/drivers/gpu/drm/drm_connector.c
>>> @@ -1637,6 +1637,7 @@ EXPORT_SYMBOL(drm_mode_create_tv_margin_properties);
>>> /**
>>> * drm_mode_create_tv_properties - create TV specific connector properties
>>> * @dev: DRM device
>>> + * @supported_tv_norms: Bitmask of TV norms supported (See DRM_MODE_TV_NORM_*)
>>> * @num_modes: number of different TV formats (modes) supported
>>> * @modes: array of pointers to strings containing name of each format
>>> *
>>> @@ -1649,11 +1650,40 @@ EXPORT_SYMBOL(drm_mode_create_tv_margin_properties);
>>> * 0 on success or a negative error code on failure.
>>> */
>>> int drm_mode_create_tv_properties(struct drm_device *dev,
>>> + unsigned int supported_tv_norms,
>>> unsigned int num_modes,
>>> const char * const modes[])
>>> {
>>> + static const struct drm_prop_enum_list tv_norm_values[] = {
>>> + { __builtin_ffs(DRM_MODE_TV_NORM_NTSC_443) - 1, "NTSC-443" },
>>> + { __builtin_ffs(DRM_MODE_TV_NORM_NTSC_J) - 1, "NTSC-J" },
>>> + { __builtin_ffs(DRM_MODE_TV_NORM_NTSC_M) - 1, "NTSC-M" },
>>> + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_60) - 1, "PAL-60" },
>>> + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_B) - 1, "PAL-B" },
>>> + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_D) - 1, "PAL-D" },
>>> + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_G) - 1, "PAL-G" },
>>> + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_H) - 1, "PAL-H" },
>>> + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_I) - 1, "PAL-I" },
>>> + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_M) - 1, "PAL-M" },
>>> + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_N) - 1, "PAL-N" },
>>> + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_NC) - 1, "PAL-Nc" },
>>> + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_60) - 1, "SECAM-60" },
>>> + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_B) - 1, "SECAM-B" },
>>> + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_D) - 1, "SECAM-D" },
>>> + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_G) - 1, "SECAM-G" },
>>> + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_K) - 1, "SECAM-K" },
>>> + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_K1) - 1, "SECAM-K1" },
>>> + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_L) - 1, "SECAM-L" },
>>> + { __builtin_ffs(DRM_MODE_TV_NORM_HD480I) - 1, "hd480i" },
>>> + { __builtin_ffs(DRM_MODE_TV_NORM_HD480P) - 1, "hd480p" },
>>> + { __builtin_ffs(DRM_MODE_TV_NORM_HD576I) - 1, "hd576i" },
>>> + { __builtin_ffs(DRM_MODE_TV_NORM_HD576P) - 1, "hd576p" },
>>> + { __builtin_ffs(DRM_MODE_TV_NORM_HD720P) - 1, "hd720p" },
>>> + { __builtin_ffs(DRM_MODE_TV_NORM_HD1080I) - 1, "hd1080i" },
>>> + };
>>> struct drm_property *tv_selector;
>>> struct drm_property *tv_subconnector;
>>> + struct drm_property *tv_norm;
>>> unsigned int i;
>>>
>>> if (dev->mode_config.tv_select_subconnector_property)
>>> @@ -1686,6 +1716,13 @@ int drm_mode_create_tv_properties(struct drm_device *dev,
>>> if (drm_mode_create_tv_margin_properties(dev))
>>> goto nomem;
>>>
>>> + tv_norm = drm_property_create_bitmask(dev, 0, "tv norm",
>>> + tv_norm_values, ARRAY_SIZE(tv_norm_values),
>>> + supported_tv_norms);
>>
>> I expected this to be an enum, why a bitmask? Userspace can set multiple
>> bits in a bitmask.
>
> I went for a bitmask since it allowed to report the capabilities of a
> driver, but I just realised that you can do that with an enum too, like
> we do for color encodings.
>
> I'll switch for an enum, thanks!
> Maxime

2022-08-16 12:13:23

by Maxime Ripard

[permalink] [raw]
Subject: Re: [PATCH v1 04/35] drm/modes: Introduce 480i and 576i modes

On Tue, Aug 02, 2022 at 04:16:29PM +0200, Thomas Zimmermann wrote:
> Hi
>
> Am 02.08.22 um 15:58 schrieb Jani Nikula:
> > On Fri, 29 Jul 2022, Maxime Ripard <[email protected]> wrote:
> > > Multiple drivers (meson, vc4) define the analog TV 525-lines and 625-lines
> > > modes in the drivers.
> > >
> > > Since those modes are fairly standards, and that we'll need to use them in
> > > more places in the future, let's move the meson definition into the
> > > framework.
> >
> > I think you should always expose interfaces, not data. Data is not an
> > interface, and I think this sets a bad example that will be cargo
> > culted.
>
> Although I wrote the opposite wrt patch 8, I agree with Jani here when it
> comes to 'official' interfaces. The cases I've seen of exported data
> structures often lead to intransparent code.

Ack. The improvement Geert suggested would involve that change anyway,
so this should be fixed for the next iteration.

Maxime


Attachments:
(No filename) (983.00 B)
signature.asc (235.00 B)
Download all attachments

2022-08-16 12:54:28

by Maxime Ripard

[permalink] [raw]
Subject: Re: [PATCH v1 07/35] drm/modes: Only consider bpp and refresh before options

Hi Geert,

Thanks for your review

On Fri, Aug 12, 2022 at 03:25:39PM +0200, Geert Uytterhoeven wrote:
> Hi Maxime,
>
> On Fri, Jul 29, 2022 at 6:35 PM Maxime Ripard <[email protected]> wrote:
> > Some video= options might have a value that contains a dash. However, the
> > command line parsing mode considers all dashes as the separator between the
> > mode and the bpp count.
> >
> > Let's rework the parsing code a bit to only consider a dash as the bpp
> > separator if it before a comma, the options separator.
> >
> > A follow-up patch will add a unit-test for this once such an option is
> > introduced.
> >
> > Signed-off-by: Maxime Ripard <[email protected]>
>
> Thanks for your patch!
>
> Reviewed-by: Geert Uytterhoeven <[email protected]>
>
> > --- a/drivers/gpu/drm/drm_modes.c
> > +++ b/drivers/gpu/drm/drm_modes.c
> > @@ -1819,20 +1819,22 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option,
> >
> > name = mode_option;
> >
> > + /* Locate the start of named options */
> > + options_ptr = strchr(name, ',');
> > + if (options_ptr)
> > + options_off = options_ptr - name;
> > + else
> > + options_off = strlen(name);
> > +
> > /* Try to locate the bpp and refresh specifiers, if any */
> > - bpp_ptr = strchr(name, '-');
> > + bpp_ptr = strnchr(name, options_off, '-');
>
> Probably you still want to add a check that the next character
> is actually a digit, cfr. my "[PATCH v2 5/5] drm/modes:
> parse_cmdline: Add support for named modes containing dashes"
> (https://lore.kernel.org/dri-devel/2eb205da88c3cb19ddf04d167ece4e16a330948b.1657788997.git.geert@linux-m68k.org)?

I think your patch is orthogonal, and we should merge it anyway.

As a matter of fact, I initially wanted to do something similar but
bailed out to deal with PAL-M and so on. If there's such modes already,
then we should totally support it

Maxime


Attachments:
(No filename) (1.96 kB)
signature.asc (235.00 B)
Download all attachments

2022-08-16 13:29:36

by Maxime Ripard

[permalink] [raw]
Subject: Re: [PATCH v1 05/35] drm/connector: Add TV standard property

Hi Geert,

On Fri, Aug 12, 2022 at 03:25:18PM +0200, Geert Uytterhoeven wrote:
> > --- a/drivers/gpu/drm/drm_connector.c
> > +++ b/drivers/gpu/drm/drm_connector.c
> > @@ -1649,11 +1650,40 @@ EXPORT_SYMBOL(drm_mode_create_tv_margin_properties);
> > * 0 on success or a negative error code on failure.
> > */
> > int drm_mode_create_tv_properties(struct drm_device *dev,
> > + unsigned int supported_tv_norms,
> > unsigned int num_modes,
> > const char * const modes[])
> > {
> > + static const struct drm_prop_enum_list tv_norm_values[] = {
> > + { __builtin_ffs(DRM_MODE_TV_NORM_NTSC_443) - 1, "NTSC-443" },
> > + { __builtin_ffs(DRM_MODE_TV_NORM_NTSC_J) - 1, "NTSC-J" },
> > + { __builtin_ffs(DRM_MODE_TV_NORM_NTSC_M) - 1, "NTSC-M" },
> > + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_60) - 1, "PAL-60" },
> > + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_B) - 1, "PAL-B" },
> > + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_D) - 1, "PAL-D" },
> > + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_G) - 1, "PAL-G" },
> > + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_H) - 1, "PAL-H" },
> > + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_I) - 1, "PAL-I" },
> > + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_M) - 1, "PAL-M" },
> > + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_N) - 1, "PAL-N" },
> > + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_NC) - 1, "PAL-Nc" },
> > + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_60) - 1, "SECAM-60" },
> > + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_B) - 1, "SECAM-B" },
> > + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_D) - 1, "SECAM-D" },
> > + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_G) - 1, "SECAM-G" },
> > + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_K) - 1, "SECAM-K" },
> > + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_K1) - 1, "SECAM-K1" },
> > + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_L) - 1, "SECAM-L" },
>
> The above are analog standards, with a variable horizontal resolution.
>
> > + { __builtin_ffs(DRM_MODE_TV_NORM_HD480I) - 1, "hd480i" },
> > + { __builtin_ffs(DRM_MODE_TV_NORM_HD480P) - 1, "hd480p" },
> > + { __builtin_ffs(DRM_MODE_TV_NORM_HD576I) - 1, "hd576i" },
> > + { __builtin_ffs(DRM_MODE_TV_NORM_HD576P) - 1, "hd576p" },
> > + { __builtin_ffs(DRM_MODE_TV_NORM_HD720P) - 1, "hd720p" },
> > + { __builtin_ffs(DRM_MODE_TV_NORM_HD1080I) - 1, "hd1080i" },
>
> The above are digital standards, with a fixed resolution.

Are they?

It's not clear to me from looking at nouveau, but I was under the
impression that they were modes for a component output, so CEA 770.3. I
don't have the spec though, so I can't check.

> You seem to have missed "hd1080p"?

Nobody is using it. If we ever have a driver that uses it I think we can
add it.

> In addition, "hd720p", "hd080i", and "hd1080p" are available in both 50
> and 60 (actually 59.94) Hz, while "hd1080p" can also use 24 or 25 Hz.

It looks like nouveau only exposes modes for 480p at 59.94Hz, 576p at
50Hz, 720p at 60Hz, 1080i at 30Hz.

> Either you have to add them here (e.g. "hd720p50" and "hd720p60"), or
> handle them through "@<refresh>". The latter would impact "[PATCH v1
> 09/35] drm/modes: Move named modes parsing to a separate function", as
> currently a named mode and a refresh rate can't be specified both.

I think the former would make more sense. It simplifies a bit the
parser, and we're going to use a named mode anyway.

> As "[PATCH v1 34/35] drm/modes: Introduce the tv_mode property as a
> command-line option" uses a separate "tv_mode" option, and not the main
> mode name, I think you want to add them here.

It's a separate story I think, we could have a named mode hd720p50,
which would be equivalent to 1280x720,tv_mode=hd720p

Maxime


Attachments:
(No filename) (4.03 kB)
signature.asc (235.00 B)
Download all attachments

2022-08-16 13:54:32

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH v1 05/35] drm/connector: Add TV standard property

Hi Maxime,

On Tue, Aug 16, 2022 at 3:20 PM Maxime Ripard <[email protected]> wrote:
> On Fri, Aug 12, 2022 at 03:25:18PM +0200, Geert Uytterhoeven wrote:
> > > --- a/drivers/gpu/drm/drm_connector.c
> > > +++ b/drivers/gpu/drm/drm_connector.c
> > > @@ -1649,11 +1650,40 @@ EXPORT_SYMBOL(drm_mode_create_tv_margin_properties);
> > > * 0 on success or a negative error code on failure.
> > > */
> > > int drm_mode_create_tv_properties(struct drm_device *dev,
> > > + unsigned int supported_tv_norms,
> > > unsigned int num_modes,
> > > const char * const modes[])
> > > {
> > > + static const struct drm_prop_enum_list tv_norm_values[] = {
> > > + { __builtin_ffs(DRM_MODE_TV_NORM_NTSC_443) - 1, "NTSC-443" },
> > > + { __builtin_ffs(DRM_MODE_TV_NORM_NTSC_J) - 1, "NTSC-J" },
> > > + { __builtin_ffs(DRM_MODE_TV_NORM_NTSC_M) - 1, "NTSC-M" },
> > > + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_60) - 1, "PAL-60" },
> > > + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_B) - 1, "PAL-B" },
> > > + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_D) - 1, "PAL-D" },
> > > + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_G) - 1, "PAL-G" },
> > > + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_H) - 1, "PAL-H" },
> > > + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_I) - 1, "PAL-I" },
> > > + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_M) - 1, "PAL-M" },
> > > + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_N) - 1, "PAL-N" },
> > > + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_NC) - 1, "PAL-Nc" },
> > > + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_60) - 1, "SECAM-60" },
> > > + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_B) - 1, "SECAM-B" },
> > > + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_D) - 1, "SECAM-D" },
> > > + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_G) - 1, "SECAM-G" },
> > > + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_K) - 1, "SECAM-K" },
> > > + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_K1) - 1, "SECAM-K1" },
> > > + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_L) - 1, "SECAM-L" },
> >
> > The above are analog standards, with a variable horizontal resolution.
> >
> > > + { __builtin_ffs(DRM_MODE_TV_NORM_HD480I) - 1, "hd480i" },
> > > + { __builtin_ffs(DRM_MODE_TV_NORM_HD480P) - 1, "hd480p" },
> > > + { __builtin_ffs(DRM_MODE_TV_NORM_HD576I) - 1, "hd576i" },
> > > + { __builtin_ffs(DRM_MODE_TV_NORM_HD576P) - 1, "hd576p" },
> > > + { __builtin_ffs(DRM_MODE_TV_NORM_HD720P) - 1, "hd720p" },
> > > + { __builtin_ffs(DRM_MODE_TV_NORM_HD1080I) - 1, "hd1080i" },
> >
> > The above are digital standards, with a fixed resolution.
>
> Are they?
>
> It's not clear to me from looking at nouveau, but I was under the
> impression that they were modes for a component output, so CEA 770.3. I
> don't have the spec though, so I can't check.

Oh right, I forgot about analog HD over component, where you can use
other pixel clocks than in the digital standard.

> > You seem to have missed "hd1080p"?
>
> Nobody is using it. If we ever have a driver that uses it I think we can
> add it.

The PS3 supports 1080p over component
https://manuals.playstation.net/document/en/ps3/current/settings/videooutput.html

> > In addition, "hd720p", "hd080i", and "hd1080p" are available in both 50
> > and 60 (actually 59.94) Hz, while "hd1080p" can also use 24 or 25 Hz.
>
> It looks like nouveau only exposes modes for 480p at 59.94Hz, 576p at
> 50Hz, 720p at 60Hz, 1080i at 30Hz.

PS3 supports both 50 and 60 Hz (same link above).

> > Either you have to add them here (e.g. "hd720p50" and "hd720p60"), or
> > handle them through "@<refresh>". The latter would impact "[PATCH v1
> > 09/35] drm/modes: Move named modes parsing to a separate function", as
> > currently a named mode and a refresh rate can't be specified both.
>
> I think the former would make more sense. It simplifies a bit the
> parser, and we're going to use a named mode anyway.
>
> > As "[PATCH v1 34/35] drm/modes: Introduce the tv_mode property as a
> > command-line option" uses a separate "tv_mode" option, and not the main
> > mode name, I think you want to add them here.
>
> It's a separate story I think, we could have a named mode hd720p50,
> which would be equivalent to 1280x720,tv_mode=hd720p

So where's the field rate in "1280x720,tv_mode=hd720p"?

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

2022-08-16 13:59:39

by Maxime Ripard

[permalink] [raw]
Subject: Re: [PATCH v1 09/35] drm/modes: Move named modes parsing to a separate function

On Fri, Aug 12, 2022 at 03:27:17PM +0200, Geert Uytterhoeven wrote:
> Hi Maxime,
>
> On Fri, Jul 29, 2022 at 6:36 PM Maxime Ripard <[email protected]> wrote:
> > 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.
> >
> > Signed-off-by: Maxime Ripard <[email protected]>
>
> Thanks for your patch, which looks similar to my "[PATCH v2 2/5]
> drm/modes: Extract drm_mode_parse_cmdline_named_mode()"
> (https://lore.kernel.org/dri-devel/1371554419ae63cb54c2a377db0c1016fcf200bb.1657788997.git.geert@linux-m68k.org
> ;-)

Indeed, I forgot about that one, sorry :/

I think I'd still prefer to have the check for refresh + named mode
outside of the function, since I see them as an "integration" issue, not
a parsing one.

It's not the named mode parsing that fails, but the fact that we both
have a valid refresh and a valid named mode.

>
> > --- a/drivers/gpu/drm/drm_modes.c
> > +++ b/drivers/gpu/drm/drm_modes.c
> > @@ -1773,6 +1773,28 @@ static const char * const drm_named_modes_whitelist[] = {
> > "PAL",
> > };
> >
> > +static bool drm_mode_parse_cmdline_named_mode(const char *name,
> > + unsigned int name_end,
> > + struct drm_cmdline_mode *cmdline_mode)
> > +{
> > + unsigned int i;
> > +
> > + for (i = 0; i < ARRAY_SIZE(drm_named_modes_whitelist); i++) {
> > + int ret;
> > +
> > + ret = str_has_prefix(name, drm_named_modes_whitelist[i]);
> > + if (ret != name_end)
> > + continue;
> > +
> > + strcpy(cmdline_mode->name, drm_named_modes_whitelist[i]);
> > + cmdline_mode->specified = true;
> > +
> > + return true;
> > + }
> > +
> > + return false;
>
> What's the point in returning a value, if it is never checked?
> Just make this function return void?

Yeah, it's something I went back and forth to between the dev, and it's
an artifact.

I'll drop that patch, take your version and move the refresh check to
drm_mode_parse_command_line_for_connector if that's alright for you?

Maxime


Attachments:
(No filename) (2.26 kB)
signature.asc (235.00 B)
Download all attachments

2022-08-16 14:10:44

by Maxime Ripard

[permalink] [raw]
Subject: Re: [PATCH v1 04/35] drm/modes: Introduce 480i and 576i modes

Hi Geert,

On Fri, Aug 12, 2022 at 03:18:58PM +0200, Geert Uytterhoeven wrote:
> Hi Maxime,
>
> Thanks for your patch!
>
> On Fri, Jul 29, 2022 at 6:35 PM Maxime Ripard <[email protected]> wrote:
> > Multiple drivers (meson, vc4) define the analog TV 525-lines and 625-lines
> > modes in the drivers.
>
> Nit: strictly speaking these are not analog modes, but the digital
> variants (ITU-R BT.656 and DVD-Video D1) of NTSC and PAL, using a
> 13.5 MHz sampling frequency for pixels.
>
> In analog modes, the only discrete values are the number of lines, and
> the frame/field rate (fixing the horizontal sync rate when combined).
>
> The number of (in)visible pixels per line depends on the available
> bandwidth. In a digital variant (which is anything generated by a
> digital computer system), the latter depends on the pixel clock, which
> can wildly differ from the 13.5 MHz used in the BT.656 standard. (e.g.
> Amiga uses 7.09/14.19/28.38 MHz (PAL) or 7.16/14.32/28.64 MHz (NTSC)).
>
> So I think we probably need some way to generate a PAL/NTSC-compatible
> mode based not only on resolution, but also on pixel clock.

This would also fix the comments made by Jani and Thomas, so I quite
like the idea of it.

I'm struggling a bit to find how would could implement this though.

From what you were saying, I guess the prototype would be something like

struct drm_display_mode *drm_create_analog_mode(unsigned int pixel_clock,
unsigned int lines,
unsigned int frame_rate)

But I have zero idea on what the implementation would be. Do you have
some resources for this you could point me to?

Thanks
Maxime


Attachments:
(No filename) (1.64 kB)
signature.asc (235.00 B)
Download all attachments

2022-08-16 14:56:01

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH v1 05/35] drm/connector: Add TV standard property

Hi Maxime,

On Tue, Aug 16, 2022 at 4:11 PM Maxime Ripard <[email protected]> wrote:
> On Tue, Aug 16, 2022 at 03:29:07PM +0200, Geert Uytterhoeven wrote:
> > On Tue, Aug 16, 2022 at 3:20 PM Maxime Ripard <[email protected]> wrote:
> > > On Fri, Aug 12, 2022 at 03:25:18PM +0200, Geert Uytterhoeven wrote:
> > > > > --- a/drivers/gpu/drm/drm_connector.c
> > > > > +++ b/drivers/gpu/drm/drm_connector.c
> > > > > @@ -1649,11 +1650,40 @@ EXPORT_SYMBOL(drm_mode_create_tv_margin_properties);
> > > > > * 0 on success or a negative error code on failure.
> > > > > */
> > > > > int drm_mode_create_tv_properties(struct drm_device *dev,
> > > > > + unsigned int supported_tv_norms,
> > > > > unsigned int num_modes,
> > > > > const char * const modes[])
> > > > > {
> > > > > + static const struct drm_prop_enum_list tv_norm_values[] = {
> > > > > + { __builtin_ffs(DRM_MODE_TV_NORM_NTSC_443) - 1, "NTSC-443" },
> > > > > + { __builtin_ffs(DRM_MODE_TV_NORM_NTSC_J) - 1, "NTSC-J" },
> > > > > + { __builtin_ffs(DRM_MODE_TV_NORM_NTSC_M) - 1, "NTSC-M" },
> > > > > + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_60) - 1, "PAL-60" },
> > > > > + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_B) - 1, "PAL-B" },
> > > > > + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_D) - 1, "PAL-D" },
> > > > > + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_G) - 1, "PAL-G" },
> > > > > + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_H) - 1, "PAL-H" },
> > > > > + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_I) - 1, "PAL-I" },
> > > > > + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_M) - 1, "PAL-M" },
> > > > > + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_N) - 1, "PAL-N" },
> > > > > + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_NC) - 1, "PAL-Nc" },
> > > > > + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_60) - 1, "SECAM-60" },
> > > > > + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_B) - 1, "SECAM-B" },
> > > > > + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_D) - 1, "SECAM-D" },
> > > > > + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_G) - 1, "SECAM-G" },
> > > > > + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_K) - 1, "SECAM-K" },
> > > > > + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_K1) - 1, "SECAM-K1" },
> > > > > + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_L) - 1, "SECAM-L" },
> > > >
> > > > The above are analog standards, with a variable horizontal resolution.
> > > >
> > > > > + { __builtin_ffs(DRM_MODE_TV_NORM_HD480I) - 1, "hd480i" },
> > > > > + { __builtin_ffs(DRM_MODE_TV_NORM_HD480P) - 1, "hd480p" },
> > > > > + { __builtin_ffs(DRM_MODE_TV_NORM_HD576I) - 1, "hd576i" },
> > > > > + { __builtin_ffs(DRM_MODE_TV_NORM_HD576P) - 1, "hd576p" },
> > > > > + { __builtin_ffs(DRM_MODE_TV_NORM_HD720P) - 1, "hd720p" },
> > > > > + { __builtin_ffs(DRM_MODE_TV_NORM_HD1080I) - 1, "hd1080i" },
> > > >
> > > > The above are digital standards, with a fixed resolution.
> > >
> > > Are they?
> > >
> > > It's not clear to me from looking at nouveau, but I was under the
> > > impression that they were modes for a component output, so CEA 770.3. I
> > > don't have the spec though, so I can't check.
> >
> > Oh right, I forgot about analog HD over component, where you can use
> > other pixel clocks than in the digital standard.
> >
> > > > You seem to have missed "hd1080p"?
> > >
> > > Nobody is using it. If we ever have a driver that uses it I think we can
> > > add it.
> >
> > The PS3 supports 1080p over component
> > https://manuals.playstation.net/document/en/ps3/current/settings/videooutput.html
>
> Yeah, and iirc the Xbox360 did too, but what I meant by nobody is using
> it is that there's no driver using it currently.

OK, it can be added later.

> > > > In addition, "hd720p", "hd080i", and "hd1080p" are available in both 50
> > > > and 60 (actually 59.94) Hz, while "hd1080p" can also use 24 or 25 Hz.
> > >
> > > It looks like nouveau only exposes modes for 480p at 59.94Hz, 576p at
> > > 50Hz, 720p at 60Hz, 1080i at 30Hz.
> >
> > PS3 supports both 50 and 60 Hz (same link above).
>
> I'm probably wary on this, but I'd rather stay at feature parity for
> this series. There's already plenty of occasion to screw up something
> that I'd rather not introduce new stuff I haven't been able to test :)
>
> Provided we can easily extend it to support these additional features of
> course :)
>
> > > > Either you have to add them here (e.g. "hd720p50" and "hd720p60"), or
> > > > handle them through "@<refresh>". The latter would impact "[PATCH v1
> > > > 09/35] drm/modes: Move named modes parsing to a separate function", as
> > > > currently a named mode and a refresh rate can't be specified both.
> > >
> > > I think the former would make more sense. It simplifies a bit the
> > > parser, and we're going to use a named mode anyway.
> > >
> > > > As "[PATCH v1 34/35] drm/modes: Introduce the tv_mode property as a
> > > > command-line option" uses a separate "tv_mode" option, and not the main
> > > > mode name, I think you want to add them here.
> > >
> > > It's a separate story I think, we could have a named mode hd720p50,
> > > which would be equivalent to 1280x720,tv_mode=hd720p
> >
> > So where's the field rate in "1280x720,tv_mode=hd720p"?
>
> Yeah, sorry I meant 1280x720@50,tv_mode=hd720p

Above you said "I think the former would make more sense", so that
should be "1280x720,tv_mode=hd720p50"?

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

2022-08-16 15:08:00

by Maxime Ripard

[permalink] [raw]
Subject: Re: [PATCH v1 05/35] drm/connector: Add TV standard property

On Tue, Aug 16, 2022 at 03:29:07PM +0200, Geert Uytterhoeven wrote:
> Hi Maxime,
>
> On Tue, Aug 16, 2022 at 3:20 PM Maxime Ripard <[email protected]> wrote:
> > On Fri, Aug 12, 2022 at 03:25:18PM +0200, Geert Uytterhoeven wrote:
> > > > --- a/drivers/gpu/drm/drm_connector.c
> > > > +++ b/drivers/gpu/drm/drm_connector.c
> > > > @@ -1649,11 +1650,40 @@ EXPORT_SYMBOL(drm_mode_create_tv_margin_properties);
> > > > * 0 on success or a negative error code on failure.
> > > > */
> > > > int drm_mode_create_tv_properties(struct drm_device *dev,
> > > > + unsigned int supported_tv_norms,
> > > > unsigned int num_modes,
> > > > const char * const modes[])
> > > > {
> > > > + static const struct drm_prop_enum_list tv_norm_values[] = {
> > > > + { __builtin_ffs(DRM_MODE_TV_NORM_NTSC_443) - 1, "NTSC-443" },
> > > > + { __builtin_ffs(DRM_MODE_TV_NORM_NTSC_J) - 1, "NTSC-J" },
> > > > + { __builtin_ffs(DRM_MODE_TV_NORM_NTSC_M) - 1, "NTSC-M" },
> > > > + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_60) - 1, "PAL-60" },
> > > > + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_B) - 1, "PAL-B" },
> > > > + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_D) - 1, "PAL-D" },
> > > > + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_G) - 1, "PAL-G" },
> > > > + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_H) - 1, "PAL-H" },
> > > > + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_I) - 1, "PAL-I" },
> > > > + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_M) - 1, "PAL-M" },
> > > > + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_N) - 1, "PAL-N" },
> > > > + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_NC) - 1, "PAL-Nc" },
> > > > + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_60) - 1, "SECAM-60" },
> > > > + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_B) - 1, "SECAM-B" },
> > > > + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_D) - 1, "SECAM-D" },
> > > > + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_G) - 1, "SECAM-G" },
> > > > + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_K) - 1, "SECAM-K" },
> > > > + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_K1) - 1, "SECAM-K1" },
> > > > + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_L) - 1, "SECAM-L" },
> > >
> > > The above are analog standards, with a variable horizontal resolution.
> > >
> > > > + { __builtin_ffs(DRM_MODE_TV_NORM_HD480I) - 1, "hd480i" },
> > > > + { __builtin_ffs(DRM_MODE_TV_NORM_HD480P) - 1, "hd480p" },
> > > > + { __builtin_ffs(DRM_MODE_TV_NORM_HD576I) - 1, "hd576i" },
> > > > + { __builtin_ffs(DRM_MODE_TV_NORM_HD576P) - 1, "hd576p" },
> > > > + { __builtin_ffs(DRM_MODE_TV_NORM_HD720P) - 1, "hd720p" },
> > > > + { __builtin_ffs(DRM_MODE_TV_NORM_HD1080I) - 1, "hd1080i" },
> > >
> > > The above are digital standards, with a fixed resolution.
> >
> > Are they?
> >
> > It's not clear to me from looking at nouveau, but I was under the
> > impression that they were modes for a component output, so CEA 770.3. I
> > don't have the spec though, so I can't check.
>
> Oh right, I forgot about analog HD over component, where you can use
> other pixel clocks than in the digital standard.
>
> > > You seem to have missed "hd1080p"?
> >
> > Nobody is using it. If we ever have a driver that uses it I think we can
> > add it.
>
> The PS3 supports 1080p over component
> https://manuals.playstation.net/document/en/ps3/current/settings/videooutput.html

Yeah, and iirc the Xbox360 did too, but what I meant by nobody is using
it is that there's no driver using it currently.

> > > In addition, "hd720p", "hd080i", and "hd1080p" are available in both 50
> > > and 60 (actually 59.94) Hz, while "hd1080p" can also use 24 or 25 Hz.
> >
> > It looks like nouveau only exposes modes for 480p at 59.94Hz, 576p at
> > 50Hz, 720p at 60Hz, 1080i at 30Hz.
>
> PS3 supports both 50 and 60 Hz (same link above).

I'm probably wary on this, but I'd rather stay at feature parity for
this series. There's already plenty of occasion to screw up something
that I'd rather not introduce new stuff I haven't been able to test :)

Provided we can easily extend it to support these additional features of
course :)

> > > Either you have to add them here (e.g. "hd720p50" and "hd720p60"), or
> > > handle them through "@<refresh>". The latter would impact "[PATCH v1
> > > 09/35] drm/modes: Move named modes parsing to a separate function", as
> > > currently a named mode and a refresh rate can't be specified both.
> >
> > I think the former would make more sense. It simplifies a bit the
> > parser, and we're going to use a named mode anyway.
> >
> > > As "[PATCH v1 34/35] drm/modes: Introduce the tv_mode property as a
> > > command-line option" uses a separate "tv_mode" option, and not the main
> > > mode name, I think you want to add them here.
> >
> > It's a separate story I think, we could have a named mode hd720p50,
> > which would be equivalent to 1280x720,tv_mode=hd720p
>
> So where's the field rate in "1280x720,tv_mode=hd720p"?

Yeah, sorry I meant 1280x720@50,tv_mode=hd720p

Maxime


Attachments:
(No filename) (5.28 kB)
signature.asc (235.00 B)
Download all attachments

2022-08-16 15:08:02

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH v1 09/35] drm/modes: Move named modes parsing to a separate function

Hi Maxime,

On Tue, Aug 16, 2022 at 3:46 PM Maxime Ripard <[email protected]> wrote:
> On Fri, Aug 12, 2022 at 03:27:17PM +0200, Geert Uytterhoeven wrote:
> > On Fri, Jul 29, 2022 at 6:36 PM Maxime Ripard <[email protected]> wrote:
> > > 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.
> > >
> > > Signed-off-by: Maxime Ripard <[email protected]>
> >
> > Thanks for your patch, which looks similar to my "[PATCH v2 2/5]
> > drm/modes: Extract drm_mode_parse_cmdline_named_mode()"
> > (https://lore.kernel.org/dri-devel/1371554419ae63cb54c2a377db0c1016fcf200bb.1657788997.git.geert@linux-m68k.org
> > ;-)
>
> Indeed, I forgot about that one, sorry :/
>
> I think I'd still prefer to have the check for refresh + named mode
> outside of the function, since I see them as an "integration" issue, not
> a parsing one.
>
> It's not the named mode parsing that fails, but the fact that we both
> have a valid refresh and a valid named mode.
>
> >
> > > --- a/drivers/gpu/drm/drm_modes.c
> > > +++ b/drivers/gpu/drm/drm_modes.c
> > > @@ -1773,6 +1773,28 @@ static const char * const drm_named_modes_whitelist[] = {
> > > "PAL",
> > > };
> > >
> > > +static bool drm_mode_parse_cmdline_named_mode(const char *name,
> > > + unsigned int name_end,
> > > + struct drm_cmdline_mode *cmdline_mode)
> > > +{
> > > + unsigned int i;
> > > +
> > > + for (i = 0; i < ARRAY_SIZE(drm_named_modes_whitelist); i++) {
> > > + int ret;
> > > +
> > > + ret = str_has_prefix(name, drm_named_modes_whitelist[i]);
> > > + if (ret != name_end)
> > > + continue;
> > > +
> > > + strcpy(cmdline_mode->name, drm_named_modes_whitelist[i]);
> > > + cmdline_mode->specified = true;
> > > +
> > > + return true;
> > > + }
> > > +
> > > + return false;
> >
> > What's the point in returning a value, if it is never checked?
> > Just make this function return void?
>
> Yeah, it's something I went back and forth to between the dev, and it's
> an artifact.
>
> I'll drop that patch, take your version and move the refresh check to
> drm_mode_parse_command_line_for_connector if that's alright for you?

Fine for me.

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

2022-08-16 15:13:55

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH v1 04/35] drm/modes: Introduce 480i and 576i modes

Hi Maxime,

On Tue, Aug 16, 2022 at 3:26 PM Maxime Ripard <[email protected]> wrote:
> On Fri, Aug 12, 2022 at 03:18:58PM +0200, Geert Uytterhoeven wrote:
> > On Fri, Jul 29, 2022 at 6:35 PM Maxime Ripard <[email protected]> wrote:
> > > Multiple drivers (meson, vc4) define the analog TV 525-lines and 625-lines
> > > modes in the drivers.
> >
> > Nit: strictly speaking these are not analog modes, but the digital
> > variants (ITU-R BT.656 and DVD-Video D1) of NTSC and PAL, using a
> > 13.5 MHz sampling frequency for pixels.
> >
> > In analog modes, the only discrete values are the number of lines, and
> > the frame/field rate (fixing the horizontal sync rate when combined).
> >
> > The number of (in)visible pixels per line depends on the available
> > bandwidth. In a digital variant (which is anything generated by a
> > digital computer system), the latter depends on the pixel clock, which
> > can wildly differ from the 13.5 MHz used in the BT.656 standard. (e.g.
> > Amiga uses 7.09/14.19/28.38 MHz (PAL) or 7.16/14.32/28.64 MHz (NTSC)).
> >
> > So I think we probably need some way to generate a PAL/NTSC-compatible
> > mode based not only on resolution, but also on pixel clock.
>
> This would also fix the comments made by Jani and Thomas, so I quite
> like the idea of it.
>
> I'm struggling a bit to find how would could implement this though.
>
> From what you were saying, I guess the prototype would be something like
>
> struct drm_display_mode *drm_create_analog_mode(unsigned int pixel_clock,
> unsigned int lines,
> unsigned int frame_rate)
>
> But I have zero idea on what the implementation would be. Do you have
> some resources for this you could point me to?

Horizontally, I think you should calculate left/right margins and
hsync length to yield timings that match those for the BT.656 PAL/NTSC
modes. I.e. when a 640x512 mode with a pixel clock of 14 MHz is
requested, you want to calculate left', right', and hslen' for

| <---- left' ---> | <- 640 pixels -> | <---- right' ---> | <--- hslen' --> |
@ 14 MHz

so they match the timings for left, right, and hslen for

| <--- left ---> | <--- 720 pixels ---> | <--- right ---> | <--- hslen ---> |
@ 13.5 MHz

As 640 pixels @ 14 MHz are less wide than 720 pixels @ 13.5 MHz,
you want to make sure to align the center of the visible part.

Vertically, it's simpler, as the number of lines is discrete.
You do have to take into account interlace and doublescan, and
progressive modes with 262/312 lines.

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

2022-08-16 16:09:10

by Maxime Ripard

[permalink] [raw]
Subject: Re: [PATCH v1 05/35] drm/connector: Add TV standard property

On Tue, Aug 16, 2022 at 04:43:44PM +0200, Geert Uytterhoeven wrote:
> > > > > Either you have to add them here (e.g. "hd720p50" and "hd720p60"), or
> > > > > handle them through "@<refresh>". The latter would impact "[PATCH v1
> > > > > 09/35] drm/modes: Move named modes parsing to a separate function", as
> > > > > currently a named mode and a refresh rate can't be specified both.
> > > >
> > > > I think the former would make more sense. It simplifies a bit the
> > > > parser, and we're going to use a named mode anyway.
> > > >
> > > > > As "[PATCH v1 34/35] drm/modes: Introduce the tv_mode property as a
> > > > > command-line option" uses a separate "tv_mode" option, and not the main
> > > > > mode name, I think you want to add them here.
> > > >
> > > > It's a separate story I think, we could have a named mode hd720p50,
> > > > which would be equivalent to 1280x720,tv_mode=hd720p
> > >
> > > So where's the field rate in "1280x720,tv_mode=hd720p"?
> >
> > Yeah, sorry I meant 1280x720@50,tv_mode=hd720p
>
> Above you said "I think the former would make more sense", so that
> should be "1280x720,tv_mode=hd720p50"?

No, 720p at 50Hz would be either hd720p50 or 1280x720@50,tv_mode=hd720p
and 60Hz would be hd720p60 or 1280x720@60,tv_mode=hd720p

Maxime


Attachments:
(No filename) (1.27 kB)
signature.asc (235.00 B)
Download all attachments

2022-08-16 20:16:12

by Noralf Trønnes

[permalink] [raw]
Subject: Re: [PATCH v1 05/35] drm/connector: Add TV standard property



Den 16.08.2022 11.49, skrev Maxime Ripard:
> On Tue, Aug 16, 2022 at 11:42:20AM +0200, Noralf Trønnes wrote:
>>
>>
>> Den 16.08.2022 10.26, skrev Maxime Ripard:
>>> Hi,
>>>
>>> On Mon, Aug 08, 2022 at 02:44:56PM +0200, Noralf Trønnes wrote:
>>>> Den 29.07.2022 18.34, skrev Maxime Ripard:
>>>>> 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 <[email protected]>
>>>>>
>>>>
>>>> Please also update Documentation/gpu/kms-properties.csv
>>>>
>>>> Requirements for adding a new property is found in
>>>> Documentation/gpu/drm-kms.rst
>>>
>>> I knew this was going to be raised at some point, so I'm glad it's that
>>> early :)
>>>
>>> I really don't know what to do there. If we stick by our usual rules,
>>> then we can't have any of that work merged.
>>>
>>> However, I think the status quo is not really satisfactory either.
>>> Indeed, we have a property, that doesn't follow those requirements
>>> either, with a driver-specific content, and that stands in the way of
>>> fixes and further improvements at both the core framework and driver
>>> levels.
>>>
>>> So having that new property still seems like a net improvement at the
>>> driver, framework and uAPI levels, even if it's not entirely following
>>> the requirements we have in place.
>>>
>>> Even more so since, realistically, those kind of interfaces will never
>>> get any new development on the user-space side of things, it's
>>> considered by everyone as legacy.
>>>
>>> This also is something we need to support at some point if we want to
>>> completely deprecate the fbdev drivers and provide decent alternatives
>>> in KMS.
>>>
>>> So yeah, strictly speaking, we would not qualify for our requirements
>>> there. I still think we have a strong case for an exception though.
>>
>> Which requirements would that be? The only one I can see is the
>> documentation and maybe an IGT test.
>
> This is the one I had in mind
> https://dri.freedesktop.org/docs/drm/gpu/drm-uapi.html#open-source-userspace-requirements
>

Oh right, I had forgotten about that one.

One benefit of having a userspace implementation is that it increases
the chance of widespread adoption having a working implementation to
look at. I don't think the reason tv.mode is not used anywhere (that I
know of) is because the driver picks the enum values resulting in no
standard names. It's a niche thing and way down on the todo list.
nouveau and ch7006 has a tv_norm module parameter which certainly
doesn't help in moving people/projects over to the DRM property
(downstream rpi also has it now).

mpv[1] is a commandline media player that after a quick look might be a
candidate for implementing the property without too much effort.

How do you test the property? I've used modetest but I can only change
to a tv.mode that matches the current display mode. I can't switch from
ntsc to pal for instance.

I have tried changing mode on rpi-5.15 (which I will switch to for the
gud gadget), but I always end up with flip timeouts when changing the value:

$ cat /proc/cpuinfo | grep Model
Model : Raspberry Pi 4 Model B Rev 1.1
$ uname -a
Linux pi4t 5.15.56-v7l+ #1575 SMP Fri Jul 22 20:29:46 BST 2022 armv7l
GNU/Linux
$ sudo dmesg -C
$ modetest -M vc4 -s 45:720x480i -w 45:mode:1
setting mode 720x480i-29.97Hz on connectors 45, crtc 73
failed to set gamma: Function not implemented

$ dmesg
$ modetest -M vc4 -s 45:720x480i -w 45:mode:0
setting mode 720x480i-29.97Hz on connectors 45, crtc 73
failed to set gamma: Function not implemented

$ dmesg
[ 95.193059] [drm:drm_atomic_helper_wait_for_flip_done
[drm_kms_helper]] *ERROR* [CRTC:73:crtc-1] flip_done timed out
[ 105.433112] [drm:drm_crtc_commit_wait [drm]] *ERROR* flip_done timed out
[ 105.433519] [drm:drm_atomic_helper_wait_for_dependencies
[drm_kms_helper]] *ERROR* [CRTC:73:crtc-1] commit wait timed out
[ 115.673095] [drm:drm_crtc_commit_wait [drm]] *ERROR* flip_done timed out
[ 115.673498] [drm:drm_atomic_helper_wait_for_dependencies
[drm_kms_helper]] *ERROR* [PLANE:63:plane-1] commit wait timed out
[ 125.913106] [drm:drm_crtc_commit_wait [drm]] *ERROR* flip_done timed out
[ 125.913510] vc4-drm gpu: [drm] *ERROR* Timed out waiting for commit
[ 136.153411] [drm:drm_atomic_helper_wait_for_flip_done
[drm_kms_helper]] *ERROR* [CRTC:73:crtc-1] flip_done timed out

I doesn't help to reload vc4, I have to reboot to get it working again.
I get this when reloading:
[ 776.799784] vc4_vec fec13000.vec: Unbalanced pm_runtime_enable!

I know this was working in rpi-5.10 on the Pi Zero (Pi4 tvout using vc4
did not work at all when I tried).


Noralf.

[1] https://mpv.io/
https://github.com/mpv-player/mpv/blob/master/video/out/drm_common.c
https://github.com/mpv-player/mpv/blob/master/video/out/drm_atomic.c

2022-08-17 08:01:02

by Maxime Ripard

[permalink] [raw]
Subject: Re: [PATCH v1 05/35] drm/connector: Add TV standard property

On Wed, Aug 17, 2022 at 09:31:18AM +0200, Geert Uytterhoeven wrote:
> Hi Maxime,
>
> On Tue, Aug 16, 2022 at 5:50 PM Maxime Ripard <[email protected]> wrote:
> > On Tue, Aug 16, 2022 at 04:43:44PM +0200, Geert Uytterhoeven wrote:
> > > > > > > Either you have to add them here (e.g. "hd720p50" and "hd720p60"), or
> > > > > > > handle them through "@<refresh>". The latter would impact "[PATCH v1
> > > > > > > 09/35] drm/modes: Move named modes parsing to a separate function", as
> > > > > > > currently a named mode and a refresh rate can't be specified both.
> > > > > >
> > > > > > I think the former would make more sense. It simplifies a bit the
> > > > > > parser, and we're going to use a named mode anyway.
> > > > > >
> > > > > > > As "[PATCH v1 34/35] drm/modes: Introduce the tv_mode property as a
> > > > > > > command-line option" uses a separate "tv_mode" option, and not the main
> > > > > > > mode name, I think you want to add them here.
> > > > > >
> > > > > > It's a separate story I think, we could have a named mode hd720p50,
> > > > > > which would be equivalent to 1280x720,tv_mode=hd720p
> > > > >
> > > > > So where's the field rate in "1280x720,tv_mode=hd720p"?
> > > >
> > > > Yeah, sorry I meant 1280x720@50,tv_mode=hd720p
> > >
> > > Above you said "I think the former would make more sense", so that
> > > should be "1280x720,tv_mode=hd720p50"?
> >
> > No, 720p at 50Hz would be either hd720p50 or 1280x720@50,tv_mode=hd720p
> > and 60Hz would be hd720p60 or 1280x720@60,tv_mode=hd720p
>
> I disagree: hd720p50 and hd720p60 are different TV modes.

I agree, and I don't see how that command-line doesn't express that?

Maxime


Attachments:
(No filename) (1.66 kB)
signature.asc (235.00 B)
Download all attachments

2022-08-17 08:03:59

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH v1 05/35] drm/connector: Add TV standard property

Hi Maxime,

On Tue, Aug 16, 2022 at 5:50 PM Maxime Ripard <[email protected]> wrote:
> On Tue, Aug 16, 2022 at 04:43:44PM +0200, Geert Uytterhoeven wrote:
> > > > > > Either you have to add them here (e.g. "hd720p50" and "hd720p60"), or
> > > > > > handle them through "@<refresh>". The latter would impact "[PATCH v1
> > > > > > 09/35] drm/modes: Move named modes parsing to a separate function", as
> > > > > > currently a named mode and a refresh rate can't be specified both.
> > > > >
> > > > > I think the former would make more sense. It simplifies a bit the
> > > > > parser, and we're going to use a named mode anyway.
> > > > >
> > > > > > As "[PATCH v1 34/35] drm/modes: Introduce the tv_mode property as a
> > > > > > command-line option" uses a separate "tv_mode" option, and not the main
> > > > > > mode name, I think you want to add them here.
> > > > >
> > > > > It's a separate story I think, we could have a named mode hd720p50,
> > > > > which would be equivalent to 1280x720,tv_mode=hd720p
> > > >
> > > > So where's the field rate in "1280x720,tv_mode=hd720p"?
> > >
> > > Yeah, sorry I meant 1280x720@50,tv_mode=hd720p
> >
> > Above you said "I think the former would make more sense", so that
> > should be "1280x720,tv_mode=hd720p50"?
>
> No, 720p at 50Hz would be either hd720p50 or 1280x720@50,tv_mode=hd720p
> and 60Hz would be hd720p60 or 1280x720@60,tv_mode=hd720p

I disagree: hd720p50 and hd720p60 are different TV modes.
Treating them the same would be similar to treating unmodulated (e.g.
component) PAL-N (25 frames/s) and PAL-M (30 frames/s) the same.

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

2022-08-17 08:07:38

by Maxime Ripard

[permalink] [raw]
Subject: Re: [PATCH v1 04/35] drm/modes: Introduce 480i and 576i modes

On Tue, Aug 16, 2022 at 05:00:38PM +0200, Geert Uytterhoeven wrote:
> Hi Maxime,
>
> On Tue, Aug 16, 2022 at 3:26 PM Maxime Ripard <[email protected]> wrote:
> > On Fri, Aug 12, 2022 at 03:18:58PM +0200, Geert Uytterhoeven wrote:
> > > On Fri, Jul 29, 2022 at 6:35 PM Maxime Ripard <[email protected]> wrote:
> > > > Multiple drivers (meson, vc4) define the analog TV 525-lines and 625-lines
> > > > modes in the drivers.
> > >
> > > Nit: strictly speaking these are not analog modes, but the digital
> > > variants (ITU-R BT.656 and DVD-Video D1) of NTSC and PAL, using a
> > > 13.5 MHz sampling frequency for pixels.
> > >
> > > In analog modes, the only discrete values are the number of lines, and
> > > the frame/field rate (fixing the horizontal sync rate when combined).
> > >
> > > The number of (in)visible pixels per line depends on the available
> > > bandwidth. In a digital variant (which is anything generated by a
> > > digital computer system), the latter depends on the pixel clock, which
> > > can wildly differ from the 13.5 MHz used in the BT.656 standard. (e.g.
> > > Amiga uses 7.09/14.19/28.38 MHz (PAL) or 7.16/14.32/28.64 MHz (NTSC)).
> > >
> > > So I think we probably need some way to generate a PAL/NTSC-compatible
> > > mode based not only on resolution, but also on pixel clock.
> >
> > This would also fix the comments made by Jani and Thomas, so I quite
> > like the idea of it.
> >
> > I'm struggling a bit to find how would could implement this though.
> >
> > From what you were saying, I guess the prototype would be something like
> >
> > struct drm_display_mode *drm_create_analog_mode(unsigned int pixel_clock,
> > unsigned int lines,
> > unsigned int frame_rate)
> >
> > But I have zero idea on what the implementation would be. Do you have
> > some resources for this you could point me to?
>
> Horizontally, I think you should calculate left/right margins and
> hsync length to yield timings that match those for the BT.656 PAL/NTSC
> modes. I.e. when a 640x512 mode with a pixel clock of 14 MHz is
> requested, you want to calculate left', right', and hslen' for
>
> | <---- left' ---> | <- 640 pixels -> | <---- right' ---> | <--- hslen' --> |
> @ 14 MHz
>
> so they match the timings for left, right, and hslen for
>
> | <--- left ---> | <--- 720 pixels ---> | <--- right ---> | <--- hslen ---> |
> @ 13.5 MHz
>
> As 640 pixels @ 14 MHz are less wide than 720 pixels @ 13.5 MHz,
> you want to make sure to align the center of the visible part.

So I guess in that example if we want to center it, left == right and
left' == right'? What about the sync length?

> Vertically, it's simpler, as the number of lines is discrete.
> You do have to take into account interlace and doublescan, and
> progressive modes with 262/312 lines.

So we only have to deal with 525 and 625 lines total (without taking
interlace and doublescan into account), right?

I guess we still have the same question, we probably want to center it,
so top == bottom, but what about the vsync length?

Maxime


Attachments:
(No filename) (3.17 kB)
signature.asc (235.00 B)
Download all attachments

2022-08-17 08:10:08

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH v1 05/35] drm/connector: Add TV standard property

On Wed, Aug 17, 2022 at 9:31 AM Geert Uytterhoeven <[email protected]> wrote:
> On Tue, Aug 16, 2022 at 5:50 PM Maxime Ripard <[email protected]> wrote:
> > On Tue, Aug 16, 2022 at 04:43:44PM +0200, Geert Uytterhoeven wrote:
> > > > > > > Either you have to add them here (e.g. "hd720p50" and "hd720p60"), or
> > > > > > > handle them through "@<refresh>". The latter would impact "[PATCH v1
> > > > > > > 09/35] drm/modes: Move named modes parsing to a separate function", as
> > > > > > > currently a named mode and a refresh rate can't be specified both.
> > > > > >
> > > > > > I think the former would make more sense. It simplifies a bit the
> > > > > > parser, and we're going to use a named mode anyway.
> > > > > >
> > > > > > > As "[PATCH v1 34/35] drm/modes: Introduce the tv_mode property as a
> > > > > > > command-line option" uses a separate "tv_mode" option, and not the main
> > > > > > > mode name, I think you want to add them here.
> > > > > >
> > > > > > It's a separate story I think, we could have a named mode hd720p50,
> > > > > > which would be equivalent to 1280x720,tv_mode=hd720p
> > > > >
> > > > > So where's the field rate in "1280x720,tv_mode=hd720p"?
> > > >
> > > > Yeah, sorry I meant 1280x720@50,tv_mode=hd720p
> > >
> > > Above you said "I think the former would make more sense", so that
> > > should be "1280x720,tv_mode=hd720p50"?
> >
> > No, 720p at 50Hz would be either hd720p50 or 1280x720@50,tv_mode=hd720p
> > and 60Hz would be hd720p60 or 1280x720@60,tv_mode=hd720p
>
> I disagree: hd720p50 and hd720p60 are different TV modes.
> Treating them the same would be similar to treating unmodulated (e.g.
> component) PAL-N (25 frames/s) and PAL-M (30 frames/s) the same.

IIRC from my PS3 -Linux days, not all HD(-Ready) TVs supported both
hd720p50 and hd720p60.

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

2022-08-17 09:08:28

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH v1 04/35] drm/modes: Introduce 480i and 576i modes

Hi Maxime,

On Wed, Aug 17, 2022 at 9:54 AM Maxime Ripard <[email protected]> wrote:
> On Tue, Aug 16, 2022 at 05:00:38PM +0200, Geert Uytterhoeven wrote:
> > On Tue, Aug 16, 2022 at 3:26 PM Maxime Ripard <[email protected]> wrote:
> > > On Fri, Aug 12, 2022 at 03:18:58PM +0200, Geert Uytterhoeven wrote:
> > > > On Fri, Jul 29, 2022 at 6:35 PM Maxime Ripard <[email protected]> wrote:
> > > > > Multiple drivers (meson, vc4) define the analog TV 525-lines and 625-lines
> > > > > modes in the drivers.
> > > >
> > > > Nit: strictly speaking these are not analog modes, but the digital
> > > > variants (ITU-R BT.656 and DVD-Video D1) of NTSC and PAL, using a
> > > > 13.5 MHz sampling frequency for pixels.
> > > >
> > > > In analog modes, the only discrete values are the number of lines, and
> > > > the frame/field rate (fixing the horizontal sync rate when combined).
> > > >
> > > > The number of (in)visible pixels per line depends on the available
> > > > bandwidth. In a digital variant (which is anything generated by a
> > > > digital computer system), the latter depends on the pixel clock, which
> > > > can wildly differ from the 13.5 MHz used in the BT.656 standard. (e.g.
> > > > Amiga uses 7.09/14.19/28.38 MHz (PAL) or 7.16/14.32/28.64 MHz (NTSC)).
> > > >
> > > > So I think we probably need some way to generate a PAL/NTSC-compatible
> > > > mode based not only on resolution, but also on pixel clock.
> > >
> > > This would also fix the comments made by Jani and Thomas, so I quite
> > > like the idea of it.
> > >
> > > I'm struggling a bit to find how would could implement this though.
> > >
> > > From what you were saying, I guess the prototype would be something like
> > >
> > > struct drm_display_mode *drm_create_analog_mode(unsigned int pixel_clock,
> > > unsigned int lines,
> > > unsigned int frame_rate)
> > >
> > > But I have zero idea on what the implementation would be. Do you have
> > > some resources for this you could point me to?
> >
> > Horizontally, I think you should calculate left/right margins and
> > hsync length to yield timings that match those for the BT.656 PAL/NTSC
> > modes. I.e. when a 640x512 mode with a pixel clock of 14 MHz is
> > requested, you want to calculate left', right', and hslen' for
> >
> > | <---- left' ---> | <- 640 pixels -> | <---- right' ---> | <--- hslen' --> |
> > @ 14 MHz
> >
> > so they match the timings for left, right, and hslen for
> >
> > | <--- left ---> | <--- 720 pixels ---> | <--- right ---> | <--- hslen ---> |
> > @ 13.5 MHz
> >
> > As 640 pixels @ 14 MHz are less wide than 720 pixels @ 13.5 MHz,
> > you want to make sure to align the center of the visible part.
>
> So I guess in that example if we want to center it, left == right and
> left' == right'? What about the sync length?

No, left and right are asymmetrical, cfr. front and back porch in
https://en.wikipedia.org/wiki/PAL#PAL_signal_details
I.e. if the pixel part is reduced, both the left and right margins
should be increased by the same amount.

From the table linked above, hslen should be ca. 4.7µs (fixed).

> > Vertically, it's simpler, as the number of lines is discrete.
> > You do have to take into account interlace and doublescan, and
> > progressive modes with 262/312 lines.
>
> So we only have to deal with 525 and 625 lines total (without taking
> interlace and doublescan into account), right?

Yes.

> I guess we still have the same question, we probably want to center it,
> so top == bottom, but what about the vsync length?

Unfortunately that table does not mention top and bottom margins.
But according to drivers/video/fbdev/amifb.c (see the "Broadcast
video timings" comment block and the definitions of the "ntsc-lace"
and "pal-lace" video modes), they are asymmetrical, too.

Vsync length is 0.576ms, so that's 9 scan lines (I guess I didn't
have that info when I wrote amifb, as I used 4 lines there).

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

2022-08-17 09:25:14

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH v1 05/35] drm/connector: Add TV standard property

Hi Maxime,

On Wed, Aug 17, 2022 at 9:47 AM Maxime Ripard <[email protected]> wrote:
> On Wed, Aug 17, 2022 at 09:31:18AM +0200, Geert Uytterhoeven wrote:
> > On Tue, Aug 16, 2022 at 5:50 PM Maxime Ripard <[email protected]> wrote:
> > > On Tue, Aug 16, 2022 at 04:43:44PM +0200, Geert Uytterhoeven wrote:
> > > > > > > > Either you have to add them here (e.g. "hd720p50" and "hd720p60"), or
> > > > > > > > handle them through "@<refresh>". The latter would impact "[PATCH v1
> > > > > > > > 09/35] drm/modes: Move named modes parsing to a separate function", as
> > > > > > > > currently a named mode and a refresh rate can't be specified both.
> > > > > > >
> > > > > > > I think the former would make more sense. It simplifies a bit the
> > > > > > > parser, and we're going to use a named mode anyway.
> > > > > > >
> > > > > > > > As "[PATCH v1 34/35] drm/modes: Introduce the tv_mode property as a
> > > > > > > > command-line option" uses a separate "tv_mode" option, and not the main
> > > > > > > > mode name, I think you want to add them here.
> > > > > > >
> > > > > > > It's a separate story I think, we could have a named mode hd720p50,
> > > > > > > which would be equivalent to 1280x720,tv_mode=hd720p
> > > > > >
> > > > > > So where's the field rate in "1280x720,tv_mode=hd720p"?
> > > > >
> > > > > Yeah, sorry I meant 1280x720@50,tv_mode=hd720p
> > > >
> > > > Above you said "I think the former would make more sense", so that
> > > > should be "1280x720,tv_mode=hd720p50"?
> > >
> > > No, 720p at 50Hz would be either hd720p50 or 1280x720@50,tv_mode=hd720p
> > > and 60Hz would be hd720p60 or 1280x720@60,tv_mode=hd720p
> >
> > I disagree: hd720p50 and hd720p60 are different TV modes.
>
> I agree, and I don't see how that command-line doesn't express that?

Oh, I see what you mean: yes, it expresses that.
But it is inconsistent with the NTSC/PAL/SECAM/hd{480,576}[ip] modes,
where the TV mode specifies both number of lines and frame rate.

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

2022-08-17 11:24:52

by Maxime Ripard

[permalink] [raw]
Subject: Re: [PATCH v1 05/35] drm/connector: Add TV standard property

On Wed, Aug 17, 2022 at 10:35:07AM +0200, Geert Uytterhoeven wrote:
> Hi Maxime,
>
> On Wed, Aug 17, 2022 at 9:47 AM Maxime Ripard <[email protected]> wrote:
> > On Wed, Aug 17, 2022 at 09:31:18AM +0200, Geert Uytterhoeven wrote:
> > > On Tue, Aug 16, 2022 at 5:50 PM Maxime Ripard <[email protected]> wrote:
> > > > On Tue, Aug 16, 2022 at 04:43:44PM +0200, Geert Uytterhoeven wrote:
> > > > > > > > > Either you have to add them here (e.g. "hd720p50" and "hd720p60"), or
> > > > > > > > > handle them through "@<refresh>". The latter would impact "[PATCH v1
> > > > > > > > > 09/35] drm/modes: Move named modes parsing to a separate function", as
> > > > > > > > > currently a named mode and a refresh rate can't be specified both.
> > > > > > > >
> > > > > > > > I think the former would make more sense. It simplifies a bit the
> > > > > > > > parser, and we're going to use a named mode anyway.
> > > > > > > >
> > > > > > > > > As "[PATCH v1 34/35] drm/modes: Introduce the tv_mode property as a
> > > > > > > > > command-line option" uses a separate "tv_mode" option, and not the main
> > > > > > > > > mode name, I think you want to add them here.
> > > > > > > >
> > > > > > > > It's a separate story I think, we could have a named mode hd720p50,
> > > > > > > > which would be equivalent to 1280x720,tv_mode=hd720p
> > > > > > >
> > > > > > > So where's the field rate in "1280x720,tv_mode=hd720p"?
> > > > > >
> > > > > > Yeah, sorry I meant 1280x720@50,tv_mode=hd720p
> > > > >
> > > > > Above you said "I think the former would make more sense", so that
> > > > > should be "1280x720,tv_mode=hd720p50"?
> > > >
> > > > No, 720p at 50Hz would be either hd720p50 or 1280x720@50,tv_mode=hd720p
> > > > and 60Hz would be hd720p60 or 1280x720@60,tv_mode=hd720p
> > >
> > > I disagree: hd720p50 and hd720p60 are different TV modes.
> >
> > I agree, and I don't see how that command-line doesn't express that?
>
> Oh, I see what you mean: yes, it expresses that.
> But it is inconsistent with the NTSC/PAL/SECAM/hd{480,576}[ip] modes,
> where the TV mode specifies both number of lines and frame rate.

Only if we're using a named mode, and naming is hard :)

Honestly, I'd be inclined to drop the hd* for now from this series. I
don't have a hardware to test it with, for some we don't even have
drivers that could implement these modes, we don't have a spec to work
from, it looks like a recipe for failure :)

Maxime


Attachments:
(No filename) (2.42 kB)
signature.asc (235.00 B)
Download all attachments

2022-08-17 11:55:47

by Maxime Ripard

[permalink] [raw]
Subject: Re: [PATCH v1 05/35] drm/connector: Add TV standard property

On Tue, Aug 16, 2022 at 09:35:24PM +0200, Noralf Tr?nnes wrote:
> Den 16.08.2022 11.49, skrev Maxime Ripard:
> > On Tue, Aug 16, 2022 at 11:42:20AM +0200, Noralf Tr?nnes wrote:
> >> Den 16.08.2022 10.26, skrev Maxime Ripard:
> >>> Hi,
> >>>
> >>> On Mon, Aug 08, 2022 at 02:44:56PM +0200, Noralf Tr?nnes wrote:
> >>>> Den 29.07.2022 18.34, skrev Maxime Ripard:
> >>>>> 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 <[email protected]>
> >>>>>
> >>>>
> >>>> Please also update Documentation/gpu/kms-properties.csv
> >>>>
> >>>> Requirements for adding a new property is found in
> >>>> Documentation/gpu/drm-kms.rst
> >>>
> >>> I knew this was going to be raised at some point, so I'm glad it's that
> >>> early :)
> >>>
> >>> I really don't know what to do there. If we stick by our usual rules,
> >>> then we can't have any of that work merged.
> >>>
> >>> However, I think the status quo is not really satisfactory either.
> >>> Indeed, we have a property, that doesn't follow those requirements
> >>> either, with a driver-specific content, and that stands in the way of
> >>> fixes and further improvements at both the core framework and driver
> >>> levels.
> >>>
> >>> So having that new property still seems like a net improvement at the
> >>> driver, framework and uAPI levels, even if it's not entirely following
> >>> the requirements we have in place.
> >>>
> >>> Even more so since, realistically, those kind of interfaces will never
> >>> get any new development on the user-space side of things, it's
> >>> considered by everyone as legacy.
> >>>
> >>> This also is something we need to support at some point if we want to
> >>> completely deprecate the fbdev drivers and provide decent alternatives
> >>> in KMS.
> >>>
> >>> So yeah, strictly speaking, we would not qualify for our requirements
> >>> there. I still think we have a strong case for an exception though.
> >>
> >> Which requirements would that be? The only one I can see is the
> >> documentation and maybe an IGT test.
> >
> > This is the one I had in mind
> > https://dri.freedesktop.org/docs/drm/gpu/drm-uapi.html#open-source-userspace-requirements
> >
>
> Oh right, I had forgotten about that one.
>
> One benefit of having a userspace implementation is that it increases
> the chance of widespread adoption having a working implementation to
> look at. I don't think the reason tv.mode is not used anywhere (that I
> know of) is because the driver picks the enum values resulting in no
> standard names.

It probably doesn't help, but it's not what I was implying.

> It's a niche thing and way down on the todo list. nouveau and ch7006
> has a tv_norm module parameter which certainly doesn't help in moving
> people/projects over to the DRM property (downstream rpi also has it
> now).

Yeah, the RPi version is part of the reason I started working on this.
We should also consider the named modes used by vc4 and sun4i. All these
ad-hoc solutions are limited and (I think) come from the fact that we
don't have a solution easy enough to use for drivers (and to discover).

nouveau, ch7006, i915 and vc4 are using the tv.mode property for
example, but sun4i and meson don't.

sun4i relies on named modes to reimplement TV modes, but meson doesn't
at all.

And then nouveau has that extra command line parameter to set it up at
boot time.

It doesn't really make much sense to me, when all drivers have very
similar needs, that none of them behave in the same way. And I think the
non-standard property is partly to blame for this, since without some
generic content we can't share code.

This is what this series is about: every driver having similar
capabilities and as trivially as possible.

> mpv[1] is a commandline media player that after a quick look might be a
> candidate for implementing the property without too much effort.

Kodi might be another one. I can try to hack something around, but I'm
really skeptical about whether a PR would be merged or not.

> How do you test the property? I've used modetest but I can only change
> to a tv.mode that matches the current display mode. I can't switch from
> ntsc to pal for instance.

Yep, if you want to change from PAL to NTSC, it will require a new mode.

> I have tried changing mode on rpi-5.15 (which I will switch to for the
> gud gadget), but I always end up with flip timeouts when changing the value:
>
> $ cat /proc/cpuinfo | grep Model
> Model : Raspberry Pi 4 Model B Rev 1.1
> $ uname -a
> Linux pi4t 5.15.56-v7l+ #1575 SMP Fri Jul 22 20:29:46 BST 2022 armv7l
> GNU/Linux
> $ sudo dmesg -C
> $ modetest -M vc4 -s 45:720x480i -w 45:mode:1
> setting mode 720x480i-29.97Hz on connectors 45, crtc 73
> failed to set gamma: Function not implemented
>
> $ dmesg
> $ modetest -M vc4 -s 45:720x480i -w 45:mode:0
> setting mode 720x480i-29.97Hz on connectors 45, crtc 73
> failed to set gamma: Function not implemented
>
> $ dmesg
> [ 95.193059] [drm:drm_atomic_helper_wait_for_flip_done
> [drm_kms_helper]] *ERROR* [CRTC:73:crtc-1] flip_done timed out
> [ 105.433112] [drm:drm_crtc_commit_wait [drm]] *ERROR* flip_done timed out
> [ 105.433519] [drm:drm_atomic_helper_wait_for_dependencies
> [drm_kms_helper]] *ERROR* [CRTC:73:crtc-1] commit wait timed out
> [ 115.673095] [drm:drm_crtc_commit_wait [drm]] *ERROR* flip_done timed out
> [ 115.673498] [drm:drm_atomic_helper_wait_for_dependencies
> [drm_kms_helper]] *ERROR* [PLANE:63:plane-1] commit wait timed out
> [ 125.913106] [drm:drm_crtc_commit_wait [drm]] *ERROR* flip_done timed out
> [ 125.913510] vc4-drm gpu: [drm] *ERROR* Timed out waiting for commit
> [ 136.153411] [drm:drm_atomic_helper_wait_for_flip_done
> [drm_kms_helper]] *ERROR* [CRTC:73:crtc-1] flip_done timed out

So I haven't tested with 5.15, but I tested it with this series and it
was working well, both with the compat layer and the new property.

Maxime


Attachments:
(No filename) (6.51 kB)
signature.asc (235.00 B)
Download all attachments

2022-08-17 13:10:48

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH v1 05/35] drm/connector: Add TV standard property

Hi Maxime,

On Wed, Aug 17, 2022 at 1:15 PM Maxime Ripard <[email protected]> wrote:
> On Wed, Aug 17, 2022 at 10:35:07AM +0200, Geert Uytterhoeven wrote:
> > On Wed, Aug 17, 2022 at 9:47 AM Maxime Ripard <[email protected]> wrote:
> > > On Wed, Aug 17, 2022 at 09:31:18AM +0200, Geert Uytterhoeven wrote:
> > > > On Tue, Aug 16, 2022 at 5:50 PM Maxime Ripard <[email protected]> wrote:
> > > > > On Tue, Aug 16, 2022 at 04:43:44PM +0200, Geert Uytterhoeven wrote:
> > > > > > > > > > Either you have to add them here (e.g. "hd720p50" and "hd720p60"), or
> > > > > > > > > > handle them through "@<refresh>". The latter would impact "[PATCH v1
> > > > > > > > > > 09/35] drm/modes: Move named modes parsing to a separate function", as
> > > > > > > > > > currently a named mode and a refresh rate can't be specified both.
> > > > > > > > >
> > > > > > > > > I think the former would make more sense. It simplifies a bit the
> > > > > > > > > parser, and we're going to use a named mode anyway.
> > > > > > > > >
> > > > > > > > > > As "[PATCH v1 34/35] drm/modes: Introduce the tv_mode property as a
> > > > > > > > > > command-line option" uses a separate "tv_mode" option, and not the main
> > > > > > > > > > mode name, I think you want to add them here.
> > > > > > > > >
> > > > > > > > > It's a separate story I think, we could have a named mode hd720p50,
> > > > > > > > > which would be equivalent to 1280x720,tv_mode=hd720p
> > > > > > > >
> > > > > > > > So where's the field rate in "1280x720,tv_mode=hd720p"?
> > > > > > >
> > > > > > > Yeah, sorry I meant 1280x720@50,tv_mode=hd720p
> > > > > >
> > > > > > Above you said "I think the former would make more sense", so that
> > > > > > should be "1280x720,tv_mode=hd720p50"?
> > > > >
> > > > > No, 720p at 50Hz would be either hd720p50 or 1280x720@50,tv_mode=hd720p
> > > > > and 60Hz would be hd720p60 or 1280x720@60,tv_mode=hd720p
> > > >
> > > > I disagree: hd720p50 and hd720p60 are different TV modes.
> > >
> > > I agree, and I don't see how that command-line doesn't express that?
> >
> > Oh, I see what you mean: yes, it expresses that.
> > But it is inconsistent with the NTSC/PAL/SECAM/hd{480,576}[ip] modes,
> > where the TV mode specifies both number of lines and frame rate.
>
> Only if we're using a named mode, and naming is hard :)

That's not true: "640x480,tv_mode=PAL-N" would give me a mode with
625 lines and 25 frames/s, "640x480,tv_mode=PAL-M" would give me a
mode with 525 lines and 30 frames/s.

> Honestly, I'd be inclined to drop the hd* for now from this series. I
> don't have a hardware to test it with, for some we don't even have
> drivers that could implement these modes, we don't have a spec to work
> from, it looks like a recipe for failure :)

OK.

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

2022-08-17 13:27:35

by Noralf Trønnes

[permalink] [raw]
Subject: Re: [PATCH v1 05/35] drm/connector: Add TV standard property



Den 17.08.2022 13.46, skrev Maxime Ripard:
> On Tue, Aug 16, 2022 at 09:35:24PM +0200, Noralf Trønnes wrote:
>> Den 16.08.2022 11.49, skrev Maxime Ripard:
>>> On Tue, Aug 16, 2022 at 11:42:20AM +0200, Noralf Trønnes wrote:
>>>> Den 16.08.2022 10.26, skrev Maxime Ripard:
>>>>> Hi,
>>>>>
>>>>> On Mon, Aug 08, 2022 at 02:44:56PM +0200, Noralf Trønnes wrote:
>>>>>> Den 29.07.2022 18.34, skrev Maxime Ripard:
>>>>>>> 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 <[email protected]>
>>>>>>>
>>>>>>
>>>>>> Please also update Documentation/gpu/kms-properties.csv
>>>>>>
>>>>>> Requirements for adding a new property is found in
>>>>>> Documentation/gpu/drm-kms.rst
>>>>>
>>>>> I knew this was going to be raised at some point, so I'm glad it's that
>>>>> early :)
>>>>>
>>>>> I really don't know what to do there. If we stick by our usual rules,
>>>>> then we can't have any of that work merged.
>>>>>
>>>>> However, I think the status quo is not really satisfactory either.
>>>>> Indeed, we have a property, that doesn't follow those requirements
>>>>> either, with a driver-specific content, and that stands in the way of
>>>>> fixes and further improvements at both the core framework and driver
>>>>> levels.
>>>>>
>>>>> So having that new property still seems like a net improvement at the
>>>>> driver, framework and uAPI levels, even if it's not entirely following
>>>>> the requirements we have in place.
>>>>>
>>>>> Even more so since, realistically, those kind of interfaces will never
>>>>> get any new development on the user-space side of things, it's
>>>>> considered by everyone as legacy.
>>>>>
>>>>> This also is something we need to support at some point if we want to
>>>>> completely deprecate the fbdev drivers and provide decent alternatives
>>>>> in KMS.
>>>>>
>>>>> So yeah, strictly speaking, we would not qualify for our requirements
>>>>> there. I still think we have a strong case for an exception though.
>>>>
>>>> Which requirements would that be? The only one I can see is the
>>>> documentation and maybe an IGT test.
>>>
>>> This is the one I had in mind
>>> https://dri.freedesktop.org/docs/drm/gpu/drm-uapi.html#open-source-userspace-requirements
>>>
>>
>> Oh right, I had forgotten about that one.
>>
>> One benefit of having a userspace implementation is that it increases
>> the chance of widespread adoption having a working implementation to
>> look at. I don't think the reason tv.mode is not used anywhere (that I
>> know of) is because the driver picks the enum values resulting in no
>> standard names.
>
> It probably doesn't help, but it's not what I was implying.
>
>> It's a niche thing and way down on the todo list. nouveau and ch7006
>> has a tv_norm module parameter which certainly doesn't help in moving
>> people/projects over to the DRM property (downstream rpi also has it
>> now).
>
> Yeah, the RPi version is part of the reason I started working on this.
> We should also consider the named modes used by vc4 and sun4i. All these
> ad-hoc solutions are limited and (I think) come from the fact that we
> don't have a solution easy enough to use for drivers (and to discover).
>
> nouveau, ch7006, i915 and vc4 are using the tv.mode property for
> example, but sun4i and meson don't.
>
> sun4i relies on named modes to reimplement TV modes, but meson doesn't
> at all.
>
> And then nouveau has that extra command line parameter to set it up at
> boot time.
>
> It doesn't really make much sense to me, when all drivers have very
> similar needs, that none of them behave in the same way. And I think the
> non-standard property is partly to blame for this, since without some
> generic content we can't share code.
>
> This is what this series is about: every driver having similar
> capabilities and as trivially as possible.
>
>> mpv[1] is a commandline media player that after a quick look might be a
>> candidate for implementing the property without too much effort.
>
> Kodi might be another one. I can try to hack something around, but I'm
> really skeptical about whether a PR would be merged or not.
>

You can ask first before wasting time ofc.

But this baffles me, if you don't think projects like Kodi which is TV
centered want this, what kind of projects do you think want to use this
property?

>> How do you test the property? I've used modetest but I can only change
>> to a tv.mode that matches the current display mode. I can't switch from
>> ntsc to pal for instance.
>
> Yep, if you want to change from PAL to NTSC, it will require a new mode.
>

So userspace has to check tv.mode first and then create a display mode
the driver will accept if switching to a different display mode is
necessary? In other words, userspace can't discover from the kernel
which display modes a certain tv.mode/norm provides before it is
selected? If so, maybe libdrm should have some function(s) to deal with
switching between modes that require a different display mode since
knowledge about which display modes a tv.mode supports is needed before
hand.

Noralf.

2022-08-17 13:36:08

by Maxime Ripard

[permalink] [raw]
Subject: Re: [PATCH v1 04/35] drm/modes: Introduce 480i and 576i modes

On Wed, Aug 17, 2022 at 10:51:55AM +0200, Geert Uytterhoeven wrote:
> On Wed, Aug 17, 2022 at 9:54 AM Maxime Ripard <[email protected]> wrote:
> > On Tue, Aug 16, 2022 at 05:00:38PM +0200, Geert Uytterhoeven wrote:
> > > On Tue, Aug 16, 2022 at 3:26 PM Maxime Ripard <[email protected]> wrote:
> > > > On Fri, Aug 12, 2022 at 03:18:58PM +0200, Geert Uytterhoeven wrote:
> > > > > On Fri, Jul 29, 2022 at 6:35 PM Maxime Ripard <[email protected]> wrote:
> > > > > > Multiple drivers (meson, vc4) define the analog TV 525-lines and 625-lines
> > > > > > modes in the drivers.
> > > > >
> > > > > Nit: strictly speaking these are not analog modes, but the digital
> > > > > variants (ITU-R BT.656 and DVD-Video D1) of NTSC and PAL, using a
> > > > > 13.5 MHz sampling frequency for pixels.
> > > > >
> > > > > In analog modes, the only discrete values are the number of lines, and
> > > > > the frame/field rate (fixing the horizontal sync rate when combined).
> > > > >
> > > > > The number of (in)visible pixels per line depends on the available
> > > > > bandwidth. In a digital variant (which is anything generated by a
> > > > > digital computer system), the latter depends on the pixel clock, which
> > > > > can wildly differ from the 13.5 MHz used in the BT.656 standard. (e.g.
> > > > > Amiga uses 7.09/14.19/28.38 MHz (PAL) or 7.16/14.32/28.64 MHz (NTSC)).
> > > > >
> > > > > So I think we probably need some way to generate a PAL/NTSC-compatible
> > > > > mode based not only on resolution, but also on pixel clock.
> > > >
> > > > This would also fix the comments made by Jani and Thomas, so I quite
> > > > like the idea of it.
> > > >
> > > > I'm struggling a bit to find how would could implement this though.
> > > >
> > > > From what you were saying, I guess the prototype would be something like
> > > >
> > > > struct drm_display_mode *drm_create_analog_mode(unsigned int pixel_clock,
> > > > unsigned int lines,
> > > > unsigned int frame_rate)
> > > >
> > > > But I have zero idea on what the implementation would be. Do you have
> > > > some resources for this you could point me to?
> > >
> > > Horizontally, I think you should calculate left/right margins and
> > > hsync length to yield timings that match those for the BT.656 PAL/NTSC
> > > modes. I.e. when a 640x512 mode with a pixel clock of 14 MHz is
> > > requested, you want to calculate left', right', and hslen' for
> > >
> > > | <---- left' ---> | <- 640 pixels -> | <---- right' ---> | <--- hslen' --> |
> > > @ 14 MHz
> > >
> > > so they match the timings for left, right, and hslen for
> > >
> > > | <--- left ---> | <--- 720 pixels ---> | <--- right ---> | <--- hslen ---> |
> > > @ 13.5 MHz
> > >
> > > As 640 pixels @ 14 MHz are less wide than 720 pixels @ 13.5 MHz,
> > > you want to make sure to align the center of the visible part.
> >
> > So I guess in that example if we want to center it, left == right and
> > left' == right'? What about the sync length?
>
> No, left and right are asymmetrical, cfr. front and back porch in
> https://en.wikipedia.org/wiki/PAL#PAL_signal_details
> I.e. if the pixel part is reduced, both the left and right margins
> should be increased by the same amount.
>
> From the table linked above, hslen should be ca. 4.7?s (fixed).

each pixel taking 1 / pixel_clock seconds (assuming pixel_clock is in
Hz), and thus hslen (in pixels) = 4.7 * 10 ^ -6 * pixel_clk, right?

> > > Vertically, it's simpler, as the number of lines is discrete.
> > > You do have to take into account interlace and doublescan, and
> > > progressive modes with 262/312 lines.
> >
> > So we only have to deal with 525 and 625 lines total (without taking
> > interlace and doublescan into account), right?
>
> Yes.
>
> > I guess we still have the same question, we probably want to center it,
> > so top == bottom, but what about the vsync length?
>
> Unfortunately that table does not mention top and bottom margins.
> But according to drivers/video/fbdev/amifb.c (see the "Broadcast
> video timings" comment block and the definitions of the "ntsc-lace"
> and "pal-lace" video modes), they are asymmetrical, too.
>
> Vsync length is 0.576ms, so that's 9 scan lines (I guess I didn't
> have that info when I wrote amifb, as I used 4 lines there).

Thanks, that's some great info already.

It's mentioned though that the settings for NTSC are "straightforward",
but it's definitely not for me :)

I've looked around and it looks like the entire blanking area is
supposed to be 40 pixels in interlaced, but I couldn't find anywhere how
it's supposed to be split between the upper and lower margins and the
sync period.

Thanks!
Maxime


Attachments:
(No filename) (4.77 kB)
signature.asc (235.00 B)
Download all attachments

2022-08-17 13:42:06

by Maxime Ripard

[permalink] [raw]
Subject: Re: [PATCH v1 05/35] drm/connector: Add TV standard property

On Wed, Aug 17, 2022 at 03:05:52PM +0200, Geert Uytterhoeven wrote:
> Hi Maxime,
>
> On Wed, Aug 17, 2022 at 1:15 PM Maxime Ripard <[email protected]> wrote:
> > On Wed, Aug 17, 2022 at 10:35:07AM +0200, Geert Uytterhoeven wrote:
> > > On Wed, Aug 17, 2022 at 9:47 AM Maxime Ripard <[email protected]> wrote:
> > > > On Wed, Aug 17, 2022 at 09:31:18AM +0200, Geert Uytterhoeven wrote:
> > > > > On Tue, Aug 16, 2022 at 5:50 PM Maxime Ripard <[email protected]> wrote:
> > > > > > On Tue, Aug 16, 2022 at 04:43:44PM +0200, Geert Uytterhoeven wrote:
> > > > > > > > > > > Either you have to add them here (e.g. "hd720p50" and "hd720p60"), or
> > > > > > > > > > > handle them through "@<refresh>". The latter would impact "[PATCH v1
> > > > > > > > > > > 09/35] drm/modes: Move named modes parsing to a separate function", as
> > > > > > > > > > > currently a named mode and a refresh rate can't be specified both.
> > > > > > > > > >
> > > > > > > > > > I think the former would make more sense. It simplifies a bit the
> > > > > > > > > > parser, and we're going to use a named mode anyway.
> > > > > > > > > >
> > > > > > > > > > > As "[PATCH v1 34/35] drm/modes: Introduce the tv_mode property as a
> > > > > > > > > > > command-line option" uses a separate "tv_mode" option, and not the main
> > > > > > > > > > > mode name, I think you want to add them here.
> > > > > > > > > >
> > > > > > > > > > It's a separate story I think, we could have a named mode hd720p50,
> > > > > > > > > > which would be equivalent to 1280x720,tv_mode=hd720p
> > > > > > > > >
> > > > > > > > > So where's the field rate in "1280x720,tv_mode=hd720p"?
> > > > > > > >
> > > > > > > > Yeah, sorry I meant 1280x720@50,tv_mode=hd720p
> > > > > > >
> > > > > > > Above you said "I think the former would make more sense", so that
> > > > > > > should be "1280x720,tv_mode=hd720p50"?
> > > > > >
> > > > > > No, 720p at 50Hz would be either hd720p50 or 1280x720@50,tv_mode=hd720p
> > > > > > and 60Hz would be hd720p60 or 1280x720@60,tv_mode=hd720p
> > > > >
> > > > > I disagree: hd720p50 and hd720p60 are different TV modes.
> > > >
> > > > I agree, and I don't see how that command-line doesn't express that?
> > >
> > > Oh, I see what you mean: yes, it expresses that.
> > > But it is inconsistent with the NTSC/PAL/SECAM/hd{480,576}[ip] modes,
> > > where the TV mode specifies both number of lines and frame rate.
> >
> > Only if we're using a named mode, and naming is hard :)
>
> That's not true: "640x480,tv_mode=PAL-N" would give me a mode with
> 625 lines and 25 frames/s, "640x480,tv_mode=PAL-M" would give me a
> mode with 525 lines and 30 frames/s.

In that series, "640x480,tv_mode=PAL-N" would be rejected as invalid:

https://lore.kernel.org/dri-devel/[email protected]/

Maxime


Attachments:
(No filename) (2.81 kB)
signature.asc (235.00 B)
Download all attachments

2022-08-17 14:06:14

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH v1 04/35] drm/modes: Introduce 480i and 576i modes

Hi Maxime,

On Wed, Aug 17, 2022 at 3:15 PM Maxime Ripard <[email protected]> wrote:
> On Wed, Aug 17, 2022 at 10:51:55AM +0200, Geert Uytterhoeven wrote:
> > On Wed, Aug 17, 2022 at 9:54 AM Maxime Ripard <[email protected]> wrote:
> > > On Tue, Aug 16, 2022 at 05:00:38PM +0200, Geert Uytterhoeven wrote:
> > > > On Tue, Aug 16, 2022 at 3:26 PM Maxime Ripard <[email protected]> wrote:
> > > > > On Fri, Aug 12, 2022 at 03:18:58PM +0200, Geert Uytterhoeven wrote:
> > > > > > On Fri, Jul 29, 2022 at 6:35 PM Maxime Ripard <[email protected]> wrote:
> > > > > > > Multiple drivers (meson, vc4) define the analog TV 525-lines and 625-lines
> > > > > > > modes in the drivers.
> > > > > >
> > > > > > Nit: strictly speaking these are not analog modes, but the digital
> > > > > > variants (ITU-R BT.656 and DVD-Video D1) of NTSC and PAL, using a
> > > > > > 13.5 MHz sampling frequency for pixels.
> > > > > >
> > > > > > In analog modes, the only discrete values are the number of lines, and
> > > > > > the frame/field rate (fixing the horizontal sync rate when combined).
> > > > > >
> > > > > > The number of (in)visible pixels per line depends on the available
> > > > > > bandwidth. In a digital variant (which is anything generated by a
> > > > > > digital computer system), the latter depends on the pixel clock, which
> > > > > > can wildly differ from the 13.5 MHz used in the BT.656 standard. (e.g.
> > > > > > Amiga uses 7.09/14.19/28.38 MHz (PAL) or 7.16/14.32/28.64 MHz (NTSC)).
> > > > > >
> > > > > > So I think we probably need some way to generate a PAL/NTSC-compatible
> > > > > > mode based not only on resolution, but also on pixel clock.
> > > > >
> > > > > This would also fix the comments made by Jani and Thomas, so I quite
> > > > > like the idea of it.
> > > > >
> > > > > I'm struggling a bit to find how would could implement this though.
> > > > >
> > > > > From what you were saying, I guess the prototype would be something like
> > > > >
> > > > > struct drm_display_mode *drm_create_analog_mode(unsigned int pixel_clock,
> > > > > unsigned int lines,
> > > > > unsigned int frame_rate)
> > > > >
> > > > > But I have zero idea on what the implementation would be. Do you have
> > > > > some resources for this you could point me to?
> > > >
> > > > Horizontally, I think you should calculate left/right margins and
> > > > hsync length to yield timings that match those for the BT.656 PAL/NTSC
> > > > modes. I.e. when a 640x512 mode with a pixel clock of 14 MHz is
> > > > requested, you want to calculate left', right', and hslen' for
> > > >
> > > > | <---- left' ---> | <- 640 pixels -> | <---- right' ---> | <--- hslen' --> |
> > > > @ 14 MHz
> > > >
> > > > so they match the timings for left, right, and hslen for
> > > >
> > > > | <--- left ---> | <--- 720 pixels ---> | <--- right ---> | <--- hslen ---> |
> > > > @ 13.5 MHz
> > > >
> > > > As 640 pixels @ 14 MHz are less wide than 720 pixels @ 13.5 MHz,
> > > > you want to make sure to align the center of the visible part.
> > >
> > > So I guess in that example if we want to center it, left == right and
> > > left' == right'? What about the sync length?
> >
> > No, left and right are asymmetrical, cfr. front and back porch in
> > https://en.wikipedia.org/wiki/PAL#PAL_signal_details
> > I.e. if the pixel part is reduced, both the left and right margins
> > should be increased by the same amount.
> >
> > From the table linked above, hslen should be ca. 4.7µs (fixed).
>
> each pixel taking 1 / pixel_clock seconds (assuming pixel_clock is in
> Hz), and thus hslen (in pixels) = 4.7 * 10 ^ -6 * pixel_clk, right?

Exactly.

> > > > Vertically, it's simpler, as the number of lines is discrete.
> > > > You do have to take into account interlace and doublescan, and
> > > > progressive modes with 262/312 lines.
> > >
> > > So we only have to deal with 525 and 625 lines total (without taking
> > > interlace and doublescan into account), right?
> >
> > Yes.
> >
> > > I guess we still have the same question, we probably want to center it,
> > > so top == bottom, but what about the vsync length?
> >
> > Unfortunately that table does not mention top and bottom margins.
> > But according to drivers/video/fbdev/amifb.c (see the "Broadcast
> > video timings" comment block and the definitions of the "ntsc-lace"
> > and "pal-lace" video modes), they are asymmetrical, too.
> >
> > Vsync length is 0.576ms, so that's 9 scan lines (I guess I didn't
> > have that info when I wrote amifb, as I used 4 lines there).
>
> Thanks, that's some great info already.
>
> It's mentioned though that the settings for NTSC are "straightforward",
> but it's definitely not for me :)

As in NTSC just uses different pixel clock and horizontal/vertical sync
rate values...

> I've looked around and it looks like the entire blanking area is
> supposed to be 40 pixels in interlaced, but I couldn't find anywhere how

625 lines - 575[*] visible lines = 50 lines.

[*] BT.656 uses 576 visible lines as that's a multiple of 2, for splitting
a frame in two fields of equal size.

"visible" is relative, as it includes the overscan region.
Some PAL monitors used with computers had knobs to control width/height
and position of the screen, so you could make use of most or all of
the overscan region, but on a real TV you're limited to ca. 640x512 (on
PAL) which is what an Amiga used by default (with a 14 MHz pixclock).
> it's supposed to be split between the upper and lower margins and the
> sync period.

"Field Synchronization of PAL System" on http://martin.hinner.info/vga/pal.html
shows the split.

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

2022-08-17 14:13:19

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH v1 05/35] drm/connector: Add TV standard property

Hi Maxime,

On Wed, Aug 17, 2022 at 3:19 PM Maxime Ripard <[email protected]> wrote:
> On Wed, Aug 17, 2022 at 03:05:52PM +0200, Geert Uytterhoeven wrote:
> > On Wed, Aug 17, 2022 at 1:15 PM Maxime Ripard <[email protected]> wrote:
> > > On Wed, Aug 17, 2022 at 10:35:07AM +0200, Geert Uytterhoeven wrote:
> > > > On Wed, Aug 17, 2022 at 9:47 AM Maxime Ripard <[email protected]> wrote:
> > > > > On Wed, Aug 17, 2022 at 09:31:18AM +0200, Geert Uytterhoeven wrote:
> > > > > > On Tue, Aug 16, 2022 at 5:50 PM Maxime Ripard <[email protected]> wrote:
> > > > > > > On Tue, Aug 16, 2022 at 04:43:44PM +0200, Geert Uytterhoeven wrote:
> > > > > > > > > > > > Either you have to add them here (e.g. "hd720p50" and "hd720p60"), or
> > > > > > > > > > > > handle them through "@<refresh>". The latter would impact "[PATCH v1
> > > > > > > > > > > > 09/35] drm/modes: Move named modes parsing to a separate function", as
> > > > > > > > > > > > currently a named mode and a refresh rate can't be specified both.
> > > > > > > > > > >
> > > > > > > > > > > I think the former would make more sense. It simplifies a bit the
> > > > > > > > > > > parser, and we're going to use a named mode anyway.
> > > > > > > > > > >
> > > > > > > > > > > > As "[PATCH v1 34/35] drm/modes: Introduce the tv_mode property as a
> > > > > > > > > > > > command-line option" uses a separate "tv_mode" option, and not the main
> > > > > > > > > > > > mode name, I think you want to add them here.
> > > > > > > > > > >
> > > > > > > > > > > It's a separate story I think, we could have a named mode hd720p50,
> > > > > > > > > > > which would be equivalent to 1280x720,tv_mode=hd720p
> > > > > > > > > >
> > > > > > > > > > So where's the field rate in "1280x720,tv_mode=hd720p"?
> > > > > > > > >
> > > > > > > > > Yeah, sorry I meant 1280x720@50,tv_mode=hd720p
> > > > > > > >
> > > > > > > > Above you said "I think the former would make more sense", so that
> > > > > > > > should be "1280x720,tv_mode=hd720p50"?
> > > > > > >
> > > > > > > No, 720p at 50Hz would be either hd720p50 or 1280x720@50,tv_mode=hd720p
> > > > > > > and 60Hz would be hd720p60 or 1280x720@60,tv_mode=hd720p
> > > > > >
> > > > > > I disagree: hd720p50 and hd720p60 are different TV modes.
> > > > >
> > > > > I agree, and I don't see how that command-line doesn't express that?
> > > >
> > > > Oh, I see what you mean: yes, it expresses that.
> > > > But it is inconsistent with the NTSC/PAL/SECAM/hd{480,576}[ip] modes,
> > > > where the TV mode specifies both number of lines and frame rate.
> > >
> > > Only if we're using a named mode, and naming is hard :)
> >
> > That's not true: "640x480,tv_mode=PAL-N" would give me a mode with
> > 625 lines and 25 frames/s, "640x480,tv_mode=PAL-M" would give me a
> > mode with 525 lines and 30 frames/s.
>
> In that series, "640x480,tv_mode=PAL-N" would be rejected as invalid:
>
> https://lore.kernel.org/dri-devel/[email protected]/

It would become supported once the ideas from thread "[PATCH v1 04/35]
drm/modes: Introduce 480i and 576i modes" are implemented...

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

2022-08-17 23:43:05

by Noralf Trønnes

[permalink] [raw]
Subject: Re: [PATCH v1 05/35] drm/connector: Add TV standard property



Den 17.08.2022 15.11, skrev Noralf Trønnes:
>
>
> Den 17.08.2022 13.46, skrev Maxime Ripard:
>> On Tue, Aug 16, 2022 at 09:35:24PM +0200, Noralf Trønnes wrote:
>>> Den 16.08.2022 11.49, skrev Maxime Ripard:
>>>> On Tue, Aug 16, 2022 at 11:42:20AM +0200, Noralf Trønnes wrote:
>>>>> Den 16.08.2022 10.26, skrev Maxime Ripard:
>>>>>> Hi,
>>>>>>
>>>>>> On Mon, Aug 08, 2022 at 02:44:56PM +0200, Noralf Trønnes wrote:
>>>>>>> Den 29.07.2022 18.34, skrev Maxime Ripard:
>>>>>>>> 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 <[email protected]>
>>>>>>>>

>>> How do you test the property? I've used modetest but I can only change
>>> to a tv.mode that matches the current display mode. I can't switch from
>>> ntsc to pal for instance.
>>
>> Yep, if you want to change from PAL to NTSC, it will require a new mode.
>>
>
> So userspace has to check tv.mode first and then create a display mode
> the driver will accept if switching to a different display mode is
> necessary? In other words, userspace can't discover from the kernel
> which display modes a certain tv.mode/norm provides before it is
> selected? If so, maybe libdrm should have some function(s) to deal with
> switching between modes that require a different display mode since
> knowledge about which display modes a tv.mode supports is needed before
> hand.
>

I haven't used vc4 on Pi4 in mainline before and have finally gotten it
to work.

I see that the connector reports 2 modes that together fit all tv.norms
so userspace doesn't have to contruct a display mode, but it does need
to know which display mode belongs to a certain tv.norm.

When I try to use modetest I'm unable to set a mode:

pi@pi4t:~ $ modetest -M vc4 -s 45:720x480i
setting mode 720x480i-29.97Hz on connectors 45, crtc 68
failed to set mode: Function not implemented

The errno is misleading, modetest does a drmModeDirtyFB before checking
the error returned by drmModeSetCrtc.

Setting the property succeeds, but the modeset still fails:

pi@pi4t:~ $ modetest -M vc4 -s 45:720x480i -w 45:"tv norm":2
setting mode 720x480i-29.97Hz on connectors 45, crtc 68
failed to set mode: Function not implemented

pi@pi4t:~ $ modetest -M vc4 -c
37 tv norm:
flags: bitmask
values: NTSC-443=0x1 NTSC-J=0x2 NTSC-M=0x4 PAL-B=0x10
PAL-M=0x200 PAL-N=0x400 SECAM-B=0x2000
value: 2

Here's the log, can you see if there's anything obvious in there:
https://gist.github.com/notro/a079498bf6b64327105752b2bafa8858

Noralf.

2022-08-18 12:47:28

by Maxime Ripard

[permalink] [raw]
Subject: Re: [PATCH v1 04/35] drm/modes: Introduce 480i and 576i modes

Hi!

On Wed, Aug 17, 2022 at 04:01:48PM +0200, Geert Uytterhoeven wrote:
> > > > > Vertically, it's simpler, as the number of lines is discrete.
> > > > > You do have to take into account interlace and doublescan, and
> > > > > progressive modes with 262/312 lines.
> > > >
> > > > So we only have to deal with 525 and 625 lines total (without taking
> > > > interlace and doublescan into account), right?
> > >
> > > Yes.
> > >
> > > > I guess we still have the same question, we probably want to center it,
> > > > so top == bottom, but what about the vsync length?
> > >
> > > Unfortunately that table does not mention top and bottom margins.
> > > But according to drivers/video/fbdev/amifb.c (see the "Broadcast
> > > video timings" comment block and the definitions of the "ntsc-lace"
> > > and "pal-lace" video modes), they are asymmetrical, too.
> > >
> > > Vsync length is 0.576ms, so that's 9 scan lines (I guess I didn't
> > > have that info when I wrote amifb, as I used 4 lines there).
> >
> > Thanks, that's some great info already.
> >
> > It's mentioned though that the settings for NTSC are "straightforward",
> > but it's definitely not for me :)
>
> As in NTSC just uses different pixel clock and horizontal/vertical sync
> rate values...

Oh, so the constants differ but the calculation is the same, ack.

> > I've looked around and it looks like the entire blanking area is
> > supposed to be 40 pixels in interlaced, but I couldn't find anywhere how
>
> 625 lines - 575[*] visible lines = 50 lines.
>
> [*] BT.656 uses 576 visible lines as that's a multiple of 2, for splitting
> a frame in two fields of equal size.
>
> "visible" is relative, as it includes the overscan region.
> Some PAL monitors used with computers had knobs to control width/height
> and position of the screen, so you could make use of most or all of
> the overscan region

It brings back some memories :)

> but on a real TV you're limited to ca. 640x512 (on PAL) which is what
> an Amiga used by default (with a 14 MHz pixclock).

> > it's supposed to be split between the upper and lower margins and the
> > sync period.
>
> "Field Synchronization of PAL System" on
> http://martin.hinner.info/vga/pal.html shows the split.

Thanks, that's excellent as well.

I'm mostly done with a function that creates a PAL mode, but I still
have one question.

If I understand well, the blanking period is made up (interlace) of 16
pulses for the first field, 14 for the second, each pulse taking half a
line. That amount to 30 pulses, so 15 lines.

I first assumed that the pre-equalizing pulses would be the back porch,
the long sync pulses the vsync, and the post-equalizing pulses the front
porch. But... we're still missing 35 lines to amount to 625 lines, that
seems to be counted in the field itself (305 lines == (575 + 35) / 2)

So I guess my assumption was wrong to begin with.

You seem to have used a fixed vsync in amifb to 4 lines, and I don't
understand how you come up with the upper and lower margins (or rather,
how they are linked to what's described in that page)

Maxime


Attachments:
(No filename) (3.09 kB)
signature.asc (235.00 B)
Download all attachments

2022-08-18 13:04:52

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH v1 04/35] drm/modes: Introduce 480i and 576i modes

Hi Maxime,

On Thu, Aug 18, 2022 at 2:39 PM Maxime Ripard <[email protected]> wrote:
> On Wed, Aug 17, 2022 at 04:01:48PM +0200, Geert Uytterhoeven wrote:
> > > I've looked around and it looks like the entire blanking area is
> > > supposed to be 40 pixels in interlaced, but I couldn't find anywhere how
> >
> > 625 lines - 575[*] visible lines = 50 lines.
> >
> > [*] BT.656 uses 576 visible lines as that's a multiple of 2, for splitting
> > a frame in two fields of equal size.
> >
> > "visible" is relative, as it includes the overscan region.
> > Some PAL monitors used with computers had knobs to control width/height
> > and position of the screen, so you could make use of most or all of
> > the overscan region
>
> It brings back some memories :)
>
> > but on a real TV you're limited to ca. 640x512 (on PAL) which is what
> > an Amiga used by default (with a 14 MHz pixclock).
>
> > > it's supposed to be split between the upper and lower margins and the
> > > sync period.
> >
> > "Field Synchronization of PAL System" on
> > http://martin.hinner.info/vga/pal.html shows the split.
>
> Thanks, that's excellent as well.
>
> I'm mostly done with a function that creates a PAL mode, but I still
> have one question.
>
> If I understand well, the blanking period is made up (interlace) of 16
> pulses for the first field, 14 for the second, each pulse taking half a
> line. That amount to 30 pulses, so 15 lines.
>
> I first assumed that the pre-equalizing pulses would be the back porch,
> the long sync pulses the vsync, and the post-equalizing pulses the front
> porch. But... we're still missing 35 lines to amount to 625 lines, that
> seems to be counted in the field itself (305 lines == (575 + 35) / 2)
>
> So I guess my assumption was wrong to begin with.

The back porch is the number of lines between the last "visible" line
and the start of the synchronization pulse, i.e. "l" in the "Field
Synchronization of PAL System" drawing.
Virtual sync length is "m".
The front porch is the number of lines between the end of
the synchronization pulse, and the first "visible" line, i.e.
"j - l - m" (I think you used "n", thus missing lines 6-23 and 319-335).

> You seem to have used a fixed vsync in amifb to 4 lines, and I don't

Actually "m" is 2.5 lines in the first field, and 3 lines in the second field,
so "4" is not that much off of 2.5 + 3.

> understand how you come up with the upper and lower margins (or rather,
> how they are linked to what's described in that page)

These margins probably came from the Amiga hardware reference manual,
for the default 640x512 (PAL) and 640x400 (NTSC) modes.

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

2022-08-18 13:52:40

by Maxime Ripard

[permalink] [raw]
Subject: Re: [PATCH v1 04/35] drm/modes: Introduce 480i and 576i modes

On Thu, Aug 18, 2022 at 02:57:55PM +0200, Geert Uytterhoeven wrote:
> Hi Maxime,
>
> On Thu, Aug 18, 2022 at 2:39 PM Maxime Ripard <[email protected]> wrote:
> > On Wed, Aug 17, 2022 at 04:01:48PM +0200, Geert Uytterhoeven wrote:
> > > > I've looked around and it looks like the entire blanking area is
> > > > supposed to be 40 pixels in interlaced, but I couldn't find anywhere how
> > >
> > > 625 lines - 575[*] visible lines = 50 lines.
> > >
> > > [*] BT.656 uses 576 visible lines as that's a multiple of 2, for splitting
> > > a frame in two fields of equal size.
> > >
> > > "visible" is relative, as it includes the overscan region.
> > > Some PAL monitors used with computers had knobs to control width/height
> > > and position of the screen, so you could make use of most or all of
> > > the overscan region
> >
> > It brings back some memories :)
> >
> > > but on a real TV you're limited to ca. 640x512 (on PAL) which is what
> > > an Amiga used by default (with a 14 MHz pixclock).
> >
> > > > it's supposed to be split between the upper and lower margins and the
> > > > sync period.
> > >
> > > "Field Synchronization of PAL System" on
> > > http://martin.hinner.info/vga/pal.html shows the split.
> >
> > Thanks, that's excellent as well.
> >
> > I'm mostly done with a function that creates a PAL mode, but I still
> > have one question.
> >
> > If I understand well, the blanking period is made up (interlace) of 16
> > pulses for the first field, 14 for the second, each pulse taking half a
> > line. That amount to 30 pulses, so 15 lines.
> >
> > I first assumed that the pre-equalizing pulses would be the back porch,
> > the long sync pulses the vsync, and the post-equalizing pulses the front
> > porch. But... we're still missing 35 lines to amount to 625 lines, that
> > seems to be counted in the field itself (305 lines == (575 + 35) / 2)
> >
> > So I guess my assumption was wrong to begin with.
>
> The back porch is the number of lines between the last "visible" line
> and the start of the synchronization pulse, i.e. "l" in the "Field
> Synchronization of PAL System" drawing.
> Virtual sync length is "m".
> The front porch is the number of lines between the end of
> the synchronization pulse, and the first "visible" line, i.e.
> "j - l - m" (I think you used "n", thus missing lines 6-23 and 319-335).

Ah, yes, that makes sense

> > You seem to have used a fixed vsync in amifb to 4 lines, and I don't
>
> Actually "m" is 2.5 lines in the first field, and 3 lines in the second field,
> so "4" is not that much off of 2.5 + 3.

Is it? If I'm reading that drawing well, l before the first field starts
on the second half of line 623 and stops at the end of line 625, so 2.5
line, and on the second field starts at the beginning of line 311, and
stops half-way through 313 so 2.5 line again.

Then, for the first field, m starts at the beginning of line 1, stops
half-way through line 3, so 2.5 line indeed, and then on the second
field starts on the second half of 313 and stops at the end of line 315.
So 2.5 again?

Thus, both should be 5?

> > understand how you come up with the upper and lower margins (or rather,
> > how they are linked to what's described in that page)
>
> These margins probably came from the Amiga hardware reference manual,
> for the default 640x512 (PAL) and 640x400 (NTSC) modes.

Ok.

I started adding more sanity checks to my code, and I just realised I
don't seem to be able to reach 720 pixels over a single line though. If
I understood it properly, and according to [1] the active part of a line
is supposed to be 51.95us, and the blanking period taking 12.05us. [2]
in the timing section has pretty much the same numbers, so it looks
sane.

At 13.5Mhz, a pixel is going to take roughly 74ns, and 51950 / 74 = 702
pixels

It seems we can go push it to 52350 ns, but that still gives us only 706
pixels.

Similarly, if I just choose to ignore that limit and just take the
active time I need, 720 * 74 = 53280ns

That leaves us 10720ns for the blanking period, and that's not enough to
fit even the minimum of the front porch, hsync and back porch (1.55 +
4.5 + 5.5 = 11.55us).

Are those constraints merely recommendations, or am I missing something?

Thanks!
Maxime

1: https://en.wikipedia.org/wiki/PAL#PAL_signal_details
2: http://martin.hinner.info/vga/pal.html


Attachments:
(No filename) (4.35 kB)
signature.asc (235.00 B)
Download all attachments

2022-08-18 15:18:26

by Maxime Ripard

[permalink] [raw]
Subject: Re: [PATCH v1 05/35] drm/connector: Add TV standard property

On Wed, Aug 17, 2022 at 04:04:24PM +0200, Geert Uytterhoeven wrote:
> Hi Maxime,
>
> On Wed, Aug 17, 2022 at 3:19 PM Maxime Ripard <[email protected]> wrote:
> > On Wed, Aug 17, 2022 at 03:05:52PM +0200, Geert Uytterhoeven wrote:
> > > On Wed, Aug 17, 2022 at 1:15 PM Maxime Ripard <[email protected]> wrote:
> > > > On Wed, Aug 17, 2022 at 10:35:07AM +0200, Geert Uytterhoeven wrote:
> > > > > On Wed, Aug 17, 2022 at 9:47 AM Maxime Ripard <[email protected]> wrote:
> > > > > > On Wed, Aug 17, 2022 at 09:31:18AM +0200, Geert Uytterhoeven wrote:
> > > > > > > On Tue, Aug 16, 2022 at 5:50 PM Maxime Ripard <[email protected]> wrote:
> > > > > > > > On Tue, Aug 16, 2022 at 04:43:44PM +0200, Geert Uytterhoeven wrote:
> > > > > > > > > > > > > Either you have to add them here (e.g. "hd720p50" and "hd720p60"), or
> > > > > > > > > > > > > handle them through "@<refresh>". The latter would impact "[PATCH v1
> > > > > > > > > > > > > 09/35] drm/modes: Move named modes parsing to a separate function", as
> > > > > > > > > > > > > currently a named mode and a refresh rate can't be specified both.
> > > > > > > > > > > >
> > > > > > > > > > > > I think the former would make more sense. It simplifies a bit the
> > > > > > > > > > > > parser, and we're going to use a named mode anyway.
> > > > > > > > > > > >
> > > > > > > > > > > > > As "[PATCH v1 34/35] drm/modes: Introduce the tv_mode property as a
> > > > > > > > > > > > > command-line option" uses a separate "tv_mode" option, and not the main
> > > > > > > > > > > > > mode name, I think you want to add them here.
> > > > > > > > > > > >
> > > > > > > > > > > > It's a separate story I think, we could have a named mode hd720p50,
> > > > > > > > > > > > which would be equivalent to 1280x720,tv_mode=hd720p
> > > > > > > > > > >
> > > > > > > > > > > So where's the field rate in "1280x720,tv_mode=hd720p"?
> > > > > > > > > >
> > > > > > > > > > Yeah, sorry I meant 1280x720@50,tv_mode=hd720p
> > > > > > > > >
> > > > > > > > > Above you said "I think the former would make more sense", so that
> > > > > > > > > should be "1280x720,tv_mode=hd720p50"?
> > > > > > > >
> > > > > > > > No, 720p at 50Hz would be either hd720p50 or 1280x720@50,tv_mode=hd720p
> > > > > > > > and 60Hz would be hd720p60 or 1280x720@60,tv_mode=hd720p
> > > > > > >
> > > > > > > I disagree: hd720p50 and hd720p60 are different TV modes.
> > > > > >
> > > > > > I agree, and I don't see how that command-line doesn't express that?
> > > > >
> > > > > Oh, I see what you mean: yes, it expresses that.
> > > > > But it is inconsistent with the NTSC/PAL/SECAM/hd{480,576}[ip] modes,
> > > > > where the TV mode specifies both number of lines and frame rate.
> > > >
> > > > Only if we're using a named mode, and naming is hard :)
> > >
> > > That's not true: "640x480,tv_mode=PAL-N" would give me a mode with
> > > 625 lines and 25 frames/s, "640x480,tv_mode=PAL-M" would give me a
> > > mode with 525 lines and 30 frames/s.
> >
> > In that series, "640x480,tv_mode=PAL-N" would be rejected as invalid:
> >
> > https://lore.kernel.org/dri-devel/[email protected]/
>
> It would become supported once the ideas from thread "[PATCH v1 04/35]
> drm/modes: Introduce 480i and 576i modes" are implemented...

Indeed, but I'm still not sure what your concern is here.
"640x480,tv_mode=PAL-N" and "640x480,tv_mode=PAL-M" are both fairly
obvious.

You were initially saying that you had concern over the inconsistency of
NTSC/PAL/SECAM where the TV mode would specify a number of lines and
frame rate, but hd720p50 also specifies a number of line and frame rate?

Maxime


Attachments:
(No filename) (3.63 kB)
signature.asc (235.00 B)
Download all attachments

2022-08-18 15:42:49

by Noralf Trønnes

[permalink] [raw]
Subject: Re: [PATCH v1 05/35] drm/connector: Add TV standard property



Den 18.08.2022 01.23, skrev Noralf Trønnes:
>
>
> Den 17.08.2022 15.11, skrev Noralf Trønnes:
>>
>>
>> Den 17.08.2022 13.46, skrev Maxime Ripard:
>>> On Tue, Aug 16, 2022 at 09:35:24PM +0200, Noralf Trønnes wrote:
>>>> Den 16.08.2022 11.49, skrev Maxime Ripard:
>>>>> On Tue, Aug 16, 2022 at 11:42:20AM +0200, Noralf Trønnes wrote:
>>>>>> Den 16.08.2022 10.26, skrev Maxime Ripard:
>>>>>>> Hi,
>>>>>>>
>>>>>>> On Mon, Aug 08, 2022 at 02:44:56PM +0200, Noralf Trønnes wrote:
>>>>>>>> Den 29.07.2022 18.34, skrev Maxime Ripard:
>>>>>>>>> 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 <[email protected]>
>>>>>>>>>
>
>>>> How do you test the property? I've used modetest but I can only change
>>>> to a tv.mode that matches the current display mode. I can't switch from
>>>> ntsc to pal for instance.
>>>
>>> Yep, if you want to change from PAL to NTSC, it will require a new mode.
>>>
>>
>> So userspace has to check tv.mode first and then create a display mode
>> the driver will accept if switching to a different display mode is
>> necessary? In other words, userspace can't discover from the kernel
>> which display modes a certain tv.mode/norm provides before it is
>> selected? If so, maybe libdrm should have some function(s) to deal with
>> switching between modes that require a different display mode since
>> knowledge about which display modes a tv.mode supports is needed before
>> hand.
>>
>
> I haven't used vc4 on Pi4 in mainline before and have finally gotten it
> to work.
>
> I see that the connector reports 2 modes that together fit all tv.norms
> so userspace doesn't have to contruct a display mode, but it does need
> to know which display mode belongs to a certain tv.norm.
>
> When I try to use modetest I'm unable to set a mode:
>
> pi@pi4t:~ $ modetest -M vc4 -s 45:720x480i
> setting mode 720x480i-29.97Hz on connectors 45, crtc 68
> failed to set mode: Function not implemented
>
> The errno is misleading, modetest does a drmModeDirtyFB before checking
> the error returned by drmModeSetCrtc.
>
> Setting the property succeeds, but the modeset still fails:
>
> pi@pi4t:~ $ modetest -M vc4 -s 45:720x480i -w 45:"tv norm":2
> setting mode 720x480i-29.97Hz on connectors 45, crtc 68
> failed to set mode: Function not implemented
>
> pi@pi4t:~ $ modetest -M vc4 -c
> 37 tv norm:
> flags: bitmask
> values: NTSC-443=0x1 NTSC-J=0x2 NTSC-M=0x4 PAL-B=0x10
> PAL-M=0x200 PAL-N=0x400 SECAM-B=0x2000
> value: 2
>
> Here's the log, can you see if there's anything obvious in there:
> https://gist.github.com/notro/a079498bf6b64327105752b2bafa8858
>

I'm one step closer as I now have fbcon working, I had forgotten to add
enable_tvout=1 and I had disable_fw_kms_setup=1 which disables the
video= mode on the kernel commandline.

modetest still fails though, after alot of printk sprinkling, I've
tracked it down to the drm_mode_equal test in
drm_atomic_helper_connector_tv_check(). The aspect ratios differ:

[ 61.336295] drm_atomic_helper_connector_tv_check:
mode->picture_aspect_ratio=1
[ 61.336301] drm_atomic_helper_connector_tv_check:
&crtc_state->mode->picture_aspect_ratio=0

Noralf.

2022-08-18 15:46:49

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH v1 05/35] drm/connector: Add TV standard property

Hi Maxime,

On Thu, Aug 18, 2022 at 4:54 PM Maxime Ripard <[email protected]> wrote:
> On Wed, Aug 17, 2022 at 04:04:24PM +0200, Geert Uytterhoeven wrote:
> > On Wed, Aug 17, 2022 at 3:19 PM Maxime Ripard <[email protected]> wrote:
> > > On Wed, Aug 17, 2022 at 03:05:52PM +0200, Geert Uytterhoeven wrote:
> > > > On Wed, Aug 17, 2022 at 1:15 PM Maxime Ripard <[email protected]> wrote:
> > > > > On Wed, Aug 17, 2022 at 10:35:07AM +0200, Geert Uytterhoeven wrote:
> > > > > > On Wed, Aug 17, 2022 at 9:47 AM Maxime Ripard <[email protected]> wrote:
> > > > > > > On Wed, Aug 17, 2022 at 09:31:18AM +0200, Geert Uytterhoeven wrote:
> > > > > > > > On Tue, Aug 16, 2022 at 5:50 PM Maxime Ripard <[email protected]> wrote:
> > > > > > > > > On Tue, Aug 16, 2022 at 04:43:44PM +0200, Geert Uytterhoeven wrote:
> > > > > > > > > > > > > > Either you have to add them here (e.g. "hd720p50" and "hd720p60"), or
> > > > > > > > > > > > > > handle them through "@<refresh>". The latter would impact "[PATCH v1
> > > > > > > > > > > > > > 09/35] drm/modes: Move named modes parsing to a separate function", as
> > > > > > > > > > > > > > currently a named mode and a refresh rate can't be specified both.
> > > > > > > > > > > > >
> > > > > > > > > > > > > I think the former would make more sense. It simplifies a bit the
> > > > > > > > > > > > > parser, and we're going to use a named mode anyway.
> > > > > > > > > > > > >
> > > > > > > > > > > > > > As "[PATCH v1 34/35] drm/modes: Introduce the tv_mode property as a
> > > > > > > > > > > > > > command-line option" uses a separate "tv_mode" option, and not the main
> > > > > > > > > > > > > > mode name, I think you want to add them here.
> > > > > > > > > > > > >
> > > > > > > > > > > > > It's a separate story I think, we could have a named mode hd720p50,
> > > > > > > > > > > > > which would be equivalent to 1280x720,tv_mode=hd720p
> > > > > > > > > > > >
> > > > > > > > > > > > So where's the field rate in "1280x720,tv_mode=hd720p"?
> > > > > > > > > > >
> > > > > > > > > > > Yeah, sorry I meant 1280x720@50,tv_mode=hd720p
> > > > > > > > > >
> > > > > > > > > > Above you said "I think the former would make more sense", so that
> > > > > > > > > > should be "1280x720,tv_mode=hd720p50"?
> > > > > > > > >
> > > > > > > > > No, 720p at 50Hz would be either hd720p50 or 1280x720@50,tv_mode=hd720p
> > > > > > > > > and 60Hz would be hd720p60 or 1280x720@60,tv_mode=hd720p
> > > > > > > >
> > > > > > > > I disagree: hd720p50 and hd720p60 are different TV modes.
> > > > > > >
> > > > > > > I agree, and I don't see how that command-line doesn't express that?
> > > > > >
> > > > > > Oh, I see what you mean: yes, it expresses that.
> > > > > > But it is inconsistent with the NTSC/PAL/SECAM/hd{480,576}[ip] modes,
> > > > > > where the TV mode specifies both number of lines and frame rate.
> > > > >
> > > > > Only if we're using a named mode, and naming is hard :)
> > > >
> > > > That's not true: "640x480,tv_mode=PAL-N" would give me a mode with
> > > > 625 lines and 25 frames/s, "640x480,tv_mode=PAL-M" would give me a
> > > > mode with 525 lines and 30 frames/s.
> > >
> > > In that series, "640x480,tv_mode=PAL-N" would be rejected as invalid:
> > >
> > > https://lore.kernel.org/dri-devel/[email protected]/
> >
> > It would become supported once the ideas from thread "[PATCH v1 04/35]
> > drm/modes: Introduce 480i and 576i modes" are implemented...
>
> Indeed, but I'm still not sure what your concern is here.
> "640x480,tv_mode=PAL-N" and "640x480,tv_mode=PAL-M" are both fairly
> obvious.
>
> You were initially saying that you had concern over the inconsistency of
> NTSC/PAL/SECAM where the TV mode would specify a number of lines and
> frame rate, but hd720p50 also specifies a number of line and frame rate?

My concern is that you want to call the TV mode "hd720p", which
does not dictate the frame rate.
I would like to have both "720p50" and "720p60", as they do dictate
the frame rate, like all the non-hd modes.

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

2022-08-18 15:48:24

by Maxime Ripard

[permalink] [raw]
Subject: Re: [PATCH v1 05/35] drm/connector: Add TV standard property

On Wed, Aug 17, 2022 at 03:11:56PM +0200, Noralf Tr?nnes wrote:
> Den 17.08.2022 13.46, skrev Maxime Ripard:
> > On Tue, Aug 16, 2022 at 09:35:24PM +0200, Noralf Tr?nnes wrote:
> >> Den 16.08.2022 11.49, skrev Maxime Ripard:
> >>> On Tue, Aug 16, 2022 at 11:42:20AM +0200, Noralf Tr?nnes wrote:
> >>>> Den 16.08.2022 10.26, skrev Maxime Ripard:
> >>>>> Hi,
> >>>>>
> >>>>> On Mon, Aug 08, 2022 at 02:44:56PM +0200, Noralf Tr?nnes wrote:
> >>>>>> Den 29.07.2022 18.34, skrev Maxime Ripard:
> >>>>>>> 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 <[email protected]>
> >>>>>>>
> >>>>>>
> >>>>>> Please also update Documentation/gpu/kms-properties.csv
> >>>>>>
> >>>>>> Requirements for adding a new property is found in
> >>>>>> Documentation/gpu/drm-kms.rst
> >>>>>
> >>>>> I knew this was going to be raised at some point, so I'm glad it's that
> >>>>> early :)
> >>>>>
> >>>>> I really don't know what to do there. If we stick by our usual rules,
> >>>>> then we can't have any of that work merged.
> >>>>>
> >>>>> However, I think the status quo is not really satisfactory either.
> >>>>> Indeed, we have a property, that doesn't follow those requirements
> >>>>> either, with a driver-specific content, and that stands in the way of
> >>>>> fixes and further improvements at both the core framework and driver
> >>>>> levels.
> >>>>>
> >>>>> So having that new property still seems like a net improvement at the
> >>>>> driver, framework and uAPI levels, even if it's not entirely following
> >>>>> the requirements we have in place.
> >>>>>
> >>>>> Even more so since, realistically, those kind of interfaces will never
> >>>>> get any new development on the user-space side of things, it's
> >>>>> considered by everyone as legacy.
> >>>>>
> >>>>> This also is something we need to support at some point if we want to
> >>>>> completely deprecate the fbdev drivers and provide decent alternatives
> >>>>> in KMS.
> >>>>>
> >>>>> So yeah, strictly speaking, we would not qualify for our requirements
> >>>>> there. I still think we have a strong case for an exception though.
> >>>>
> >>>> Which requirements would that be? The only one I can see is the
> >>>> documentation and maybe an IGT test.
> >>>
> >>> This is the one I had in mind
> >>> https://dri.freedesktop.org/docs/drm/gpu/drm-uapi.html#open-source-userspace-requirements
> >>>
> >>
> >> Oh right, I had forgotten about that one.
> >>
> >> One benefit of having a userspace implementation is that it increases
> >> the chance of widespread adoption having a working implementation to
> >> look at. I don't think the reason tv.mode is not used anywhere (that I
> >> know of) is because the driver picks the enum values resulting in no
> >> standard names.
> >
> > It probably doesn't help, but it's not what I was implying.
> >
> >> It's a niche thing and way down on the todo list. nouveau and ch7006
> >> has a tv_norm module parameter which certainly doesn't help in moving
> >> people/projects over to the DRM property (downstream rpi also has it
> >> now).
> >
> > Yeah, the RPi version is part of the reason I started working on this.
> > We should also consider the named modes used by vc4 and sun4i. All these
> > ad-hoc solutions are limited and (I think) come from the fact that we
> > don't have a solution easy enough to use for drivers (and to discover).
> >
> > nouveau, ch7006, i915 and vc4 are using the tv.mode property for
> > example, but sun4i and meson don't.
> >
> > sun4i relies on named modes to reimplement TV modes, but meson doesn't
> > at all.
> >
> > And then nouveau has that extra command line parameter to set it up at
> > boot time.
> >
> > It doesn't really make much sense to me, when all drivers have very
> > similar needs, that none of them behave in the same way. And I think the
> > non-standard property is partly to blame for this, since without some
> > generic content we can't share code.
> >
> > This is what this series is about: every driver having similar
> > capabilities and as trivially as possible.
> >
> >> mpv[1] is a commandline media player that after a quick look might be a
> >> candidate for implementing the property without too much effort.
> >
> > Kodi might be another one. I can try to hack something around, but I'm
> > really skeptical about whether a PR would be merged or not.
> >
>
> You can ask first before wasting time ofc.

Yep, will do.

> But this baffles me, if you don't think projects like Kodi which is TV
> centered want this, what kind of projects do you think want to use this
> property?

I mean, at this point it's really a consolidation of stuff we have
scattered around the kernel tree, in order to clean up that mess, and
not add more hacks.

And it allows the current effort to move the remaining fbdev drivers
into KMS.

As far as userspace is concerned, I don't know who is still using it
or cares today.

I still believe that refactoring is beneficial though, if only to make
one more nail in fbdev's coffin.

> >> How do you test the property? I've used modetest but I can only change
> >> to a tv.mode that matches the current display mode. I can't switch from
> >> ntsc to pal for instance.
> >
> > Yep, if you want to change from PAL to NTSC, it will require a new mode.
>
> So userspace has to check tv.mode first and then create a display mode
> the driver will accept if switching to a different display mode is
> necessary?

I'd expect drivers to expose both 576i and 480i (that's what vc4 and
sun4i are doing), so the userspace can pick them up.

> In other words, userspace can't discover from the kernel which display
> modes a certain tv.mode/norm provides before it is selected?

It's kind of the other way around in my mind, but the userspace would
have to figure out what display mode can use what tv mode, yes.

Even more so since Geert and I are discussing to allow continuous modes,
so we would allow to have modes with the same (active) resolution but a
different tv mode.

> If so, maybe libdrm should have some function(s) to deal with
> switching between modes that require a different display mode since
> knowledge about which display modes a tv.mode supports is needed
> before hand.

I'm not sure what you mean here, sorry. It's fairly easy to update a
property and the mode with atomic?

Maxime


Attachments:
(No filename) (6.97 kB)
signature.asc (235.00 B)
Download all attachments

2022-08-18 15:49:39

by Maxime Ripard

[permalink] [raw]
Subject: Re: [PATCH v1 05/35] drm/connector: Add TV standard property

On Thu, Aug 18, 2022 at 05:01:38PM +0200, Noralf Tr?nnes wrote:
>
>
> Den 18.08.2022 01.23, skrev Noralf Tr?nnes:
> >
> >
> > Den 17.08.2022 15.11, skrev Noralf Tr?nnes:
> >>
> >>
> >> Den 17.08.2022 13.46, skrev Maxime Ripard:
> >>> On Tue, Aug 16, 2022 at 09:35:24PM +0200, Noralf Tr?nnes wrote:
> >>>> Den 16.08.2022 11.49, skrev Maxime Ripard:
> >>>>> On Tue, Aug 16, 2022 at 11:42:20AM +0200, Noralf Tr?nnes wrote:
> >>>>>> Den 16.08.2022 10.26, skrev Maxime Ripard:
> >>>>>>> Hi,
> >>>>>>>
> >>>>>>> On Mon, Aug 08, 2022 at 02:44:56PM +0200, Noralf Tr?nnes wrote:
> >>>>>>>> Den 29.07.2022 18.34, skrev Maxime Ripard:
> >>>>>>>>> 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 <[email protected]>
> >>>>>>>>>
> >
> >>>> How do you test the property? I've used modetest but I can only change
> >>>> to a tv.mode that matches the current display mode. I can't switch from
> >>>> ntsc to pal for instance.
> >>>
> >>> Yep, if you want to change from PAL to NTSC, it will require a new mode.
> >>>
> >>
> >> So userspace has to check tv.mode first and then create a display mode
> >> the driver will accept if switching to a different display mode is
> >> necessary? In other words, userspace can't discover from the kernel
> >> which display modes a certain tv.mode/norm provides before it is
> >> selected? If so, maybe libdrm should have some function(s) to deal with
> >> switching between modes that require a different display mode since
> >> knowledge about which display modes a tv.mode supports is needed before
> >> hand.
> >>
> >
> > I haven't used vc4 on Pi4 in mainline before and have finally gotten it
> > to work.
> >
> > I see that the connector reports 2 modes that together fit all tv.norms
> > so userspace doesn't have to contruct a display mode, but it does need
> > to know which display mode belongs to a certain tv.norm.
> >
> > When I try to use modetest I'm unable to set a mode:
> >
> > pi@pi4t:~ $ modetest -M vc4 -s 45:720x480i
> > setting mode 720x480i-29.97Hz on connectors 45, crtc 68
> > failed to set mode: Function not implemented
> >
> > The errno is misleading, modetest does a drmModeDirtyFB before checking
> > the error returned by drmModeSetCrtc.
> >
> > Setting the property succeeds, but the modeset still fails:
> >
> > pi@pi4t:~ $ modetest -M vc4 -s 45:720x480i -w 45:"tv norm":2
> > setting mode 720x480i-29.97Hz on connectors 45, crtc 68
> > failed to set mode: Function not implemented
> >
> > pi@pi4t:~ $ modetest -M vc4 -c
> > 37 tv norm:
> > flags: bitmask
> > values: NTSC-443=0x1 NTSC-J=0x2 NTSC-M=0x4 PAL-B=0x10
> > PAL-M=0x200 PAL-N=0x400 SECAM-B=0x2000
> > value: 2
> >
> > Here's the log, can you see if there's anything obvious in there:
> > https://gist.github.com/notro/a079498bf6b64327105752b2bafa8858
> >
>
> I'm one step closer as I now have fbcon working, I had forgotten to add
> enable_tvout=1 and I had disable_fw_kms_setup=1 which disables the
> video= mode on the kernel commandline.
>
> modetest still fails though, after alot of printk sprinkling, I've
> tracked it down to the drm_mode_equal test in
> drm_atomic_helper_connector_tv_check(). The aspect ratios differ:
>
> [ 61.336295] drm_atomic_helper_connector_tv_check:
> mode->picture_aspect_ratio=1
> [ 61.336301] drm_atomic_helper_connector_tv_check:
> &crtc_state->mode->picture_aspect_ratio=0

I haven't seen this when testing, but I'll have a look, thanks!
Maxime


Attachments:
(No filename) (4.18 kB)
signature.asc (235.00 B)
Download all attachments

2022-08-18 15:50:14

by Maxime Ripard

[permalink] [raw]
Subject: Re: [PATCH v1 05/35] drm/connector: Add TV standard property

On Thu, Aug 18, 2022 at 05:20:42PM +0200, Geert Uytterhoeven wrote:
> Hi Maxime,
>
> On Thu, Aug 18, 2022 at 4:54 PM Maxime Ripard <[email protected]> wrote:
> > On Wed, Aug 17, 2022 at 04:04:24PM +0200, Geert Uytterhoeven wrote:
> > > On Wed, Aug 17, 2022 at 3:19 PM Maxime Ripard <[email protected]> wrote:
> > > > On Wed, Aug 17, 2022 at 03:05:52PM +0200, Geert Uytterhoeven wrote:
> > > > > On Wed, Aug 17, 2022 at 1:15 PM Maxime Ripard <[email protected]> wrote:
> > > > > > On Wed, Aug 17, 2022 at 10:35:07AM +0200, Geert Uytterhoeven wrote:
> > > > > > > On Wed, Aug 17, 2022 at 9:47 AM Maxime Ripard <[email protected]> wrote:
> > > > > > > > On Wed, Aug 17, 2022 at 09:31:18AM +0200, Geert Uytterhoeven wrote:
> > > > > > > > > On Tue, Aug 16, 2022 at 5:50 PM Maxime Ripard <[email protected]> wrote:
> > > > > > > > > > On Tue, Aug 16, 2022 at 04:43:44PM +0200, Geert Uytterhoeven wrote:
> > > > > > > > > > > > > > > Either you have to add them here (e.g. "hd720p50" and "hd720p60"), or
> > > > > > > > > > > > > > > handle them through "@<refresh>". The latter would impact "[PATCH v1
> > > > > > > > > > > > > > > 09/35] drm/modes: Move named modes parsing to a separate function", as
> > > > > > > > > > > > > > > currently a named mode and a refresh rate can't be specified both.
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > I think the former would make more sense. It simplifies a bit the
> > > > > > > > > > > > > > parser, and we're going to use a named mode anyway.
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > > As "[PATCH v1 34/35] drm/modes: Introduce the tv_mode property as a
> > > > > > > > > > > > > > > command-line option" uses a separate "tv_mode" option, and not the main
> > > > > > > > > > > > > > > mode name, I think you want to add them here.
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > It's a separate story I think, we could have a named mode hd720p50,
> > > > > > > > > > > > > > which would be equivalent to 1280x720,tv_mode=hd720p
> > > > > > > > > > > > >
> > > > > > > > > > > > > So where's the field rate in "1280x720,tv_mode=hd720p"?
> > > > > > > > > > > >
> > > > > > > > > > > > Yeah, sorry I meant 1280x720@50,tv_mode=hd720p
> > > > > > > > > > >
> > > > > > > > > > > Above you said "I think the former would make more sense", so that
> > > > > > > > > > > should be "1280x720,tv_mode=hd720p50"?
> > > > > > > > > >
> > > > > > > > > > No, 720p at 50Hz would be either hd720p50 or 1280x720@50,tv_mode=hd720p
> > > > > > > > > > and 60Hz would be hd720p60 or 1280x720@60,tv_mode=hd720p
> > > > > > > > >
> > > > > > > > > I disagree: hd720p50 and hd720p60 are different TV modes.
> > > > > > > >
> > > > > > > > I agree, and I don't see how that command-line doesn't express that?
> > > > > > >
> > > > > > > Oh, I see what you mean: yes, it expresses that.
> > > > > > > But it is inconsistent with the NTSC/PAL/SECAM/hd{480,576}[ip] modes,
> > > > > > > where the TV mode specifies both number of lines and frame rate.
> > > > > >
> > > > > > Only if we're using a named mode, and naming is hard :)
> > > > >
> > > > > That's not true: "640x480,tv_mode=PAL-N" would give me a mode with
> > > > > 625 lines and 25 frames/s, "640x480,tv_mode=PAL-M" would give me a
> > > > > mode with 525 lines and 30 frames/s.
> > > >
> > > > In that series, "640x480,tv_mode=PAL-N" would be rejected as invalid:
> > > >
> > > > https://lore.kernel.org/dri-devel/[email protected]/
> > >
> > > It would become supported once the ideas from thread "[PATCH v1 04/35]
> > > drm/modes: Introduce 480i and 576i modes" are implemented...
> >
> > Indeed, but I'm still not sure what your concern is here.
> > "640x480,tv_mode=PAL-N" and "640x480,tv_mode=PAL-M" are both fairly
> > obvious.
> >
> > You were initially saying that you had concern over the inconsistency of
> > NTSC/PAL/SECAM where the TV mode would specify a number of lines and
> > frame rate, but hd720p50 also specifies a number of line and frame rate?
>
> My concern is that you want to call the TV mode "hd720p", which
> does not dictate the frame rate.
> I would like to have both "720p50" and "720p60", as they do dictate
> the frame rate, like all the non-hd modes.

But they don't?

The refresh rate is part of the drm_display_mode, whereas that property
is metadata and entirely separate from the display mode.

You can even change it without changing the mode at all

Maxime


Attachments:
(No filename) (4.44 kB)
signature.asc (235.00 B)
Download all attachments

2022-08-18 16:05:12

by Maxime Ripard

[permalink] [raw]
Subject: Re: [PATCH v1 04/35] drm/modes: Introduce 480i and 576i modes

On Thu, Aug 18, 2022 at 05:34:30PM +0200, Geert Uytterhoeven wrote:
> On Thu, Aug 18, 2022 at 3:42 PM Maxime Ripard <[email protected]> wrote:
> > On Thu, Aug 18, 2022 at 02:57:55PM +0200, Geert Uytterhoeven wrote:
> > > On Thu, Aug 18, 2022 at 2:39 PM Maxime Ripard <[email protected]> wrote:
> > > > On Wed, Aug 17, 2022 at 04:01:48PM +0200, Geert Uytterhoeven wrote:
> > > > > > I've looked around and it looks like the entire blanking area is
> > > > > > supposed to be 40 pixels in interlaced, but I couldn't find anywhere how
> > > > >
> > > > > 625 lines - 575[*] visible lines = 50 lines.
> > > > >
> > > > > [*] BT.656 uses 576 visible lines as that's a multiple of 2, for splitting
> > > > > a frame in two fields of equal size.
> > > > >
> > > > > "visible" is relative, as it includes the overscan region.
> > > > > Some PAL monitors used with computers had knobs to control width/height
> > > > > and position of the screen, so you could make use of most or all of
> > > > > the overscan region
> > > >
> > > > It brings back some memories :)
> > > >
> > > > > but on a real TV you're limited to ca. 640x512 (on PAL) which is what
> > > > > an Amiga used by default (with a 14 MHz pixclock).
> > > >
> > > > > > it's supposed to be split between the upper and lower margins and the
> > > > > > sync period.
> > > > >
> > > > > "Field Synchronization of PAL System" on
> > > > > http://martin.hinner.info/vga/pal.html shows the split.
> > > >
> > > > Thanks, that's excellent as well.
> > > >
> > > > I'm mostly done with a function that creates a PAL mode, but I still
> > > > have one question.
> > > >
> > > > If I understand well, the blanking period is made up (interlace) of 16
> > > > pulses for the first field, 14 for the second, each pulse taking half a
> > > > line. That amount to 30 pulses, so 15 lines.
> > > >
> > > > I first assumed that the pre-equalizing pulses would be the back porch,
> > > > the long sync pulses the vsync, and the post-equalizing pulses the front
> > > > porch. But... we're still missing 35 lines to amount to 625 lines, that
> > > > seems to be counted in the field itself (305 lines == (575 + 35) / 2)
> > > >
> > > > So I guess my assumption was wrong to begin with.
> > >
> > > The back porch is the number of lines between the last "visible" line
> > > and the start of the synchronization pulse, i.e. "l" in the "Field
> > > Synchronization of PAL System" drawing.
> > > Virtual sync length is "m".
> > > The front porch is the number of lines between the end of
> > > the synchronization pulse, and the first "visible" line, i.e.
> > > "j - l - m" (I think you used "n", thus missing lines 6-23 and 319-335).
> >
> > Ah, yes, that makes sense
> >
> > > > You seem to have used a fixed vsync in amifb to 4 lines, and I don't
> > >
> > > Actually "m" is 2.5 lines in the first field, and 3 lines in the second field,
> > > so "4" is not that much off of 2.5 + 3.
> >
> > Is it? If I'm reading that drawing well, l before the first field starts
> > on the second half of line 623 and stops at the end of line 625, so 2.5
> > line, and on the second field starts at the beginning of line 311, and
> > stops half-way through 313 so 2.5 line again.
> >
> > Then, for the first field, m starts at the beginning of line 1, stops
> > half-way through line 3, so 2.5 line indeed, and then on the second
> > field starts on the second half of 313 and stops at the end of line 315.
> > So 2.5 again?
> >
> > Thus, both should be 5?
>
> Possibly. Note that this for the official broadcast PAL.
>
> I never looked at these signals with a scope, but I wouldn't be
> surprised if some
> device on't bother implementing the "half-line-sync", and synchronize
> the start and stop of the vertical
> sync signal with the start of a horizontal.

Yeah... official PAL looks like a good enough target to me :)

We'll always be able to tweak it if needed later on.

> > > > understand how you come up with the upper and lower margins (or rather,
> > > > how they are linked to what's described in that page)
> > >
> > > These margins probably came from the Amiga hardware reference manual,
> > > for the default 640x512 (PAL) and 640x400 (NTSC) modes.
> >
> > Ok.
> >
> > I started adding more sanity checks to my code, and I just realised I
> > don't seem to be able to reach 720 pixels over a single line though. If
> > I understood it properly, and according to [1] the active part of a line
> > is supposed to be 51.95us, and the blanking period taking 12.05us. [2]
> > in the timing section has pretty much the same numbers, so it looks
> > sane.
> >
> > At 13.5Mhz, a pixel is going to take roughly 74ns, and 51950 / 74 = 702
> > pixels
> >
> > It seems we can go push it to 52350 ns, but that still gives us only 706
> > pixels.
> >
> > Similarly, if I just choose to ignore that limit and just take the
> > active time I need, 720 * 74 = 53280ns
> >
> > That leaves us 10720ns for the blanking period, and that's not enough to
> > fit even the minimum of the front porch, hsync and back porch (1.55 +
> > 4.5 + 5.5 = 11.55us).
> >
> > Are those constraints merely recommendations, or am I missing something?
>
> You are missing that the parts near the borders of the full image are
> part of the overscan range, and may or may not be visible, depending
> on your actual display.
> The full 768x576 image size from BT.656 is not visible on a typical PAL display,
> and is more of an "absolute maximum rating", guaranteed to cover more
> than analog PAL.

So the overscan range is not part of the active area, unlike what HDMI
is doing for example?

Is there some minimal timings available somewhere to fit those absolute
maximum ratings?

Maxime


Attachments:
(No filename) (5.69 kB)
signature.asc (235.00 B)
Download all attachments

2022-08-18 16:07:38

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH v1 04/35] drm/modes: Introduce 480i and 576i modes

Hi Maxime,

On Thu, Aug 18, 2022 at 3:42 PM Maxime Ripard <[email protected]> wrote:
> On Thu, Aug 18, 2022 at 02:57:55PM +0200, Geert Uytterhoeven wrote:
> > On Thu, Aug 18, 2022 at 2:39 PM Maxime Ripard <[email protected]> wrote:
> > > On Wed, Aug 17, 2022 at 04:01:48PM +0200, Geert Uytterhoeven wrote:
> > > > > I've looked around and it looks like the entire blanking area is
> > > > > supposed to be 40 pixels in interlaced, but I couldn't find anywhere how
> > > >
> > > > 625 lines - 575[*] visible lines = 50 lines.
> > > >
> > > > [*] BT.656 uses 576 visible lines as that's a multiple of 2, for splitting
> > > > a frame in two fields of equal size.
> > > >
> > > > "visible" is relative, as it includes the overscan region.
> > > > Some PAL monitors used with computers had knobs to control width/height
> > > > and position of the screen, so you could make use of most or all of
> > > > the overscan region
> > >
> > > It brings back some memories :)
> > >
> > > > but on a real TV you're limited to ca. 640x512 (on PAL) which is what
> > > > an Amiga used by default (with a 14 MHz pixclock).
> > >
> > > > > it's supposed to be split between the upper and lower margins and the
> > > > > sync period.
> > > >
> > > > "Field Synchronization of PAL System" on
> > > > http://martin.hinner.info/vga/pal.html shows the split.
> > >
> > > Thanks, that's excellent as well.
> > >
> > > I'm mostly done with a function that creates a PAL mode, but I still
> > > have one question.
> > >
> > > If I understand well, the blanking period is made up (interlace) of 16
> > > pulses for the first field, 14 for the second, each pulse taking half a
> > > line. That amount to 30 pulses, so 15 lines.
> > >
> > > I first assumed that the pre-equalizing pulses would be the back porch,
> > > the long sync pulses the vsync, and the post-equalizing pulses the front
> > > porch. But... we're still missing 35 lines to amount to 625 lines, that
> > > seems to be counted in the field itself (305 lines == (575 + 35) / 2)
> > >
> > > So I guess my assumption was wrong to begin with.
> >
> > The back porch is the number of lines between the last "visible" line
> > and the start of the synchronization pulse, i.e. "l" in the "Field
> > Synchronization of PAL System" drawing.
> > Virtual sync length is "m".
> > The front porch is the number of lines between the end of
> > the synchronization pulse, and the first "visible" line, i.e.
> > "j - l - m" (I think you used "n", thus missing lines 6-23 and 319-335).
>
> Ah, yes, that makes sense
>
> > > You seem to have used a fixed vsync in amifb to 4 lines, and I don't
> >
> > Actually "m" is 2.5 lines in the first field, and 3 lines in the second field,
> > so "4" is not that much off of 2.5 + 3.
>
> Is it? If I'm reading that drawing well, l before the first field starts
> on the second half of line 623 and stops at the end of line 625, so 2.5
> line, and on the second field starts at the beginning of line 311, and
> stops half-way through 313 so 2.5 line again.
>
> Then, for the first field, m starts at the beginning of line 1, stops
> half-way through line 3, so 2.5 line indeed, and then on the second
> field starts on the second half of 313 and stops at the end of line 315.
> So 2.5 again?
>
> Thus, both should be 5?

Possibly. Note that this for the official broadcast PAL.

I never looked at these signals with a scope, but I wouldn't be
surprised if some
device on't bother implementing the "half-line-sync", and synchronize
the start and stop of the vertical
sync signal with the start of a horizontal.

> > > understand how you come up with the upper and lower margins (or rather,
> > > how they are linked to what's described in that page)
> >
> > These margins probably came from the Amiga hardware reference manual,
> > for the default 640x512 (PAL) and 640x400 (NTSC) modes.
>
> Ok.
>
> I started adding more sanity checks to my code, and I just realised I
> don't seem to be able to reach 720 pixels over a single line though. If
> I understood it properly, and according to [1] the active part of a line
> is supposed to be 51.95us, and the blanking period taking 12.05us. [2]
> in the timing section has pretty much the same numbers, so it looks
> sane.
>
> At 13.5Mhz, a pixel is going to take roughly 74ns, and 51950 / 74 = 702
> pixels
>
> It seems we can go push it to 52350 ns, but that still gives us only 706
> pixels.
>
> Similarly, if I just choose to ignore that limit and just take the
> active time I need, 720 * 74 = 53280ns
>
> That leaves us 10720ns for the blanking period, and that's not enough to
> fit even the minimum of the front porch, hsync and back porch (1.55 +
> 4.5 + 5.5 = 11.55us).
>
> Are those constraints merely recommendations, or am I missing something?

You are missing that the parts near the borders of the full image are
part of the overscan range, and may or may not be visible, depending
on your actual display.
The full 768x576 image size from BT.656 is not visible on a typical PAL display,
and is more of an "absolute maximum rating", guaranteed to cover more
than analog PAL.

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

2022-08-18 16:27:14

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH v1 04/35] drm/modes: Introduce 480i and 576i modes

Hi Maxime,

On Thu, Aug 18, 2022 at 5:46 PM Maxime Ripard <[email protected]> wrote:
> On Thu, Aug 18, 2022 at 05:34:30PM +0200, Geert Uytterhoeven wrote:
> > On Thu, Aug 18, 2022 at 3:42 PM Maxime Ripard <[email protected]> wrote:
> > > I started adding more sanity checks to my code, and I just realised I
> > > don't seem to be able to reach 720 pixels over a single line though. If
> > > I understood it properly, and according to [1] the active part of a line
> > > is supposed to be 51.95us, and the blanking period taking 12.05us. [2]
> > > in the timing section has pretty much the same numbers, so it looks
> > > sane.
> > >
> > > At 13.5Mhz, a pixel is going to take roughly 74ns, and 51950 / 74 = 702
> > > pixels
> > >
> > > It seems we can go push it to 52350 ns, but that still gives us only 706
> > > pixels.
> > >
> > > Similarly, if I just choose to ignore that limit and just take the
> > > active time I need, 720 * 74 = 53280ns
> > >
> > > That leaves us 10720ns for the blanking period, and that's not enough to
> > > fit even the minimum of the front porch, hsync and back porch (1.55 +
> > > 4.5 + 5.5 = 11.55us).
> > >
> > > Are those constraints merely recommendations, or am I missing something?
> >
> > You are missing that the parts near the borders of the full image are
> > part of the overscan range, and may or may not be visible, depending
> > on your actual display.
> > The full 768x576 image size from BT.656 is not visible on a typical PAL display,
> > and is more of an "absolute maximum rating", guaranteed to cover more
> > than analog PAL.
>
> So the overscan range is not part of the active area, unlike what HDMI
> is doing for example?

Indeed. DVI-D and HDMI etc. are pure digital (let's ignore they are a
digitized variant of old analog VGA ;-), hence there is a one-to-one
match between pixels in the image and pixels on the screen (ignoring
scaling). But even when using an analog VGA input on a modern
digital display, you have controls to e.g. move the image.

> Is there some minimal timings available somewhere to fit those absolute
> maximum ratings?

I guess they can be found on the Internet...

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

2022-08-19 10:09:26

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH v1 05/35] drm/connector: Add TV standard property

Hi Maxime,

On Thu, Aug 18, 2022 at 5:34 PM Maxime Ripard <[email protected]> wrote:
> On Thu, Aug 18, 2022 at 05:20:42PM +0200, Geert Uytterhoeven wrote:
> > On Thu, Aug 18, 2022 at 4:54 PM Maxime Ripard <[email protected]> wrote:
> > > On Wed, Aug 17, 2022 at 04:04:24PM +0200, Geert Uytterhoeven wrote:
> > > > On Wed, Aug 17, 2022 at 3:19 PM Maxime Ripard <[email protected]> wrote:
> > > > > On Wed, Aug 17, 2022 at 03:05:52PM +0200, Geert Uytterhoeven wrote:
> > > > > > On Wed, Aug 17, 2022 at 1:15 PM Maxime Ripard <[email protected]> wrote:
> > > > > > > On Wed, Aug 17, 2022 at 10:35:07AM +0200, Geert Uytterhoeven wrote:
> > > > > > > > On Wed, Aug 17, 2022 at 9:47 AM Maxime Ripard <[email protected]> wrote:
> > > > > > > > > On Wed, Aug 17, 2022 at 09:31:18AM +0200, Geert Uytterhoeven wrote:
> > > > > > > > > > On Tue, Aug 16, 2022 at 5:50 PM Maxime Ripard <[email protected]> wrote:
> > > > > > > > > > > On Tue, Aug 16, 2022 at 04:43:44PM +0200, Geert Uytterhoeven wrote:
> > > > > > > > > > > > > > > > Either you have to add them here (e.g. "hd720p50" and "hd720p60"), or
> > > > > > > > > > > > > > > > handle them through "@<refresh>". The latter would impact "[PATCH v1
> > > > > > > > > > > > > > > > 09/35] drm/modes: Move named modes parsing to a separate function", as
> > > > > > > > > > > > > > > > currently a named mode and a refresh rate can't be specified both.
> > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > I think the former would make more sense. It simplifies a bit the
> > > > > > > > > > > > > > > parser, and we're going to use a named mode anyway.
> > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > As "[PATCH v1 34/35] drm/modes: Introduce the tv_mode property as a
> > > > > > > > > > > > > > > > command-line option" uses a separate "tv_mode" option, and not the main
> > > > > > > > > > > > > > > > mode name, I think you want to add them here.
> > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > It's a separate story I think, we could have a named mode hd720p50,
> > > > > > > > > > > > > > > which would be equivalent to 1280x720,tv_mode=hd720p
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > So where's the field rate in "1280x720,tv_mode=hd720p"?
> > > > > > > > > > > > >
> > > > > > > > > > > > > Yeah, sorry I meant 1280x720@50,tv_mode=hd720p
> > > > > > > > > > > >
> > > > > > > > > > > > Above you said "I think the former would make more sense", so that
> > > > > > > > > > > > should be "1280x720,tv_mode=hd720p50"?
> > > > > > > > > > >
> > > > > > > > > > > No, 720p at 50Hz would be either hd720p50 or 1280x720@50,tv_mode=hd720p
> > > > > > > > > > > and 60Hz would be hd720p60 or 1280x720@60,tv_mode=hd720p
> > > > > > > > > >
> > > > > > > > > > I disagree: hd720p50 and hd720p60 are different TV modes.
> > > > > > > > >
> > > > > > > > > I agree, and I don't see how that command-line doesn't express that?
> > > > > > > >
> > > > > > > > Oh, I see what you mean: yes, it expresses that.
> > > > > > > > But it is inconsistent with the NTSC/PAL/SECAM/hd{480,576}[ip] modes,
> > > > > > > > where the TV mode specifies both number of lines and frame rate.
> > > > > > >
> > > > > > > Only if we're using a named mode, and naming is hard :)
> > > > > >
> > > > > > That's not true: "640x480,tv_mode=PAL-N" would give me a mode with
> > > > > > 625 lines and 25 frames/s, "640x480,tv_mode=PAL-M" would give me a
> > > > > > mode with 525 lines and 30 frames/s.
> > > > >
> > > > > In that series, "640x480,tv_mode=PAL-N" would be rejected as invalid:
> > > > >
> > > > > https://lore.kernel.org/dri-devel/[email protected]/
> > > >
> > > > It would become supported once the ideas from thread "[PATCH v1 04/35]
> > > > drm/modes: Introduce 480i and 576i modes" are implemented...
> > >
> > > Indeed, but I'm still not sure what your concern is here.
> > > "640x480,tv_mode=PAL-N" and "640x480,tv_mode=PAL-M" are both fairly
> > > obvious.
> > >
> > > You were initially saying that you had concern over the inconsistency of
> > > NTSC/PAL/SECAM where the TV mode would specify a number of lines and
> > > frame rate, but hd720p50 also specifies a number of line and frame rate?
> >
> > My concern is that you want to call the TV mode "hd720p", which
> > does not dictate the frame rate.
> > I would like to have both "720p50" and "720p60", as they do dictate
> > the frame rate, like all the non-hd modes.
>
> But they don't?
>
> The refresh rate is part of the drm_display_mode, whereas that property
> is metadata and entirely separate from the display mode.
>
> You can even change it without changing the mode at all

Yes, the refresh rate is part of drm_display_mode. Vdisplay also
is, but that doesn't mean you can set it to e.g. 700 when using
"tv_mode=PAL-B". Some (combination of) parameters in drm_display_mode
are dictated by the tv_mode.

Perhaps the meaning of "tv_mode" should be clarified? What does it
really mean, and what parameters does it (not) constrain?

For e.g. "PAL-B", I know it's a mode with 625 lines and 30 frames/s
(60 fields/s).
For "hd720p" I know it is an analog mode with 750 lines, but it's still
ambiguous, as I don't know if it is the variant with 60 or 50 frames/s.

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

2022-08-20 17:42:56

by Noralf Trønnes

[permalink] [raw]
Subject: Re: [PATCH v1 23/35] drm/vc4: vec: Convert to the new TV mode property



Den 29.07.2022 18.35, skrev Maxime Ripard:
> 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 <[email protected]>
>
> diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c

> static int vc4_vec_connector_get_modes(struct drm_connector *connector)
> {
> - struct drm_connector_state *state = connector->state;
> struct drm_display_mode *mode;
>
> - mode = drm_mode_duplicate(connector->dev,
> - vc4_vec_tv_modes[state->tv.mode].mode);
> + mode = drm_mode_duplicate(connector->dev, &drm_mode_480i);
> + if (!mode) {
> + DRM_ERROR("Failed to create a new display mode\n");
> + return -ENOMEM;
> + }
> +
> + drm_mode_probed_add(connector, mode);
> +
> + mode = drm_mode_duplicate(connector->dev, &drm_mode_576i);

Maybe the mode that matches tv.norm should be marked as preferred so
userspace knows which one to pick?

Noralf.

> if (!mode) {
> DRM_ERROR("Failed to create a new display mode\n");
> return -ENOMEM;
> @@ -277,21 +313,95 @@ static int vc4_vec_connector_get_modes(struct drm_connector *connector)
> return 1;
> }

2022-08-20 20:19:41

by Noralf Trønnes

[permalink] [raw]
Subject: Re: [PATCH v1 05/35] drm/connector: Add TV standard property



Den 29.07.2022 18.34, skrev Maxime Ripard:
> 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 <[email protected]>
>
> diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
> index c06d0639d552..d7ff6c644c2f 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->tv_mode_property) {
> state->tv.mode = val;
> + } else if (property == config->tv_norm_property) {
> + state->tv.norm = 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->tv_mode_property) {
> *val = state->tv.mode;
> + } else if (property == config->tv_norm_property) {
> + *val = state->tv.norm;
> } 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 e3142c8142b3..68a4e47f85a9 100644
> --- a/drivers/gpu/drm/drm_connector.c
> +++ b/drivers/gpu/drm/drm_connector.c
> @@ -1637,6 +1637,7 @@ EXPORT_SYMBOL(drm_mode_create_tv_margin_properties);
> /**
> * drm_mode_create_tv_properties - create TV specific connector properties
> * @dev: DRM device
> + * @supported_tv_norms: Bitmask of TV norms supported (See DRM_MODE_TV_NORM_*)
> * @num_modes: number of different TV formats (modes) supported
> * @modes: array of pointers to strings containing name of each format
> *
> @@ -1649,11 +1650,40 @@ EXPORT_SYMBOL(drm_mode_create_tv_margin_properties);
> * 0 on success or a negative error code on failure.
> */
> int drm_mode_create_tv_properties(struct drm_device *dev,
> + unsigned int supported_tv_norms,
> unsigned int num_modes,
> const char * const modes[])
> {
> + static const struct drm_prop_enum_list tv_norm_values[] = {
> + { __builtin_ffs(DRM_MODE_TV_NORM_NTSC_443) - 1, "NTSC-443" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_NTSC_J) - 1, "NTSC-J" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_NTSC_M) - 1, "NTSC-M" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_60) - 1, "PAL-60" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_B) - 1, "PAL-B" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_D) - 1, "PAL-D" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_G) - 1, "PAL-G" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_H) - 1, "PAL-H" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_I) - 1, "PAL-I" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_M) - 1, "PAL-M" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_N) - 1, "PAL-N" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_PAL_NC) - 1, "PAL-Nc" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_60) - 1, "SECAM-60" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_B) - 1, "SECAM-B" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_D) - 1, "SECAM-D" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_G) - 1, "SECAM-G" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_K) - 1, "SECAM-K" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_K1) - 1, "SECAM-K1" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_SECAM_L) - 1, "SECAM-L" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_HD480I) - 1, "hd480i" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_HD480P) - 1, "hd480p" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_HD576I) - 1, "hd576i" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_HD576P) - 1, "hd576p" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_HD720P) - 1, "hd720p" },
> + { __builtin_ffs(DRM_MODE_TV_NORM_HD1080I) - 1, "hd1080i" },
> + };
> struct drm_property *tv_selector;
> struct drm_property *tv_subconnector;
> + struct drm_property *tv_norm;
> unsigned int i;
>
> if (dev->mode_config.tv_select_subconnector_property)
> @@ -1686,6 +1716,13 @@ int drm_mode_create_tv_properties(struct drm_device *dev,
> if (drm_mode_create_tv_margin_properties(dev))
> goto nomem;
>
> + tv_norm = drm_property_create_bitmask(dev, 0, "tv norm",
> + tv_norm_values, ARRAY_SIZE(tv_norm_values),
> + supported_tv_norms);
> + if (!tv_norm)
> + goto nomem;
> + dev->mode_config.tv_norm_property = tv_norm;
> +
> dev->mode_config.tv_mode_property =
> drm_property_create(dev, DRM_MODE_PROP_ENUM,
> "mode", num_modes);
> diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c
> index 4a788c1c9058..457529e5d857 100644
> --- a/drivers/gpu/drm/vc4/vc4_vec.c
> +++ b/drivers/gpu/drm/vc4/vc4_vec.c
> @@ -573,7 +573,9 @@ 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(drm, ARRAY_SIZE(tv_mode_names),
> + ret = drm_mode_create_tv_properties(drm,
> + 0,
> + ARRAY_SIZE(tv_mode_names),
> tv_mode_names);
> if (ret)
> return ret;
> diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
> index 1e9996b33cc8..78275e68ff66 100644
> --- a/include/drm/drm_connector.h
> +++ b/include/drm/drm_connector.h
> @@ -143,6 +143,32 @@ enum subpixel_order {
>
> };
>
> +#define DRM_MODE_TV_NORM_NTSC_443 (1 << 0)
> +#define DRM_MODE_TV_NORM_NTSC_J (1 << 1)
> +#define DRM_MODE_TV_NORM_NTSC_M (1 << 2)
> +#define DRM_MODE_TV_NORM_PAL_60 (1 << 3)
> +#define DRM_MODE_TV_NORM_PAL_B (1 << 4)
> +#define DRM_MODE_TV_NORM_PAL_D (1 << 5)
> +#define DRM_MODE_TV_NORM_PAL_G (1 << 6)
> +#define DRM_MODE_TV_NORM_PAL_H (1 << 7)
> +#define DRM_MODE_TV_NORM_PAL_I (1 << 8)
> +#define DRM_MODE_TV_NORM_PAL_M (1 << 9)
> +#define DRM_MODE_TV_NORM_PAL_N (1 << 10)
> +#define DRM_MODE_TV_NORM_PAL_NC (1 << 11)
> +#define DRM_MODE_TV_NORM_SECAM_60 (1 << 12)
> +#define DRM_MODE_TV_NORM_SECAM_B (1 << 13)
> +#define DRM_MODE_TV_NORM_SECAM_D (1 << 14)
> +#define DRM_MODE_TV_NORM_SECAM_G (1 << 15)
> +#define DRM_MODE_TV_NORM_SECAM_K (1 << 16)
> +#define DRM_MODE_TV_NORM_SECAM_K1 (1 << 17)
> +#define DRM_MODE_TV_NORM_SECAM_L (1 << 18)
> +#define DRM_MODE_TV_NORM_HD480I (1 << 19)
> +#define DRM_MODE_TV_NORM_HD480P (1 << 20)
> +#define DRM_MODE_TV_NORM_HD576I (1 << 21)
> +#define DRM_MODE_TV_NORM_HD576P (1 << 22)
> +#define DRM_MODE_TV_NORM_HD720P (1 << 23)
> +#define DRM_MODE_TV_NORM_HD1080I (1 << 24)
> +

This is an area where DRM overlaps with v4l2, see:
- include/dt-bindings/display/sdtv-standards.h
- v4l2_norm_to_name()

Maybe we should follow suit, but if we do our own thing please mention
why in the commit message.

Noralf.

> /**
> * struct drm_scrambling: sink's scrambling support.
> */
> @@ -687,6 +713,7 @@ struct drm_tv_connector_state {
> enum drm_mode_subconnector subconnector;
> struct drm_connector_tv_margins margins;
> unsigned int mode;
> + unsigned int norm;
> unsigned int brightness;
> unsigned int contrast;
> unsigned int flicker_reduction;
> @@ -1779,6 +1806,7 @@ void drm_connector_attach_dp_subconnector_property(struct drm_connector *connect
>
> int drm_mode_create_tv_margin_properties(struct drm_device *dev);
> int drm_mode_create_tv_properties(struct drm_device *dev,
> + unsigned int supported_tv_norms,
> unsigned int num_modes,
> const char * const modes[]);
> void drm_connector_attach_tv_margin_properties(struct drm_connector *conn);
> diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
> index 6b5e01295348..d9e79def8b92 100644
> --- a/include/drm/drm_mode_config.h
> +++ b/include/drm/drm_mode_config.h
> @@ -704,6 +704,12 @@ struct drm_mode_config {
> */
> struct drm_property *dp_subconnector_property;
>
> + /**
> + * @tv_norm_property: Optional TV property to select the TV
> + * standard output on the connector.
> + */
> + struct drm_property *tv_norm_property;
> +
> /**
> * @tv_subconnector_property: Optional TV property to differentiate
> * between different TV connector types.
>

2022-08-21 11:56:13

by Noralf Trønnes

[permalink] [raw]
Subject: Re: [PATCH v1 05/35] drm/connector: Add TV standard property



Den 18.08.2022 17.31, skrev Maxime Ripard:
> On Thu, Aug 18, 2022 at 05:01:38PM +0200, Noralf Trønnes wrote:
>>
>>
>> Den 18.08.2022 01.23, skrev Noralf Trønnes:
>>>
>>>
>>> Den 17.08.2022 15.11, skrev Noralf Trønnes:
>>>>
>>>>
>>>> Den 17.08.2022 13.46, skrev Maxime Ripard:
>>>>> On Tue, Aug 16, 2022 at 09:35:24PM +0200, Noralf Trønnes wrote:
>>>>>> Den 16.08.2022 11.49, skrev Maxime Ripard:
>>>>>>> On Tue, Aug 16, 2022 at 11:42:20AM +0200, Noralf Trønnes wrote:
>>>>>>>> Den 16.08.2022 10.26, skrev Maxime Ripard:
>>>>>>>>> Hi,
>>>>>>>>>
>>>>>>>>> On Mon, Aug 08, 2022 at 02:44:56PM +0200, Noralf Trønnes wrote:
>>>>>>>>>> Den 29.07.2022 18.34, skrev Maxime Ripard:
>>>>>>>>>>> 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 <[email protected]>
>>>>>>>>>>>
>>>
>>>>>> How do you test the property? I've used modetest but I can only change
>>>>>> to a tv.mode that matches the current display mode. I can't switch from
>>>>>> ntsc to pal for instance.
>>>>>
>>>>> Yep, if you want to change from PAL to NTSC, it will require a new mode.
>>>>>
>>>>
>>>> So userspace has to check tv.mode first and then create a display mode
>>>> the driver will accept if switching to a different display mode is
>>>> necessary? In other words, userspace can't discover from the kernel
>>>> which display modes a certain tv.mode/norm provides before it is
>>>> selected? If so, maybe libdrm should have some function(s) to deal with
>>>> switching between modes that require a different display mode since
>>>> knowledge about which display modes a tv.mode supports is needed before
>>>> hand.
>>>>
>>>
>>> I haven't used vc4 on Pi4 in mainline before and have finally gotten it
>>> to work.
>>>
>>> I see that the connector reports 2 modes that together fit all tv.norms
>>> so userspace doesn't have to contruct a display mode, but it does need
>>> to know which display mode belongs to a certain tv.norm.
>>>
>>> When I try to use modetest I'm unable to set a mode:
>>>
>>> pi@pi4t:~ $ modetest -M vc4 -s 45:720x480i
>>> setting mode 720x480i-29.97Hz on connectors 45, crtc 68
>>> failed to set mode: Function not implemented
>>>
>>> The errno is misleading, modetest does a drmModeDirtyFB before checking
>>> the error returned by drmModeSetCrtc.
>>>
>>> Setting the property succeeds, but the modeset still fails:
>>>
>>> pi@pi4t:~ $ modetest -M vc4 -s 45:720x480i -w 45:"tv norm":2
>>> setting mode 720x480i-29.97Hz on connectors 45, crtc 68
>>> failed to set mode: Function not implemented
>>>
>>> pi@pi4t:~ $ modetest -M vc4 -c
>>> 37 tv norm:
>>> flags: bitmask
>>> values: NTSC-443=0x1 NTSC-J=0x2 NTSC-M=0x4 PAL-B=0x10
>>> PAL-M=0x200 PAL-N=0x400 SECAM-B=0x2000
>>> value: 2
>>>
>>> Here's the log, can you see if there's anything obvious in there:
>>> https://gist.github.com/notro/a079498bf6b64327105752b2bafa8858
>>>
>>
>> I'm one step closer as I now have fbcon working, I had forgotten to add
>> enable_tvout=1 and I had disable_fw_kms_setup=1 which disables the
>> video= mode on the kernel commandline.
>>
>> modetest still fails though, after alot of printk sprinkling, I've
>> tracked it down to the drm_mode_equal test in
>> drm_atomic_helper_connector_tv_check(). The aspect ratios differ:
>>
>> [ 61.336295] drm_atomic_helper_connector_tv_check:
>> mode->picture_aspect_ratio=1
>> [ 61.336301] drm_atomic_helper_connector_tv_check:
>> &crtc_state->mode->picture_aspect_ratio=0
>
> I haven't seen this when testing, but I'll have a look, thanks!

I have found the cause, the kernel strips off the aspect ratio in
drm_mode_getconnector() if drm_file->aspect_ratio_allowed is false. So I
think the drm_mode_equal() test needs to be relaxed for
legacy/non-atomic userspace to work.

If I use modetest with atomic commit (-a) it works as is, having the
drm_mode_equal() test:

$ modetest -M vc4 -a -P 61@68:720x480 -s 45:720x480i

I have a problem because the board hangs, either right away or after I
press <enter> to quit modetest.

I often get this, sometimes after 10s of seconds:

[ 136.822963] Unhandled fault: asynchronous external abort (0x1211) at
0x00000000
...
[ 137.248496] bcm2711_get_temp [bcm2711_thermal] from
thermal_zone_get_temp+0x54/0x74

Unloading bcm2711_thermal didn't help, in that case I got nothing, so
the problem lies elsewhere.
I have even tried with a fresh SD image and a fresh kernel, but it
didn't help.

I can switch from NTSC to PAL like this (but it still crashes):

$ modetest -M vc4 -a -w 45:"tv norm":16 -P 61@68:720x576 -s 45:720x576i

I had to patch modetest for that to work:

diff --git a/tests/modetest/modetest.c b/tests/modetest/modetest.c
index 8ff6c80d..accd2166 100644
--- a/tests/modetest/modetest.c
+++ b/tests/modetest/modetest.c
@@ -2188,12 +2187,13 @@ int main(int argc, char **argv)
dump_resource(&dev, planes);
dump_resource(&dev, framebuffers);

+ if (dev.use_atomic)
+ dev.req = drmModeAtomicAlloc();
+
for (i = 0; i < prop_count; ++i)
set_property(&dev, &prop_args[i]);

if (dev.use_atomic) {
- dev.req = drmModeAtomicAlloc();
-
if (set_preferred || (count && plane_count)) {
uint64_t cap = 0;


I use a composite to USB adapter to see the output:
https://www.adafruit.com/product/4715

Noralf.

2022-08-21 17:12:28

by Noralf Trønnes

[permalink] [raw]
Subject: Re: [PATCH v1 00/35] drm: Analog TV Improvements



Den 29.07.2022 18.34, skrev Maxime Ripard:
> Hi,
>
> Here's a series aiming at improving the command line named modes support,
> and more importantly how we deal with all the analog TV variants.
>
> The named modes support were initially introduced to allow to specify the
> analog TV mode to be used.
>
> However, this was causing multiple issues:
>
> * The mode name parsed on the command line was passed directly to the
> driver, which had to figure out which mode it was suppose to match;
>
> * Figuring that out wasn't really easy, since the video= argument or what
> the userspace might not even have a name in the first place, but
> instead could have passed a mode with the same timings;
>
> * The fallback to matching on the timings was mostly working as long as
> we were supporting one 525 lines (most likely NSTC) and one 625 lines
> (PAL), but couldn't differentiate between two modes with the same
> timings (NTSC vs PAL-M vs NSTC-J for example);
>
> * There was also some overlap with the tv mode property registered by
> drm_mode_create_tv_properties(), but named modes weren't interacting
> with that property at all.
>
> * Even though that property was generic, its possible values were
> specific to each drivers, which made some generic support difficult.
>
> Thus, I chose to tackle in multiple steps:
>
> * A new TV norm property was introduced, with generic values, each driver
> reporting through a bitmask what standard it supports to the userspace;
>
> * This option was added to the command line parsing code to be able to
> specify it on the kernel command line, and new atomic_check and reset
> helpers were created to integrate properly into atomic KMS;
>
> * The named mode parsing code is now creating a proper display mode for
> the given named mode, and the TV standard will thus be part of the
> connector state;
>
> * Two drivers were converted and tested for now (vc4 and sun4i), with
> some backward compatibility code to translate the old TV mode to the
> new TV mode;
>
> Unit tests were created along the way. Nouveau, ch7006 and gud are
> currently broken for now since I expect that work to be reworked fairly
> significantly. I'm also not entirely sure about how to migrate GUD to the
> new property.
>
> Let me know what you think,
> Maxime
>

I don't know if it's related to this patchset or not, but I do get this:

pi@pi4t:~ $ sudo dmesg -C && sudo modprobe -r vc4 && sudo modprobe vc4
&& dmesg
[ 430.066211] Console: switching to colour dummy device 80x30
[ 431.294788] vc4-drm gpu: bound fe400000.hvs (ops vc4_hvs_ops [vc4])
[ 431.295115] vc4-drm gpu: bound fec13000.vec (ops vc4_vec_ops [vc4])
[ 431.295467] vc4-drm gpu: bound fe004000.txp (ops vc4_txp_ops [vc4])
[ 431.295804] vc4-drm gpu: bound fec12000.pixelvalve (ops vc4_crtc_ops
[vc4])
[ 431.298895] [drm] Initialized vc4 0.0.0 20140616 for gpu on minor 0
[ 441.444250] vc4-drm gpu: [drm] *ERROR* [CRTC:68:crtc-1] flip_done
timed out
[ 441.446529] Console: switching to colour frame buffer device 90x30
[ 451.684321] vc4-drm gpu: [drm] *ERROR* flip_done timed out
[ 451.684347] vc4-drm gpu: [drm] *ERROR* [CRTC:68:crtc-1] commit wait
timed out
[ 461.924255] vc4-drm gpu: [drm] *ERROR* flip_done timed out
[ 461.924281] vc4-drm gpu: [drm] *ERROR* [CONNECTOR:45:Composite-1]
commit wait timed out
[ 472.164006] vc4-drm gpu: [drm] *ERROR* flip_done timed out
[ 472.164031] vc4-drm gpu: [drm] *ERROR* [PLANE:61:plane-1] commit wait
timed out
[ 482.403877] vc4-drm gpu: [drm] *ERROR* flip_done timed out
[ 482.403903] vc4-drm gpu: [drm] *ERROR* Timed out waiting for commit
[ 492.643799] vc4-drm gpu: [drm] *ERROR* [CRTC:68:crtc-1] flip_done
timed out
[ 492.647073] vc4-drm gpu: [drm] fb0: vc4drmfb frame buffer device

Noralf.

2022-08-22 08:07:10

by Maxime Ripard

[permalink] [raw]
Subject: Re: [PATCH v1 00/35] drm: Analog TV Improvements

Hi,

On Sun, Aug 21, 2022 at 06:33:12PM +0200, Noralf Tr?nnes wrote:
> Den 29.07.2022 18.34, skrev Maxime Ripard:
> > Hi,
> >
> > Here's a series aiming at improving the command line named modes support,
> > and more importantly how we deal with all the analog TV variants.
> >
> > The named modes support were initially introduced to allow to specify the
> > analog TV mode to be used.
> >
> > However, this was causing multiple issues:
> >
> > * The mode name parsed on the command line was passed directly to the
> > driver, which had to figure out which mode it was suppose to match;
> >
> > * Figuring that out wasn't really easy, since the video= argument or what
> > the userspace might not even have a name in the first place, but
> > instead could have passed a mode with the same timings;
> >
> > * The fallback to matching on the timings was mostly working as long as
> > we were supporting one 525 lines (most likely NSTC) and one 625 lines
> > (PAL), but couldn't differentiate between two modes with the same
> > timings (NTSC vs PAL-M vs NSTC-J for example);
> >
> > * There was also some overlap with the tv mode property registered by
> > drm_mode_create_tv_properties(), but named modes weren't interacting
> > with that property at all.
> >
> > * Even though that property was generic, its possible values were
> > specific to each drivers, which made some generic support difficult.
> >
> > Thus, I chose to tackle in multiple steps:
> >
> > * A new TV norm property was introduced, with generic values, each driver
> > reporting through a bitmask what standard it supports to the userspace;
> >
> > * This option was added to the command line parsing code to be able to
> > specify it on the kernel command line, and new atomic_check and reset
> > helpers were created to integrate properly into atomic KMS;
> >
> > * The named mode parsing code is now creating a proper display mode for
> > the given named mode, and the TV standard will thus be part of the
> > connector state;
> >
> > * Two drivers were converted and tested for now (vc4 and sun4i), with
> > some backward compatibility code to translate the old TV mode to the
> > new TV mode;
> >
> > Unit tests were created along the way. Nouveau, ch7006 and gud are
> > currently broken for now since I expect that work to be reworked fairly
> > significantly. I'm also not entirely sure about how to migrate GUD to the
> > new property.
> >
> > Let me know what you think,
> > Maxime
> >
>
> I don't know if it's related to this patchset or not, but I do get this:
>
> pi@pi4t:~ $ sudo dmesg -C && sudo modprobe -r vc4 && sudo modprobe vc4
> && dmesg
> [ 430.066211] Console: switching to colour dummy device 80x30
> [ 431.294788] vc4-drm gpu: bound fe400000.hvs (ops vc4_hvs_ops [vc4])
> [ 431.295115] vc4-drm gpu: bound fec13000.vec (ops vc4_vec_ops [vc4])
> [ 431.295467] vc4-drm gpu: bound fe004000.txp (ops vc4_txp_ops [vc4])
> [ 431.295804] vc4-drm gpu: bound fec12000.pixelvalve (ops vc4_crtc_ops
> [vc4])
> [ 431.298895] [drm] Initialized vc4 0.0.0 20140616 for gpu on minor 0
> [ 441.444250] vc4-drm gpu: [drm] *ERROR* [CRTC:68:crtc-1] flip_done
> timed out
> [ 441.446529] Console: switching to colour frame buffer device 90x30
> [ 451.684321] vc4-drm gpu: [drm] *ERROR* flip_done timed out
> [ 451.684347] vc4-drm gpu: [drm] *ERROR* [CRTC:68:crtc-1] commit wait
> timed out
> [ 461.924255] vc4-drm gpu: [drm] *ERROR* flip_done timed out
> [ 461.924281] vc4-drm gpu: [drm] *ERROR* [CONNECTOR:45:Composite-1]
> commit wait timed out
> [ 472.164006] vc4-drm gpu: [drm] *ERROR* flip_done timed out
> [ 472.164031] vc4-drm gpu: [drm] *ERROR* [PLANE:61:plane-1] commit wait
> timed out
> [ 482.403877] vc4-drm gpu: [drm] *ERROR* flip_done timed out
> [ 482.403903] vc4-drm gpu: [drm] *ERROR* Timed out waiting for commit
> [ 492.643799] vc4-drm gpu: [drm] *ERROR* [CRTC:68:crtc-1] flip_done
> timed out
> [ 492.647073] vc4-drm gpu: [drm] fb0: vc4drmfb frame buffer device

Module unloading/reloading has been janky for a while.

I've fixed it up recently but it doesn't surprise me that there's still
some situation that won't work. Is it on a Pi3?

Maxime

2022-08-22 09:06:37

by Mateusz Kwiatkowski

[permalink] [raw]
Subject: Re: [PATCH v1 00/35] drm: Analog TV Improvements

Hi Maxime,

I tried testing and reviewing your changes properly over the last weekend, but
ultimately ran into this ("flip_done timed out" etc.) issue and was unable to
mitigate it, at least so far. This seems to pop up every time I try to change
modes in any way (either change the TV norm, or just try doing
"xrandr --output Composite-1 --off" followed by bringing it back on; it also
means that the Pi goes unusable when the DE's screen saving routine kicks in).

I'm using a Pi 4, and it works with the rpi-5.13.y branch
https://github.com/raspberrypi/linux, but seemingly nothing newer.
I specifically tried rpi-5.14.y, rpi-5.15.y and rpi-5.19.y - rpi-5.15.y,
which is the current main branch in Raspberry Pi OS, seems to be broken since
forever; at least since my patches (originally written for 5.10) landed there.

I'll try identifying the issue further, possibly later today, and maybe check
the rpi-6.0.y branch as well.

Best regards,
Mateusz Kwiatkowski

W dniu 22.08.2022 o 09:48, Maxime Ripard pisze:
> Hi,
>
> On Sun, Aug 21, 2022 at 06:33:12PM +0200, Noralf Trønnes wrote:
>> Den 29.07.2022 18.34, skrev Maxime Ripard:
>>> Hi,
>>>
>>> Here's a series aiming at improving the command line named modes support,
>>> and more importantly how we deal with all the analog TV variants.
>>>
>>> The named modes support were initially introduced to allow to specify the
>>> analog TV mode to be used.
>>>
>>> However, this was causing multiple issues:
>>>
>>> * The mode name parsed on the command line was passed directly to the
>>> driver, which had to figure out which mode it was suppose to match;
>>>
>>> * Figuring that out wasn't really easy, since the video= argument or what
>>> the userspace might not even have a name in the first place, but
>>> instead could have passed a mode with the same timings;
>>>
>>> * The fallback to matching on the timings was mostly working as long as
>>> we were supporting one 525 lines (most likely NSTC) and one 625 lines
>>> (PAL), but couldn't differentiate between two modes with the same
>>> timings (NTSC vs PAL-M vs NSTC-J for example);
>>>
>>> * There was also some overlap with the tv mode property registered by
>>> drm_mode_create_tv_properties(), but named modes weren't interacting
>>> with that property at all.
>>>
>>> * Even though that property was generic, its possible values were
>>> specific to each drivers, which made some generic support difficult.
>>>
>>> Thus, I chose to tackle in multiple steps:
>>>
>>> * A new TV norm property was introduced, with generic values, each driver
>>> reporting through a bitmask what standard it supports to the userspace;
>>>
>>> * This option was added to the command line parsing code to be able to
>>> specify it on the kernel command line, and new atomic_check and reset
>>> helpers were created to integrate properly into atomic KMS;
>>>
>>> * The named mode parsing code is now creating a proper display mode for
>>> the given named mode, and the TV standard will thus be part of the
>>> connector state;
>>>
>>> * Two drivers were converted and tested for now (vc4 and sun4i), with
>>> some backward compatibility code to translate the old TV mode to the
>>> new TV mode;
>>>
>>> Unit tests were created along the way. Nouveau, ch7006 and gud are
>>> currently broken for now since I expect that work to be reworked fairly
>>> significantly. I'm also not entirely sure about how to migrate GUD to the
>>> new property.
>>>
>>> Let me know what you think,
>>> Maxime
>>>
>> I don't know if it's related to this patchset or not, but I do get this:
>>
>> pi@pi4t:~ $ sudo dmesg -C && sudo modprobe -r vc4 && sudo modprobe vc4
>> && dmesg
>> [ 430.066211] Console: switching to colour dummy device 80x30
>> [ 431.294788] vc4-drm gpu: bound fe400000.hvs (ops vc4_hvs_ops [vc4])
>> [ 431.295115] vc4-drm gpu: bound fec13000.vec (ops vc4_vec_ops [vc4])
>> [ 431.295467] vc4-drm gpu: bound fe004000.txp (ops vc4_txp_ops [vc4])
>> [ 431.295804] vc4-drm gpu: bound fec12000.pixelvalve (ops vc4_crtc_ops
>> [vc4])
>> [ 431.298895] [drm] Initialized vc4 0.0.0 20140616 for gpu on minor 0
>> [ 441.444250] vc4-drm gpu: [drm] *ERROR* [CRTC:68:crtc-1] flip_done
>> timed out
>> [ 441.446529] Console: switching to colour frame buffer device 90x30
>> [ 451.684321] vc4-drm gpu: [drm] *ERROR* flip_done timed out
>> [ 451.684347] vc4-drm gpu: [drm] *ERROR* [CRTC:68:crtc-1] commit wait
>> timed out
>> [ 461.924255] vc4-drm gpu: [drm] *ERROR* flip_done timed out
>> [ 461.924281] vc4-drm gpu: [drm] *ERROR* [CONNECTOR:45:Composite-1]
>> commit wait timed out
>> [ 472.164006] vc4-drm gpu: [drm] *ERROR* flip_done timed out
>> [ 472.164031] vc4-drm gpu: [drm] *ERROR* [PLANE:61:plane-1] commit wait
>> timed out
>> [ 482.403877] vc4-drm gpu: [drm] *ERROR* flip_done timed out
>> [ 482.403903] vc4-drm gpu: [drm] *ERROR* Timed out waiting for commit
>> [ 492.643799] vc4-drm gpu: [drm] *ERROR* [CRTC:68:crtc-1] flip_done
>> timed out
>> [ 492.647073] vc4-drm gpu: [drm] fb0: vc4drmfb frame buffer device
> Module unloading/reloading has been janky for a while.
>
> I've fixed it up recently but it doesn't surprise me that there's still
> some situation that won't work. Is it on a Pi3?
>
> Maxime


2022-08-22 13:44:06

by Noralf Trønnes

[permalink] [raw]
Subject: Re: [PATCH v1 00/35] drm: Analog TV Improvements



Den 22.08.2022 09.48, skrev Maxime Ripard:
> Hi,
>
> On Sun, Aug 21, 2022 at 06:33:12PM +0200, Noralf Trønnes wrote:
>> Den 29.07.2022 18.34, skrev Maxime Ripard:
>>> Hi,
>>>
>>> Here's a series aiming at improving the command line named modes support,
>>> and more importantly how we deal with all the analog TV variants.
>>>
>>> The named modes support were initially introduced to allow to specify the
>>> analog TV mode to be used.
>>>
>>> However, this was causing multiple issues:
>>>
>>> * The mode name parsed on the command line was passed directly to the
>>> driver, which had to figure out which mode it was suppose to match;
>>>
>>> * Figuring that out wasn't really easy, since the video= argument or what
>>> the userspace might not even have a name in the first place, but
>>> instead could have passed a mode with the same timings;
>>>
>>> * The fallback to matching on the timings was mostly working as long as
>>> we were supporting one 525 lines (most likely NSTC) and one 625 lines
>>> (PAL), but couldn't differentiate between two modes with the same
>>> timings (NTSC vs PAL-M vs NSTC-J for example);
>>>
>>> * There was also some overlap with the tv mode property registered by
>>> drm_mode_create_tv_properties(), but named modes weren't interacting
>>> with that property at all.
>>>
>>> * Even though that property was generic, its possible values were
>>> specific to each drivers, which made some generic support difficult.
>>>
>>> Thus, I chose to tackle in multiple steps:
>>>
>>> * A new TV norm property was introduced, with generic values, each driver
>>> reporting through a bitmask what standard it supports to the userspace;
>>>
>>> * This option was added to the command line parsing code to be able to
>>> specify it on the kernel command line, and new atomic_check and reset
>>> helpers were created to integrate properly into atomic KMS;
>>>
>>> * The named mode parsing code is now creating a proper display mode for
>>> the given named mode, and the TV standard will thus be part of the
>>> connector state;
>>>
>>> * Two drivers were converted and tested for now (vc4 and sun4i), with
>>> some backward compatibility code to translate the old TV mode to the
>>> new TV mode;
>>>
>>> Unit tests were created along the way. Nouveau, ch7006 and gud are
>>> currently broken for now since I expect that work to be reworked fairly
>>> significantly. I'm also not entirely sure about how to migrate GUD to the
>>> new property.
>>>
>>> Let me know what you think,
>>> Maxime
>>>
>>
>> I don't know if it's related to this patchset or not, but I do get this:
>>
>> pi@pi4t:~ $ sudo dmesg -C && sudo modprobe -r vc4 && sudo modprobe vc4
>> && dmesg
>> [ 430.066211] Console: switching to colour dummy device 80x30
>> [ 431.294788] vc4-drm gpu: bound fe400000.hvs (ops vc4_hvs_ops [vc4])
>> [ 431.295115] vc4-drm gpu: bound fec13000.vec (ops vc4_vec_ops [vc4])
>> [ 431.295467] vc4-drm gpu: bound fe004000.txp (ops vc4_txp_ops [vc4])
>> [ 431.295804] vc4-drm gpu: bound fec12000.pixelvalve (ops vc4_crtc_ops
>> [vc4])
>> [ 431.298895] [drm] Initialized vc4 0.0.0 20140616 for gpu on minor 0
>> [ 441.444250] vc4-drm gpu: [drm] *ERROR* [CRTC:68:crtc-1] flip_done
>> timed out
>> [ 441.446529] Console: switching to colour frame buffer device 90x30
>> [ 451.684321] vc4-drm gpu: [drm] *ERROR* flip_done timed out
>> [ 451.684347] vc4-drm gpu: [drm] *ERROR* [CRTC:68:crtc-1] commit wait
>> timed out
>> [ 461.924255] vc4-drm gpu: [drm] *ERROR* flip_done timed out
>> [ 461.924281] vc4-drm gpu: [drm] *ERROR* [CONNECTOR:45:Composite-1]
>> commit wait timed out
>> [ 472.164006] vc4-drm gpu: [drm] *ERROR* flip_done timed out
>> [ 472.164031] vc4-drm gpu: [drm] *ERROR* [PLANE:61:plane-1] commit wait
>> timed out
>> [ 482.403877] vc4-drm gpu: [drm] *ERROR* flip_done timed out
>> [ 482.403903] vc4-drm gpu: [drm] *ERROR* Timed out waiting for commit
>> [ 492.643799] vc4-drm gpu: [drm] *ERROR* [CRTC:68:crtc-1] flip_done
>> timed out
>> [ 492.647073] vc4-drm gpu: [drm] fb0: vc4drmfb frame buffer device
>
> Module unloading/reloading has been janky for a while.
>
> I've fixed it up recently but it doesn't surprise me that there's still
> some situation that won't work. Is it on a Pi3?
>

It's a Pi4.

Noralf.

2022-08-24 15:40:35

by Maxime Ripard

[permalink] [raw]
Subject: Re: [PATCH v1 23/35] drm/vc4: vec: Convert to the new TV mode property

Hi,

On Sat, Aug 20, 2022 at 07:22:48PM +0200, Noralf Tr?nnes wrote:
> Den 29.07.2022 18.35, skrev Maxime Ripard:
> > 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 <[email protected]>
> >
> > diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c
>
> > static int vc4_vec_connector_get_modes(struct drm_connector *connector)
> > {
> > - struct drm_connector_state *state = connector->state;
> > struct drm_display_mode *mode;
> >
> > - mode = drm_mode_duplicate(connector->dev,
> > - vc4_vec_tv_modes[state->tv.mode].mode);
> > + mode = drm_mode_duplicate(connector->dev, &drm_mode_480i);
> > + if (!mode) {
> > + DRM_ERROR("Failed to create a new display mode\n");
> > + return -ENOMEM;
> > + }
> > +
> > + drm_mode_probed_add(connector, mode);
> > +
> > + mode = drm_mode_duplicate(connector->dev, &drm_mode_576i);
>
> Maybe the mode that matches tv.norm should be marked as preferred so
> userspace knows which one to pick?

I'm not sure how realistic that would be. Doing this based on the driver
/ cmdline preference is going to be fairly easy, but then it's a
property, it's going to be updated, and we probably don't want to mess
around the mode flags based on new property values?

Maxime


Attachments:
(No filename) (1.49 kB)
signature.asc (235.00 B)
Download all attachments

2022-08-24 16:49:03

by Mateusz Kwiatkowski

[permalink] [raw]
Subject: Re: [PATCH v1 04/35] drm/modes: Introduce 480i and 576i modes

Hi Maxime,

W dniu 18.08.2022 o 17:56, Geert Uytterhoeven pisze:
> Hi Maxime,
>
> On Thu, Aug 18, 2022 at 5:46 PM Maxime Ripard <[email protected]> wrote:
>> On Thu, Aug 18, 2022 at 05:34:30PM +0200, Geert Uytterhoeven wrote:
>>> On Thu, Aug 18, 2022 at 3:42 PM Maxime Ripard <[email protected]> wrote:
>>>> I started adding more sanity checks to my code, and I just realised I
>>>> don't seem to be able to reach 720 pixels over a single line though. If
>>>> I understood it properly, and according to [1] the active part of a line
>>>> is supposed to be 51.95us, and the blanking period taking 12.05us. [2]
>>>> in the timing section has pretty much the same numbers, so it looks
>>>> sane.
>>>>
>>>> At 13.5Mhz, a pixel is going to take roughly 74ns, and 51950 / 74 = 702
>>>> pixels
>>>>
>>>> It seems we can go push it to 52350 ns, but that still gives us only 706
>>>> pixels.
>>>>
>>>> Similarly, if I just choose to ignore that limit and just take the
>>>> active time I need, 720 * 74 = 53280ns
>>>>
>>>> That leaves us 10720ns for the blanking period, and that's not enough to
>>>> fit even the minimum of the front porch, hsync and back porch (1.55 +
>>>> 4.5 + 5.5 = 11.55us).
>>>>
>>>> Are those constraints merely recommendations, or am I missing something?
>>>
>>> You are missing that the parts near the borders of the full image are
>>> part of the overscan range, and may or may not be visible, depending
>>> on your actual display.
>>> The full 768x576 image size from BT.656 is not visible on a typical PAL display,
>>> and is more of an "absolute maximum rating", guaranteed to cover more
>>> than analog PAL.
>>
>> So the overscan range is not part of the active area, unlike what HDMI
>> is doing for example?
>
> Indeed. DVI-D and HDMI etc. are pure digital (let's ignore they are a
> digitized variant of old analog VGA ;-), hence there is a one-to-one
> match between pixels in the image and pixels on the screen (ignoring
> scaling).  But even when using an analog VGA input on a modern
> digital display, you have controls to e.g. move the image.
>
>> Is there some minimal timings available somewhere to fit those absolute
>> maximum ratings?
>
> I guess they can be found on the Internet...

Here are some references that I personally found useful:

- ITU-R BT.601 <https://www.itu.int/rec/R-REC-BT.601/en>
  This is *the* standard that pretty much every modern device that deals with
  analog-style TV signal follows then converting to and from the digital domain.
  For example in the figures on page 10 (12 in the PDF numbering) you can see
  that the "time datum", i.e. start of horizontal sync pulse is canonically
  supposed to happen on sample 732 for 50 Hz or sample 736 for 59.94 Hz modes.

  BT.601 assumes 13.5 MHz sample rate / pixel clock, but you can proportionally
  scale those for other pixel clocks.

- ITU-R BT.1700 <https://www.itu.int/rec/R-REC-BT.1700/en>
  This is *the* standard in force for actual analog composite video signals.
  The vertical sync specs are discrete, so they don't really change between
  analog and digital domains. For horizontal sync, the values in those specs
  are given in microseconds/nanoseconds, but you can multiply those by the
  sampling rate for equivalent pixel counts.

- Pembers' Ponderings
  <https://web.archive.org/web/20160423225838/http://www.pembers.freeserve.co.uk/>
  An old archived website with a ton of resources about analog TV.
  The "Line Standards" article will probably be most interesting to you.

By the way, please note a couple of things:

- The analog standards are very imprecise for modern digital norms, giving
  considerable leeway for just about every timing. The allowed leeways are
  usually equivalent to a couple of pixels at the standard 13.5 MHz sampling
  rate - and those are meant for the transmitting end. Receivers are usually
  much more forgiving to maximize compatibility.

- The 720-pixel standard of BT.601 is considerably wider than the active width
  specified in the analog standards. AFAIK this is intentional, to ensure that
  no part of the actual image is missed during digitization, and to keep the
  number a nice multiply of 16. The picture width given in the analog standards
  is equivalent to somewhere between 702 and 714 pixels (at 13.5 MHz clock),
  depending on the specific standard. And that includes overscan.

- Same goes for the vertical active area. Original analog standards varied
  wildly from country to country, before finally settling on 575 lines for the
  50 Hz standard and 485 lines for the 59.94 Hz standard. Or 576/486, depending
  on how you count. The topmost line of those 576/486 starts at half the screen,
  and the bottommost line ends at half the screen - so they are often combined
  when counting and given as 575/485. The digital 576i50 standard includes
  those half-lines. In the 59.94 Hz regions, 480 active digial lines ended up
  the norm, because 486 does not have nice dividers, and also some of the
  outermost lines which were always overscanned anyway, ended up used for things
  like closed captioning over the years.

- Speaking of closed captioning... a lot of different stuff were put in the
  blanking interval over the years. Like teletext in Europe. There are projects
  like VBIT2 <https://github.com/peterkvt80/vbit2> which intentionally
  reconfigure the Raspberry Pi composite output to include the blanking interval
  in the framebuffer so that teletext can be output by drawing on the edge of
  the "screen" (from the computer point of view).

- A lot of equipment outside the broadcast industry willingly violated those
  standards, and there are real world use cases for that. Film studios used very
  slightly modified TVs to make them sync with 24fps cameras - in that variant,
  "NTSC" could have e.g. 655 lines so that the TV would refresh at 48 Hz with
  the same line frequency. Home computers and video game consoles output
  progressive 262/312-line modes instead of interlaced 525/625 lines. And often
  changed the line frequency slightly as well, for various reasons. Those
  progressive modes are still favored by retro gaming and emulation enthusiasts,
  because they incur a specific look on CRT displays. Even playing back video
  from a tape (especially home-grade, like VHS) could cause timings to go wildly
  out of spec, because of mechanical imprecisions.

- There were multitude of standards predating the ubiquitous 525/60 and 625/50
  modes. The British 405-line and French 819-line standards are the most
  notorious, having lasted well into the 1980s, but there were also a lot of
  wildly varying pre-WW2 television systems. And there are enthusiasts dedicated
  to preserving those.

My point is that the norms for analog TV are rather loose, and I think we
shouldn't limit the drivers to only accepting the "proper" modes as defined in
the spec. Those should of course be the default, but if non-standard modelines
can be generated - there are legitimate use cases why people might want those.

>
> Gr{oetje,eeting}s,
>
>                         Geert
>
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]
>
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like that.
>                                 -- Linus Torvalds

Best regards,
Mateusz Kwiatkowski

2022-08-24 17:48:31

by Mateusz Kwiatkowski

[permalink] [raw]
Subject: Re: [PATCH v1 24/35] drm/vc4: vec: Add support for more analog TV standards

Hi Maxime,

W dniu 15.08.2022 o 10:37, Maxime Ripard pisze:
> Hi,
>
> On Fri, Jul 29, 2022 at 07:55:30PM +0200, Mateusz Kwiatkowski wrote:
>> Hi Maxime,
>>
>> I think that declaring PAL-B and SECAM-B as the only supported 576i
>> norms is a bit random.
>
> Starting with this patch, PAL-N should be supported as well, right?

Oh, sure. I forgot about it. My brain was too focused on the "standard PAL"
modes, which excludes PAL-N.

>
>> Norms B, D, G, H, I, K, K1 and L (for both PAL and SECAM) are
>> essentially identical if we're talking about baseband signals, AFAIK
>> they only differ when those are modulated as RF signals. I'm not sure
>> if there's a point to differentiating those (that's more about patch
>> 05/35) unless we need to deal with some device that actually features
>> an RF modulator.
>
> What I was aiming for is to have all the cases we have in all the
> drivers covered so that we can make that property generic. i915
> declares and uses all those variants:
>
> https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/i915/display/intel_sdvo.c#L68
>
> Especially since it's i915 and it's pretty much the standard as far as
> the uAPI goes, I'd rather avoid any regression there.

OK, if there are already drivers that differentiate those, then it doesn't make
sense to introduce regressions. And yes, there is plenty of software already out
there that differentiate between those modes in the context of composite video.
It still doesn't make much sense from the engineering point of view, though.

>
>> But if we do want to have all those norms separate, then I'd say that
>> VC4 should declare support for all of those, and all should map to the
>> same VEC settings. Some users from e.g. the UK might think that they
>> won't get proper picture if PAL-I is not on the list of supported
>> norms. Same goes for e.g. SECAM-D/K in the former Soviet territories,
>> and so on.
>
> I'd be open to it, but we can always extend vc4 to support those modes
> later on. The work you did to make that easier should make it trivial.

Doing that in the future is OK as well. I just wanted to point out that
PAL-B/D/G/H/I/K/K1/L (and same for SECAM) is the same exact thing as far as
baseband composite video is concerned, so declaring only one of those as
supported is potentially misleading for anybody who is not aware of that fact.

>
> Maxime

Best regards,
Mateusz Kwiatkowski

2022-08-25 13:36:24

by Noralf Trønnes

[permalink] [raw]
Subject: Re: [PATCH v1 23/35] drm/vc4: vec: Convert to the new TV mode property



Den 24.08.2022 17.26, skrev Maxime Ripard:
> Hi,
>
> On Sat, Aug 20, 2022 at 07:22:48PM +0200, Noralf Trønnes wrote:
>> Den 29.07.2022 18.35, skrev Maxime Ripard:
>>> 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 <[email protected]>
>>>
>>> diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c
>>
>>> static int vc4_vec_connector_get_modes(struct drm_connector *connector)
>>> {
>>> - struct drm_connector_state *state = connector->state;
>>> struct drm_display_mode *mode;
>>>
>>> - mode = drm_mode_duplicate(connector->dev,
>>> - vc4_vec_tv_modes[state->tv.mode].mode);
>>> + mode = drm_mode_duplicate(connector->dev, &drm_mode_480i);
>>> + if (!mode) {
>>> + DRM_ERROR("Failed to create a new display mode\n");
>>> + return -ENOMEM;
>>> + }
>>> +
>>> + drm_mode_probed_add(connector, mode);
>>> +
>>> + mode = drm_mode_duplicate(connector->dev, &drm_mode_576i);
>>
>> Maybe the mode that matches tv.norm should be marked as preferred so
>> userspace knows which one to pick?
>
> I'm not sure how realistic that would be. Doing this based on the driver
> / cmdline preference is going to be fairly easy, but then it's a
> property, it's going to be updated, and we probably don't want to mess
> around the mode flags based on new property values?
>

Strictly speaking we need to fire an event to userspace if the mode
changes, and this is probably not straightforward to do underneath
modeset locks, would probably need a worker.

Clever userspace like GNOME will try to use the active mode, so it will
handle this that way. If someone has set up the pipeline first that is.
drm_client/fbdev and plymouth can do that because they honour userdef modes.

Other userspace that don't know the userdef flag will fallback to the
first mode which is NTSC which is also the default tvmode, so maybe this
is good enough. PAL users will have to specify the mode, or teach their
program about the userdef flag.

But ofc relying on the userdef flag depends on the fact that there's a
mode on the kernel command line, but maybe there's no way to avoid that
since much/most? userspace treat "unknown" connector status as
disconnected so many will have to force the connector to "connected"
anyway. At least I don't know any way to permanetly force the connector
status other than using video=.

Noralf.

2022-08-25 13:45:00

by Maxime Ripard

[permalink] [raw]
Subject: Re: [PATCH v1 05/35] drm/connector: Add TV standard property

Hi,

On Fri, Aug 19, 2022 at 11:35:42AM +0200, Geert Uytterhoeven wrote:
> On Thu, Aug 18, 2022 at 5:34 PM Maxime Ripard <[email protected]> wrote:
> > On Thu, Aug 18, 2022 at 05:20:42PM +0200, Geert Uytterhoeven wrote:
> > > On Thu, Aug 18, 2022 at 4:54 PM Maxime Ripard <[email protected]> wrote:
> > > > On Wed, Aug 17, 2022 at 04:04:24PM +0200, Geert Uytterhoeven wrote:
> > > > > On Wed, Aug 17, 2022 at 3:19 PM Maxime Ripard <[email protected]> wrote:
> > > > > > On Wed, Aug 17, 2022 at 03:05:52PM +0200, Geert Uytterhoeven wrote:
> > > > > > > On Wed, Aug 17, 2022 at 1:15 PM Maxime Ripard <[email protected]> wrote:
> > > > > > > > On Wed, Aug 17, 2022 at 10:35:07AM +0200, Geert Uytterhoeven wrote:
> > > > > > > > > On Wed, Aug 17, 2022 at 9:47 AM Maxime Ripard <[email protected]> wrote:
> > > > > > > > > > On Wed, Aug 17, 2022 at 09:31:18AM +0200, Geert Uytterhoeven wrote:
> > > > > > > > > > > On Tue, Aug 16, 2022 at 5:50 PM Maxime Ripard <[email protected]> wrote:
> > > > > > > > > > > > On Tue, Aug 16, 2022 at 04:43:44PM +0200, Geert Uytterhoeven wrote:
> > > > > > > > > > > > > > > > > Either you have to add them here (e.g. "hd720p50" and "hd720p60"), or
> > > > > > > > > > > > > > > > > handle them through "@<refresh>". The latter would impact "[PATCH v1
> > > > > > > > > > > > > > > > > 09/35] drm/modes: Move named modes parsing to a separate function", as
> > > > > > > > > > > > > > > > > currently a named mode and a refresh rate can't be specified both.
> > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > I think the former would make more sense. It simplifies a bit the
> > > > > > > > > > > > > > > > parser, and we're going to use a named mode anyway.
> > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > > As "[PATCH v1 34/35] drm/modes: Introduce the tv_mode property as a
> > > > > > > > > > > > > > > > > command-line option" uses a separate "tv_mode" option, and not the main
> > > > > > > > > > > > > > > > > mode name, I think you want to add them here.
> > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > It's a separate story I think, we could have a named mode hd720p50,
> > > > > > > > > > > > > > > > which would be equivalent to 1280x720,tv_mode=hd720p
> > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > So where's the field rate in "1280x720,tv_mode=hd720p"?
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > Yeah, sorry I meant 1280x720@50,tv_mode=hd720p
> > > > > > > > > > > > >
> > > > > > > > > > > > > Above you said "I think the former would make more sense", so that
> > > > > > > > > > > > > should be "1280x720,tv_mode=hd720p50"?
> > > > > > > > > > > >
> > > > > > > > > > > > No, 720p at 50Hz would be either hd720p50 or 1280x720@50,tv_mode=hd720p
> > > > > > > > > > > > and 60Hz would be hd720p60 or 1280x720@60,tv_mode=hd720p
> > > > > > > > > > >
> > > > > > > > > > > I disagree: hd720p50 and hd720p60 are different TV modes.
> > > > > > > > > >
> > > > > > > > > > I agree, and I don't see how that command-line doesn't express that?
> > > > > > > > >
> > > > > > > > > Oh, I see what you mean: yes, it expresses that.
> > > > > > > > > But it is inconsistent with the NTSC/PAL/SECAM/hd{480,576}[ip] modes,
> > > > > > > > > where the TV mode specifies both number of lines and frame rate.
> > > > > > > >
> > > > > > > > Only if we're using a named mode, and naming is hard :)
> > > > > > >
> > > > > > > That's not true: "640x480,tv_mode=PAL-N" would give me a mode with
> > > > > > > 625 lines and 25 frames/s, "640x480,tv_mode=PAL-M" would give me a
> > > > > > > mode with 525 lines and 30 frames/s.
> > > > > >
> > > > > > In that series, "640x480,tv_mode=PAL-N" would be rejected as invalid:
> > > > > >
> > > > > > https://lore.kernel.org/dri-devel/[email protected]/
> > > > >
> > > > > It would become supported once the ideas from thread "[PATCH v1 04/35]
> > > > > drm/modes: Introduce 480i and 576i modes" are implemented...
> > > >
> > > > Indeed, but I'm still not sure what your concern is here.
> > > > "640x480,tv_mode=PAL-N" and "640x480,tv_mode=PAL-M" are both fairly
> > > > obvious.
> > > >
> > > > You were initially saying that you had concern over the inconsistency of
> > > > NTSC/PAL/SECAM where the TV mode would specify a number of lines and
> > > > frame rate, but hd720p50 also specifies a number of line and frame rate?
> > >
> > > My concern is that you want to call the TV mode "hd720p", which
> > > does not dictate the frame rate.
> > > I would like to have both "720p50" and "720p60", as they do dictate
> > > the frame rate, like all the non-hd modes.
> >
> > But they don't?
> >
> > The refresh rate is part of the drm_display_mode, whereas that property
> > is metadata and entirely separate from the display mode.
> >
> > You can even change it without changing the mode at all
>
> Yes, the refresh rate is part of drm_display_mode. Vdisplay also
> is, but that doesn't mean you can set it to e.g. 700 when using
> "tv_mode=PAL-B". Some (combination of) parameters in drm_display_mode
> are dictated by the tv_mode.

But the opposite is also true: PAL-B and SECAM-B would be two different
TV mode, but (could) have the same display mode.

There's no equivalence or implication in that relationship, except for a
smaller set of those parameters. But it's the entire display mode that
we should compare.

> Perhaps the meaning of "tv_mode" should be clarified? What does it
> really mean, and what parameters does it (not) constrain?

As far as I'm concerned, it's only about the encoding. We can check
after the fact that, say, you don't try to use a mode line with than 525
lines and some NTSC variant, but the mode has precedence over the
property.

> For e.g. "PAL-B", I know it's a mode with 625 lines and 30 frames/s
> (60 fields/s).
> For "hd720p" I know it is an analog mode with 750 lines, but it's still
> ambiguous, as I don't know if it is the variant with 60 or 50 frames/s.

As far as the TV mode property is concerned, it doesn't encode neither
whether it has 750 lines, nor the refresh rate.

If you're talking about a named mode, then yeah, it's basically an alias
for a mode + a property, so it does, but we can choose names that aren't
ambiguous.

Maxime


Attachments:
(No filename) (6.25 kB)
signature.asc (235.00 B)
Download all attachments

2022-08-25 14:07:00

by Maxime Ripard

[permalink] [raw]
Subject: Re: [PATCH v1 05/35] drm/connector: Add TV standard property

Hi,

On Sat, Aug 20, 2022 at 10:12:46PM +0200, Noralf Tr?nnes wrote:
> > diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
> > index 1e9996b33cc8..78275e68ff66 100644
> > --- a/include/drm/drm_connector.h
> > +++ b/include/drm/drm_connector.h
> > @@ -143,6 +143,32 @@ enum subpixel_order {
> >
> > };
> >
> > +#define DRM_MODE_TV_NORM_NTSC_443 (1 << 0)
> > +#define DRM_MODE_TV_NORM_NTSC_J (1 << 1)
> > +#define DRM_MODE_TV_NORM_NTSC_M (1 << 2)
> > +#define DRM_MODE_TV_NORM_PAL_60 (1 << 3)
> > +#define DRM_MODE_TV_NORM_PAL_B (1 << 4)
> > +#define DRM_MODE_TV_NORM_PAL_D (1 << 5)
> > +#define DRM_MODE_TV_NORM_PAL_G (1 << 6)
> > +#define DRM_MODE_TV_NORM_PAL_H (1 << 7)
> > +#define DRM_MODE_TV_NORM_PAL_I (1 << 8)
> > +#define DRM_MODE_TV_NORM_PAL_M (1 << 9)
> > +#define DRM_MODE_TV_NORM_PAL_N (1 << 10)
> > +#define DRM_MODE_TV_NORM_PAL_NC (1 << 11)
> > +#define DRM_MODE_TV_NORM_SECAM_60 (1 << 12)
> > +#define DRM_MODE_TV_NORM_SECAM_B (1 << 13)
> > +#define DRM_MODE_TV_NORM_SECAM_D (1 << 14)
> > +#define DRM_MODE_TV_NORM_SECAM_G (1 << 15)
> > +#define DRM_MODE_TV_NORM_SECAM_K (1 << 16)
> > +#define DRM_MODE_TV_NORM_SECAM_K1 (1 << 17)
> > +#define DRM_MODE_TV_NORM_SECAM_L (1 << 18)
> > +#define DRM_MODE_TV_NORM_HD480I (1 << 19)
> > +#define DRM_MODE_TV_NORM_HD480P (1 << 20)
> > +#define DRM_MODE_TV_NORM_HD576I (1 << 21)
> > +#define DRM_MODE_TV_NORM_HD576P (1 << 22)
> > +#define DRM_MODE_TV_NORM_HD720P (1 << 23)
> > +#define DRM_MODE_TV_NORM_HD1080I (1 << 24)
> > +
>
> This is an area where DRM overlaps with v4l2, see:
> - include/dt-bindings/display/sdtv-standards.h
> - v4l2_norm_to_name()
>
> Maybe we should follow suit, but if we do our own thing please mention
> why in the commit message.

Are you suggesting that we'd share that definition with v4l2?

I've tried to share some code in the past between v4l2 and DRM, and it
got completely shut down so it's not something I'd like to try again, if
possible.

Maxime


Attachments:
(No filename) (1.99 kB)
signature.asc (235.00 B)
Download all attachments

2022-08-25 16:00:29

by Noralf Trønnes

[permalink] [raw]
Subject: Re: [PATCH v1 05/35] drm/connector: Add TV standard property



Den 25.08.2022 15.44, skrev Maxime Ripard:
> Hi,
>
> On Sat, Aug 20, 2022 at 10:12:46PM +0200, Noralf Trønnes wrote:
>>> diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
>>> index 1e9996b33cc8..78275e68ff66 100644
>>> --- a/include/drm/drm_connector.h
>>> +++ b/include/drm/drm_connector.h
>>> @@ -143,6 +143,32 @@ enum subpixel_order {
>>>
>>> };
>>>
>>> +#define DRM_MODE_TV_NORM_NTSC_443 (1 << 0)
>>> +#define DRM_MODE_TV_NORM_NTSC_J (1 << 1)
>>> +#define DRM_MODE_TV_NORM_NTSC_M (1 << 2)
>>> +#define DRM_MODE_TV_NORM_PAL_60 (1 << 3)
>>> +#define DRM_MODE_TV_NORM_PAL_B (1 << 4)
>>> +#define DRM_MODE_TV_NORM_PAL_D (1 << 5)
>>> +#define DRM_MODE_TV_NORM_PAL_G (1 << 6)
>>> +#define DRM_MODE_TV_NORM_PAL_H (1 << 7)
>>> +#define DRM_MODE_TV_NORM_PAL_I (1 << 8)
>>> +#define DRM_MODE_TV_NORM_PAL_M (1 << 9)
>>> +#define DRM_MODE_TV_NORM_PAL_N (1 << 10)
>>> +#define DRM_MODE_TV_NORM_PAL_NC (1 << 11)
>>> +#define DRM_MODE_TV_NORM_SECAM_60 (1 << 12)
>>> +#define DRM_MODE_TV_NORM_SECAM_B (1 << 13)
>>> +#define DRM_MODE_TV_NORM_SECAM_D (1 << 14)
>>> +#define DRM_MODE_TV_NORM_SECAM_G (1 << 15)
>>> +#define DRM_MODE_TV_NORM_SECAM_K (1 << 16)
>>> +#define DRM_MODE_TV_NORM_SECAM_K1 (1 << 17)
>>> +#define DRM_MODE_TV_NORM_SECAM_L (1 << 18)
>>> +#define DRM_MODE_TV_NORM_HD480I (1 << 19)
>>> +#define DRM_MODE_TV_NORM_HD480P (1 << 20)
>>> +#define DRM_MODE_TV_NORM_HD576I (1 << 21)
>>> +#define DRM_MODE_TV_NORM_HD576P (1 << 22)
>>> +#define DRM_MODE_TV_NORM_HD720P (1 << 23)
>>> +#define DRM_MODE_TV_NORM_HD1080I (1 << 24)
>>> +
>>
>> This is an area where DRM overlaps with v4l2, see:
>> - include/dt-bindings/display/sdtv-standards.h
>> - v4l2_norm_to_name()
>>
>> Maybe we should follow suit, but if we do our own thing please mention
>> why in the commit message.
>
> Are you suggesting that we'd share that definition with v4l2?
>

If possible, yes.

> I've tried to share some code in the past between v4l2 and DRM, and it
> got completely shut down so it's not something I'd like to try again, if
> possible.
>

But that is a good enough reason not to do so. I just got the impression
from some of Laurent's emails a while back that there was some
cooperativ atmosphere, but I might be mistaken in my reading/understanding.

It is ofc possible to just copy the values from sdtv-standards.h, but I
see that hd* is missing from that list, so not sure if there's much
point if it has to be extended without changing the source.

We can at least use the names from v4l2_norm_to_name(), but from a quick
look it seems you already do so.

Noralf.

2022-08-25 16:12:29

by Maxime Ripard

[permalink] [raw]
Subject: Re: [PATCH v1 00/35] drm: Analog TV Improvements

Hi Mateusz,

On Mon, Aug 22, 2022 at 10:57:26AM +0200, Mateusz Kwiatkowski wrote:
> Hi Maxime,
>
> I tried testing and reviewing your changes properly over the last weekend, but
> ultimately ran into this ("flip_done timed out" etc.) issue and was unable to
> mitigate it, at least so far. This seems to pop up every time I try to change
> modes in any way (either change the TV norm, or just try doing
> "xrandr --output Composite-1 --off" followed by bringing it back on; it also
> means that the Pi goes unusable when the DE's screen saving routine kicks in).
>
> I'm using a Pi 4, and it works with the rpi-5.13.y branch
> https://github.com/raspberrypi/linux, but seemingly nothing newer.
> I specifically tried rpi-5.14.y, rpi-5.15.y and rpi-5.19.y - rpi-5.15.y,
> which is the current main branch in Raspberry Pi OS, seems to be broken since
> forever; at least since my patches (originally written for 5.10) landed there.
>
> I'll try identifying the issue further, possibly later today, and maybe check
> the rpi-6.0.y branch as well.

I've tried it this, and I can't reproduce it here. But I'm curious, how
did you apply this series? rpi-5.13.y is probably full of conflicts
everywhere?

Maxime


Attachments:
(No filename) (1.21 kB)
signature.asc (235.00 B)
Download all attachments

2022-08-25 16:41:42

by Mateusz Kwiatkowski

[permalink] [raw]
Subject: Re: [PATCH v1 00/35] drm: Analog TV Improvements

Hi Maxime,

W dniu 25.08.2022 o 17:55, Maxime Ripard pisze:
> Hi Mateusz,
>
> On Mon, Aug 22, 2022 at 10:57:26AM +0200, Mateusz Kwiatkowski wrote:
>> Hi Maxime,
>>
>> I tried testing and reviewing your changes properly over the last weekend, but
>> ultimately ran into this ("flip_done timed out" etc.) issue and was unable to
>> mitigate it, at least so far. This seems to pop up every time I try to change
>> modes in any way (either change the TV norm, or just try doing
>> "xrandr --output Composite-1 --off" followed by bringing it back on; it also
>> means that the Pi goes unusable when the DE's screen saving routine kicks in).
>>
>> I'm using a Pi 4, and it works with the rpi-5.13.y branch
>> https://github.com/raspberrypi/linux, but seemingly nothing newer.
>> I specifically tried rpi-5.14.y, rpi-5.15.y and rpi-5.19.y - rpi-5.15.y,
>> which is the current main branch in Raspberry Pi OS, seems to be broken since
>> forever; at least since my patches (originally written for 5.10) landed there.
>>
>> I'll try identifying the issue further, possibly later today, and maybe check
>> the rpi-6.0.y branch as well.
>
> I've tried it this, and I can't reproduce it here. But I'm curious, how
> did you apply this series? rpi-5.13.y is probably full of conflicts
> everywhere?

I applied your patches onto rpi-5.15.y. There were conflicts, but they seemed
relatively minor. I'm not sure if I did a good job at resolving them - I ran
into various problems trying to test your changes, but I chose not to criticize
you before making sure that it's really due to your changes, or without some
remarks more constructive than "doesn't work" ;-)

I can push my rebase onto some Github fork if you're interested.

I was able to work around some of those problems, and also saw that some
of them were already mentioned by other reviewers (such as the generic modes
not matching due to the aspect ratio setting).

Ultimately I got stuck on this bug, so I put testing this series on hold
in favor of debugging the bigger issue. So far unfortunately no luck with it.

I did not try rebasing your changes onto 5.13 or older.

> Maxime

Best regards,
Mateusz Kwiatkowski

2022-08-25 16:42:11

by Maxime Ripard

[permalink] [raw]
Subject: Re: [PATCH v1 00/35] drm: Analog TV Improvements

On Mon, Aug 22, 2022 at 03:21:29PM +0200, Noralf Tr?nnes wrote:
>
>
> Den 22.08.2022 09.48, skrev Maxime Ripard:
> > Hi,
> >
> > On Sun, Aug 21, 2022 at 06:33:12PM +0200, Noralf Tr?nnes wrote:
> >> Den 29.07.2022 18.34, skrev Maxime Ripard:
> >>> Hi,
> >>>
> >>> Here's a series aiming at improving the command line named modes support,
> >>> and more importantly how we deal with all the analog TV variants.
> >>>
> >>> The named modes support were initially introduced to allow to specify the
> >>> analog TV mode to be used.
> >>>
> >>> However, this was causing multiple issues:
> >>>
> >>> * The mode name parsed on the command line was passed directly to the
> >>> driver, which had to figure out which mode it was suppose to match;
> >>>
> >>> * Figuring that out wasn't really easy, since the video= argument or what
> >>> the userspace might not even have a name in the first place, but
> >>> instead could have passed a mode with the same timings;
> >>>
> >>> * The fallback to matching on the timings was mostly working as long as
> >>> we were supporting one 525 lines (most likely NSTC) and one 625 lines
> >>> (PAL), but couldn't differentiate between two modes with the same
> >>> timings (NTSC vs PAL-M vs NSTC-J for example);
> >>>
> >>> * There was also some overlap with the tv mode property registered by
> >>> drm_mode_create_tv_properties(), but named modes weren't interacting
> >>> with that property at all.
> >>>
> >>> * Even though that property was generic, its possible values were
> >>> specific to each drivers, which made some generic support difficult.
> >>>
> >>> Thus, I chose to tackle in multiple steps:
> >>>
> >>> * A new TV norm property was introduced, with generic values, each driver
> >>> reporting through a bitmask what standard it supports to the userspace;
> >>>
> >>> * This option was added to the command line parsing code to be able to
> >>> specify it on the kernel command line, and new atomic_check and reset
> >>> helpers were created to integrate properly into atomic KMS;
> >>>
> >>> * The named mode parsing code is now creating a proper display mode for
> >>> the given named mode, and the TV standard will thus be part of the
> >>> connector state;
> >>>
> >>> * Two drivers were converted and tested for now (vc4 and sun4i), with
> >>> some backward compatibility code to translate the old TV mode to the
> >>> new TV mode;
> >>>
> >>> Unit tests were created along the way. Nouveau, ch7006 and gud are
> >>> currently broken for now since I expect that work to be reworked fairly
> >>> significantly. I'm also not entirely sure about how to migrate GUD to the
> >>> new property.
> >>>
> >>> Let me know what you think,
> >>> Maxime
> >>>
> >>
> >> I don't know if it's related to this patchset or not, but I do get this:
> >>
> >> pi@pi4t:~ $ sudo dmesg -C && sudo modprobe -r vc4 && sudo modprobe vc4
> >> && dmesg
> >> [ 430.066211] Console: switching to colour dummy device 80x30
> >> [ 431.294788] vc4-drm gpu: bound fe400000.hvs (ops vc4_hvs_ops [vc4])
> >> [ 431.295115] vc4-drm gpu: bound fec13000.vec (ops vc4_vec_ops [vc4])
> >> [ 431.295467] vc4-drm gpu: bound fe004000.txp (ops vc4_txp_ops [vc4])
> >> [ 431.295804] vc4-drm gpu: bound fec12000.pixelvalve (ops vc4_crtc_ops
> >> [vc4])
> >> [ 431.298895] [drm] Initialized vc4 0.0.0 20140616 for gpu on minor 0
> >> [ 441.444250] vc4-drm gpu: [drm] *ERROR* [CRTC:68:crtc-1] flip_done
> >> timed out
> >> [ 441.446529] Console: switching to colour frame buffer device 90x30
> >> [ 451.684321] vc4-drm gpu: [drm] *ERROR* flip_done timed out
> >> [ 451.684347] vc4-drm gpu: [drm] *ERROR* [CRTC:68:crtc-1] commit wait
> >> timed out
> >> [ 461.924255] vc4-drm gpu: [drm] *ERROR* flip_done timed out
> >> [ 461.924281] vc4-drm gpu: [drm] *ERROR* [CONNECTOR:45:Composite-1]
> >> commit wait timed out
> >> [ 472.164006] vc4-drm gpu: [drm] *ERROR* flip_done timed out
> >> [ 472.164031] vc4-drm gpu: [drm] *ERROR* [PLANE:61:plane-1] commit wait
> >> timed out
> >> [ 482.403877] vc4-drm gpu: [drm] *ERROR* flip_done timed out
> >> [ 482.403903] vc4-drm gpu: [drm] *ERROR* Timed out waiting for commit
> >> [ 492.643799] vc4-drm gpu: [drm] *ERROR* [CRTC:68:crtc-1] flip_done
> >> timed out
> >> [ 492.647073] vc4-drm gpu: [drm] fb0: vc4drmfb frame buffer device
> >
> > Module unloading/reloading has been janky for a while.
> >
> > I've fixed it up recently but it doesn't surprise me that there's still
> > some situation that won't work. Is it on a Pi3?
> >
>
> It's a Pi4.

With which kernel? I just tested it on last next and it seems to work ok
there. I've fixed it recently though, so it's only in drm-misc-next and
linux-next at the moment.

Maxime


Attachments:
(No filename) (4.77 kB)
signature.asc (235.00 B)
Download all attachments

2022-08-25 19:58:50

by Noralf Trønnes

[permalink] [raw]
Subject: Re: [PATCH v1 00/35] drm: Analog TV Improvements



Den 25.08.2022 18.21, skrev Maxime Ripard:
> On Mon, Aug 22, 2022 at 03:21:29PM +0200, Noralf Trønnes wrote:
>>
>>
>> Den 22.08.2022 09.48, skrev Maxime Ripard:
>>> Hi,
>>>
>>> On Sun, Aug 21, 2022 at 06:33:12PM +0200, Noralf Trønnes wrote:
>>>> Den 29.07.2022 18.34, skrev Maxime Ripard:
>>>>> Hi,
>>>>>
>>>>> Here's a series aiming at improving the command line named modes support,
>>>>> and more importantly how we deal with all the analog TV variants.
>>>>>
>>>>> The named modes support were initially introduced to allow to specify the
>>>>> analog TV mode to be used.
>>>>>
>>>>> However, this was causing multiple issues:
>>>>>
>>>>> * The mode name parsed on the command line was passed directly to the
>>>>> driver, which had to figure out which mode it was suppose to match;
>>>>>
>>>>> * Figuring that out wasn't really easy, since the video= argument or what
>>>>> the userspace might not even have a name in the first place, but
>>>>> instead could have passed a mode with the same timings;
>>>>>
>>>>> * The fallback to matching on the timings was mostly working as long as
>>>>> we were supporting one 525 lines (most likely NSTC) and one 625 lines
>>>>> (PAL), but couldn't differentiate between two modes with the same
>>>>> timings (NTSC vs PAL-M vs NSTC-J for example);
>>>>>
>>>>> * There was also some overlap with the tv mode property registered by
>>>>> drm_mode_create_tv_properties(), but named modes weren't interacting
>>>>> with that property at all.
>>>>>
>>>>> * Even though that property was generic, its possible values were
>>>>> specific to each drivers, which made some generic support difficult.
>>>>>
>>>>> Thus, I chose to tackle in multiple steps:
>>>>>
>>>>> * A new TV norm property was introduced, with generic values, each driver
>>>>> reporting through a bitmask what standard it supports to the userspace;
>>>>>
>>>>> * This option was added to the command line parsing code to be able to
>>>>> specify it on the kernel command line, and new atomic_check and reset
>>>>> helpers were created to integrate properly into atomic KMS;
>>>>>
>>>>> * The named mode parsing code is now creating a proper display mode for
>>>>> the given named mode, and the TV standard will thus be part of the
>>>>> connector state;
>>>>>
>>>>> * Two drivers were converted and tested for now (vc4 and sun4i), with
>>>>> some backward compatibility code to translate the old TV mode to the
>>>>> new TV mode;
>>>>>
>>>>> Unit tests were created along the way. Nouveau, ch7006 and gud are
>>>>> currently broken for now since I expect that work to be reworked fairly
>>>>> significantly. I'm also not entirely sure about how to migrate GUD to the
>>>>> new property.
>>>>>
>>>>> Let me know what you think,
>>>>> Maxime
>>>>>
>>>>
>>>> I don't know if it's related to this patchset or not, but I do get this:
>>>>
>>>> pi@pi4t:~ $ sudo dmesg -C && sudo modprobe -r vc4 && sudo modprobe vc4
>>>> && dmesg
>>>> [ 430.066211] Console: switching to colour dummy device 80x30
>>>> [ 431.294788] vc4-drm gpu: bound fe400000.hvs (ops vc4_hvs_ops [vc4])
>>>> [ 431.295115] vc4-drm gpu: bound fec13000.vec (ops vc4_vec_ops [vc4])
>>>> [ 431.295467] vc4-drm gpu: bound fe004000.txp (ops vc4_txp_ops [vc4])
>>>> [ 431.295804] vc4-drm gpu: bound fec12000.pixelvalve (ops vc4_crtc_ops
>>>> [vc4])
>>>> [ 431.298895] [drm] Initialized vc4 0.0.0 20140616 for gpu on minor 0
>>>> [ 441.444250] vc4-drm gpu: [drm] *ERROR* [CRTC:68:crtc-1] flip_done
>>>> timed out
>>>> [ 441.446529] Console: switching to colour frame buffer device 90x30
>>>> [ 451.684321] vc4-drm gpu: [drm] *ERROR* flip_done timed out
>>>> [ 451.684347] vc4-drm gpu: [drm] *ERROR* [CRTC:68:crtc-1] commit wait
>>>> timed out
>>>> [ 461.924255] vc4-drm gpu: [drm] *ERROR* flip_done timed out
>>>> [ 461.924281] vc4-drm gpu: [drm] *ERROR* [CONNECTOR:45:Composite-1]
>>>> commit wait timed out
>>>> [ 472.164006] vc4-drm gpu: [drm] *ERROR* flip_done timed out
>>>> [ 472.164031] vc4-drm gpu: [drm] *ERROR* [PLANE:61:plane-1] commit wait
>>>> timed out
>>>> [ 482.403877] vc4-drm gpu: [drm] *ERROR* flip_done timed out
>>>> [ 482.403903] vc4-drm gpu: [drm] *ERROR* Timed out waiting for commit
>>>> [ 492.643799] vc4-drm gpu: [drm] *ERROR* [CRTC:68:crtc-1] flip_done
>>>> timed out
>>>> [ 492.647073] vc4-drm gpu: [drm] fb0: vc4drmfb frame buffer device
>>>
>>> Module unloading/reloading has been janky for a while.
>>>
>>> I've fixed it up recently but it doesn't surprise me that there's still
>>> some situation that won't work. Is it on a Pi3?
>>>
>>
>> It's a Pi4.
>
> With which kernel? I just tested it on last next and it seems to work ok
> there. I've fixed it recently though, so it's only in drm-misc-next and
> linux-next at the moment.
>

I'm on a week old drm-misc-next.

What's your setup so I can try that.

This is mine:
https://gist.github.com/notro/41c59d77c3022dc6d931d4f9547c4ea6

I can't see anything that should differ significantly from what you
could have done. Only maybe that I use the latest firmware and perhaps
you've got a 64-bit kernel.

Noralf.

2022-08-26 04:47:34

by Mateusz Kwiatkowski

[permalink] [raw]
Subject: Re: [PATCH v1 00/35] drm: Analog TV Improvements

Hi Maxime, Noralf and everyone,

Just as a quick update. I isolated the issue to the power management subsystem.
Unfortunately I know very little about the power management subsystem so
I don't think I can help.

There are two alternative dirty ad-hoc hacks that get things working.

- Commenting out the pm_runtime_put() / pm_runtime_get_sync() calls in vc4_vec.c
- Reverting this PR by Dom Cobley a.k.a. popcornmix:
  https://github.com/raspberrypi/linux/pull/4639

Either of these approaches makes VEC mode switching work again. Obviously
neither is appropriate for a permanent solution.

I tried some random code permutations that came to my mind, like using the
vc4_encoder callbacks (e.g. post_crtc_powerdown) instead of the standard
enable/disable encoder callbacks, but to no avail.

Since the clocks and power management seem to be delegated to the firmware now,
my guess is that this might be a firmware issue, but I can't really check all
the firmware versions. It certainly crashes on the version currently available
in Raspberry Pi OS repos, and on this one:
https://github.com/raspberrypi/rpi-firmware/commit/4dde751. My Pi4 doesn't boot
using any newer firmware, at least not from USB - I might try some SD card
after the weekend.

Best regards,
Mateusz Kwiatkowski

W dniu 25.08.2022 o 18:17, Mateusz Kwiatkowski pisze:
> Hi Maxime,
>
> W dniu 25.08.2022 o 17:55, Maxime Ripard pisze:
>> Hi Mateusz,
>>
>> On Mon, Aug 22, 2022 at 10:57:26AM +0200, Mateusz Kwiatkowski wrote:
>>> Hi Maxime,
>>>
>>> I tried testing and reviewing your changes properly over the last weekend, but
>>> ultimately ran into this ("flip_done timed out" etc.) issue and was unable to
>>> mitigate it, at least so far. This seems to pop up every time I try to change
>>> modes in any way (either change the TV norm, or just try doing
>>> "xrandr --output Composite-1 --off" followed by bringing it back on; it also
>>> means that the Pi goes unusable when the DE's screen saving routine kicks in).
>>>
>>> I'm using a Pi 4, and it works with the rpi-5.13.y branch
>>> https://github.com/raspberrypi/linux, but seemingly nothing newer.
>>> I specifically tried rpi-5.14.y, rpi-5.15.y and rpi-5.19.y - rpi-5.15.y,
>>> which is the current main branch in Raspberry Pi OS, seems to be broken since
>>> forever; at least since my patches (originally written for 5.10) landed there.
>>>
>>> I'll try identifying the issue further, possibly later today, and maybe check
>>> the rpi-6.0.y branch as well.
>> I've tried it this, and I can't reproduce it here. But I'm curious, how
>> did you apply this series? rpi-5.13.y is probably full of conflicts
>> everywhere?
> I applied your patches onto rpi-5.15.y. There were conflicts, but they seemed
> relatively minor. I'm not sure if I did a good job at resolving them - I ran
> into various problems trying to test your changes, but I chose not to criticize
> you before making sure that it's really due to your changes, or without some
> remarks more constructive than "doesn't work" ;-)
>
> I can push my rebase onto some Github fork if you're interested.
>
> I was able to work around some of those problems, and also saw that some
> of them were already mentioned by other reviewers (such as the generic modes
> not matching due to the aspect ratio setting).
>
> Ultimately I got stuck on this bug, so I put testing this series on hold
> in favor of debugging the bigger issue. So far unfortunately no luck with it.
>
> I did not try rebasing your changes onto 5.13 or older.
>
>> Maxime
> Best regards,
> Mateusz Kwiatkowski


2022-08-26 08:30:03

by Maxime Ripard

[permalink] [raw]
Subject: Re: [PATCH v1 05/35] drm/connector: Add TV standard property

On Sun, Aug 21, 2022 at 01:43:40PM +0200, Noralf Tr?nnes wrote:
>
>
> Den 18.08.2022 17.31, skrev Maxime Ripard:
> > On Thu, Aug 18, 2022 at 05:01:38PM +0200, Noralf Tr?nnes wrote:
> >>
> >>
> >> Den 18.08.2022 01.23, skrev Noralf Tr?nnes:
> >>>
> >>>
> >>> Den 17.08.2022 15.11, skrev Noralf Tr?nnes:
> >>>>
> >>>>
> >>>> Den 17.08.2022 13.46, skrev Maxime Ripard:
> >>>>> On Tue, Aug 16, 2022 at 09:35:24PM +0200, Noralf Tr?nnes wrote:
> >>>>>> Den 16.08.2022 11.49, skrev Maxime Ripard:
> >>>>>>> On Tue, Aug 16, 2022 at 11:42:20AM +0200, Noralf Tr?nnes wrote:
> >>>>>>>> Den 16.08.2022 10.26, skrev Maxime Ripard:
> >>>>>>>>> Hi,
> >>>>>>>>>
> >>>>>>>>> On Mon, Aug 08, 2022 at 02:44:56PM +0200, Noralf Tr?nnes wrote:
> >>>>>>>>>> Den 29.07.2022 18.34, skrev Maxime Ripard:
> >>>>>>>>>>> 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 <[email protected]>
> >>>>>>>>>>>
> >>>
> >>>>>> How do you test the property? I've used modetest but I can only change
> >>>>>> to a tv.mode that matches the current display mode. I can't switch from
> >>>>>> ntsc to pal for instance.
> >>>>>
> >>>>> Yep, if you want to change from PAL to NTSC, it will require a new mode.
> >>>>>
> >>>>
> >>>> So userspace has to check tv.mode first and then create a display mode
> >>>> the driver will accept if switching to a different display mode is
> >>>> necessary? In other words, userspace can't discover from the kernel
> >>>> which display modes a certain tv.mode/norm provides before it is
> >>>> selected? If so, maybe libdrm should have some function(s) to deal with
> >>>> switching between modes that require a different display mode since
> >>>> knowledge about which display modes a tv.mode supports is needed before
> >>>> hand.
> >>>>
> >>>
> >>> I haven't used vc4 on Pi4 in mainline before and have finally gotten it
> >>> to work.
> >>>
> >>> I see that the connector reports 2 modes that together fit all tv.norms
> >>> so userspace doesn't have to contruct a display mode, but it does need
> >>> to know which display mode belongs to a certain tv.norm.
> >>>
> >>> When I try to use modetest I'm unable to set a mode:
> >>>
> >>> pi@pi4t:~ $ modetest -M vc4 -s 45:720x480i
> >>> setting mode 720x480i-29.97Hz on connectors 45, crtc 68
> >>> failed to set mode: Function not implemented
> >>>
> >>> The errno is misleading, modetest does a drmModeDirtyFB before checking
> >>> the error returned by drmModeSetCrtc.
> >>>
> >>> Setting the property succeeds, but the modeset still fails:
> >>>
> >>> pi@pi4t:~ $ modetest -M vc4 -s 45:720x480i -w 45:"tv norm":2
> >>> setting mode 720x480i-29.97Hz on connectors 45, crtc 68
> >>> failed to set mode: Function not implemented
> >>>
> >>> pi@pi4t:~ $ modetest -M vc4 -c
> >>> 37 tv norm:
> >>> flags: bitmask
> >>> values: NTSC-443=0x1 NTSC-J=0x2 NTSC-M=0x4 PAL-B=0x10
> >>> PAL-M=0x200 PAL-N=0x400 SECAM-B=0x2000
> >>> value: 2
> >>>
> >>> Here's the log, can you see if there's anything obvious in there:
> >>> https://gist.github.com/notro/a079498bf6b64327105752b2bafa8858
> >>>
> >>
> >> I'm one step closer as I now have fbcon working, I had forgotten to add
> >> enable_tvout=1 and I had disable_fw_kms_setup=1 which disables the
> >> video= mode on the kernel commandline.
> >>
> >> modetest still fails though, after alot of printk sprinkling, I've
> >> tracked it down to the drm_mode_equal test in
> >> drm_atomic_helper_connector_tv_check(). The aspect ratios differ:
> >>
> >> [ 61.336295] drm_atomic_helper_connector_tv_check:
> >> mode->picture_aspect_ratio=1
> >> [ 61.336301] drm_atomic_helper_connector_tv_check:
> >> &crtc_state->mode->picture_aspect_ratio=0
> >
> > I haven't seen this when testing, but I'll have a look, thanks!
>
> I have found the cause, the kernel strips off the aspect ratio in
> drm_mode_getconnector() if drm_file->aspect_ratio_allowed is false. So I
> think the drm_mode_equal() test needs to be relaxed for
> legacy/non-atomic userspace to work.

Geert suggested I removed it too, so this check is gone now.

> If I use modetest with atomic commit (-a) it works as is, having the
> drm_mode_equal() test:
>
> $ modetest -M vc4 -a -P 61@68:720x480 -s 45:720x480i
>
> I have a problem because the board hangs, either right away or after I
> press <enter> to quit modetest.
>
> I often get this, sometimes after 10s of seconds:
>
> [ 136.822963] Unhandled fault: asynchronous external abort (0x1211) at
> 0x00000000
> ...
> [ 137.248496] bcm2711_get_temp [bcm2711_thermal] from
> thermal_zone_get_temp+0x54/0x74
>
> Unloading bcm2711_thermal didn't help, in that case I got nothing, so
> the problem lies elsewhere.
> I have even tried with a fresh SD image and a fresh kernel, but it
> didn't help.

I got this too when working from current next (next-20220825) but it
doesn't seem to happen on drm-misc-next-2022-08-20-1, so it's probably
something unrelated?

> I can switch from NTSC to PAL like this (but it still crashes):
>
> $ modetest -M vc4 -a -w 45:"tv norm":16 -P 61@68:720x576 -s 45:720x576i

I've tested with my current branch, and it work fine with modetest, I'll
put my commands in my next iteration so that you can compare?

Maxime


Attachments:
(No filename) (5.94 kB)
signature.asc (235.00 B)
Download all attachments

2022-08-26 09:40:13

by Maxime Ripard

[permalink] [raw]
Subject: Re: [PATCH v1 00/35] drm: Analog TV Improvements

On Fri, Aug 26, 2022 at 06:07:47AM +0200, Mateusz Kwiatkowski wrote:
> Hi Maxime, Noralf and everyone,
>
> Just as a quick update. I isolated the issue to the power management subsystem.
> Unfortunately I know very little about the power management subsystem so
> I don't think I can help.
>
> There are two alternative dirty ad-hoc hacks that get things working.
>
> - Commenting out the pm_runtime_put() / pm_runtime_get_sync() calls in vc4_vec.c
> - Reverting this PR by Dom Cobley a.k.a. popcornmix:
> ? https://github.com/raspberrypi/linux/pull/4639

We don't have that PR upstream, so that might be the explanation to why
you're seeing this and I don't. I'll look into this further and will
open an issue.

I can't see anything wrong with the pm_runtime use though.

> Either of these approaches makes VEC mode switching work again. Obviously
> neither is appropriate for a permanent solution.
>
> I tried some random code permutations that came to my mind, like using the
> vc4_encoder callbacks (e.g. post_crtc_powerdown) instead of the standard
> enable/disable encoder callbacks, but to no avail.
>
> Since the clocks and power management seem to be delegated to the firmware now,
> my guess is that this might be a firmware issue, but I can't really check all
> the firmware versions. It certainly crashes on the version currently available
> in Raspberry Pi OS repos, and on this one:
> https://github.com/raspberrypi/rpi-firmware/commit/4dde751. My Pi4 doesn't boot
> using any newer firmware, at least not from USB - I might try some SD card
> after the weekend.

Thanks for your testing

Maxime


Attachments:
(No filename) (1.61 kB)
signature.asc (235.00 B)
Download all attachments

2022-08-26 15:09:47

by Dom Cobley

[permalink] [raw]
Subject: Re: [PATCH v1 00/35] drm: Analog TV Improvements

On Fri, 26 Aug 2022 at 05:08, Mateusz Kwiatkowski <[email protected]> wrote:
> - Commenting out the pm_runtime_put() / pm_runtime_get_sync() calls in vc4_vec.c
> - Reverting this PR by Dom Cobley a.k.a. popcornmix:
> https://github.com/raspberrypi/linux/pull/4639
>
> Either of these approaches makes VEC mode switching work again. Obviously
> neither is appropriate for a permanent solution.

Might be worth trying the latest rpi-update firmware.
There was a change that affects restoring PIXEL/VEC clocks after a
power domain cycle.
There is also a fix for a USB boot breakage.

If you still have an issue that occurs in downstream pi tree but not
upstream, then create a linux github issue.

2022-08-27 16:41:29

by Noralf Trønnes

[permalink] [raw]
Subject: Re: [PATCH v1 00/35] drm: Analog TV Improvements



Den 26.08.2022 16.56, skrev Dom Cobley:
> On Fri, 26 Aug 2022 at 05:08, Mateusz Kwiatkowski <[email protected]> wrote:
>> - Commenting out the pm_runtime_put() / pm_runtime_get_sync() calls in vc4_vec.c
>> - Reverting this PR by Dom Cobley a.k.a. popcornmix:
>> https://github.com/raspberrypi/linux/pull/4639
>>
>> Either of these approaches makes VEC mode switching work again. Obviously
>> neither is appropriate for a permanent solution.
>
> Might be worth trying the latest rpi-update firmware.
> There was a change that affects restoring PIXEL/VEC clocks after a
> power domain cycle.
> There is also a fix for a USB boot breakage.
>

That firmware gives me firmware timeout references in the 5 attempts
I've done.

My first attempt gave me this:

[ 112.454982] WARNING: CPU: 2 PID: 855 at
drivers/firmware/raspberrypi.c:63 rpi_firmware_property_list+0x204/0x270
[ 112.466985] Firmware transaction timeout
...
[ 112.533740] warn_slowpath_fmt from
rpi_firmware_property_list+0x204/0x270
[ 112.541449] rpi_firmware_property_list from
rpi_firmware_property+0x68/0x94
[ 112.549326] rpi_firmware_property from
raspberrypi_clock_property+0x50/0x84
[ 112.557197] raspberrypi_clock_property from
raspberrypi_fw_set_rate+0x4c/0xc4
[ 112.565242] raspberrypi_fw_set_rate from clk_change_rate+0x16c/0x6f8
[ 112.572502] clk_change_rate from clk_core_set_rate_nolock+0x1c4/0x2a4
[ 112.579857] clk_core_set_rate_nolock from
clk_set_rate_range.part.0+0x128/0x2ac
[ 112.588091] clk_set_rate_range.part.0 from
vc4_atomic_commit_tail+0x2b4/0x854 [vc4]
[ 112.596832] vc4_atomic_commit_tail [vc4] from commit_tail+0xa4/0x19c
[ 112.604269] commit_tail from drm_atomic_helper_commit+0x16c/0x194
[ 112.611279] drm_atomic_helper_commit from drm_atomic_commit+0xb4/0xec
[ 112.618625] drm_atomic_commit from drm_mode_atomic_ioctl+0x8f0/0xb6c
[ 112.625877] drm_mode_atomic_ioctl from drm_ioctl_kernel+0xcc/0x170
[ 112.632950] drm_ioctl_kernel from drm_ioctl+0x1d8/0x374
[ 112.639056] drm_ioctl from sys_ioctl+0xe4/0xbac
[ 112.644462] sys_ioctl from ret_fast_syscall+0x0/0x1c
...
[ 112.726171] raspberrypi-clk soc:firmware:clocks: Failed to change
fw-clk-core frequency: -110

I've also done one with drm debug enabled.
Kernel messages:
https://gist.github.com/notro/53afe9fdc3d0afbf0fb12678be1ab377

Dom, in case you want to debug this I've uploaded a rpi-update'able
archive plus config.txt and cmdline.txt.
There are some custom overlays in there that are needed.

Kernel: tronnes.org/downloads/vec-kernel-2022-08-27.gz
Build/setup info from another post:
https://gist.github.com/notro/41c59d77c3022dc6d931d4f9547c4ea6

I've tried this on another Pi4 (same revision: c03111) as well to rule
out any hw issues. The first attempt also gave me an mmc fault (no dmesg
-w) and the second one (dmesg -w) gave me the timeout.

Noralf.

2022-08-28 17:35:30

by Noralf Trønnes

[permalink] [raw]
Subject: Re: [PATCH v1 32/35] drm/sun4i: tv: Convert to the new TV mode property



Den 29.07.2022 18.35, skrev Maxime Ripard:
> Now that the core can deal fine with analog TV modes, let's convert the
> sun4i TV driver to leverage those new features.
>
> Signed-off-by: Maxime Ripard <[email protected]>
>
> diff --git a/drivers/gpu/drm/sun4i/sun4i_tv.c b/drivers/gpu/drm/sun4i/sun4i_tv.c
> index 74ff5ad6a8b9..bed52423776e 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_tv.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_tv.c

> @@ -586,8 +524,17 @@ static int sun4i_tv_bind(struct device *dev, struct device *master,
>
> drm_connector_attach_encoder(&tv->connector, &tv->encoder);
>
> + ret = drm_mode_create_tv_properties(drm,
> + DRM_MODE_TV_NORM_NTSC_M |
> + DRM_MODE_TV_NORM_PAL_B,
> + 0, NULL);
> + if (ret)
> + goto err_cleanup_connector;
> +

Looks like you have forgotten to attach the property?

Noralf.

> return 0;
>
> +err_cleanup_connector:
> + drm_connector_cleanup(&tv->connector);
> err_cleanup_encoder:
> drm_encoder_cleanup(&tv->encoder);
> err_disable_clk:
>

2022-08-29 08:34:19

by Maxime Ripard

[permalink] [raw]
Subject: Re: [PATCH v1 05/35] drm/connector: Add TV standard property

On Thu, Aug 25, 2022 at 05:13:29PM +0200, Noralf Tr?nnes wrote:
>
>
> Den 25.08.2022 15.44, skrev Maxime Ripard:
> > Hi,
> >
> > On Sat, Aug 20, 2022 at 10:12:46PM +0200, Noralf Tr?nnes wrote:
> >>> diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
> >>> index 1e9996b33cc8..78275e68ff66 100644
> >>> --- a/include/drm/drm_connector.h
> >>> +++ b/include/drm/drm_connector.h
> >>> @@ -143,6 +143,32 @@ enum subpixel_order {
> >>>
> >>> };
> >>>
> >>> +#define DRM_MODE_TV_NORM_NTSC_443 (1 << 0)
> >>> +#define DRM_MODE_TV_NORM_NTSC_J (1 << 1)
> >>> +#define DRM_MODE_TV_NORM_NTSC_M (1 << 2)
> >>> +#define DRM_MODE_TV_NORM_PAL_60 (1 << 3)
> >>> +#define DRM_MODE_TV_NORM_PAL_B (1 << 4)
> >>> +#define DRM_MODE_TV_NORM_PAL_D (1 << 5)
> >>> +#define DRM_MODE_TV_NORM_PAL_G (1 << 6)
> >>> +#define DRM_MODE_TV_NORM_PAL_H (1 << 7)
> >>> +#define DRM_MODE_TV_NORM_PAL_I (1 << 8)
> >>> +#define DRM_MODE_TV_NORM_PAL_M (1 << 9)
> >>> +#define DRM_MODE_TV_NORM_PAL_N (1 << 10)
> >>> +#define DRM_MODE_TV_NORM_PAL_NC (1 << 11)
> >>> +#define DRM_MODE_TV_NORM_SECAM_60 (1 << 12)
> >>> +#define DRM_MODE_TV_NORM_SECAM_B (1 << 13)
> >>> +#define DRM_MODE_TV_NORM_SECAM_D (1 << 14)
> >>> +#define DRM_MODE_TV_NORM_SECAM_G (1 << 15)
> >>> +#define DRM_MODE_TV_NORM_SECAM_K (1 << 16)
> >>> +#define DRM_MODE_TV_NORM_SECAM_K1 (1 << 17)
> >>> +#define DRM_MODE_TV_NORM_SECAM_L (1 << 18)
> >>> +#define DRM_MODE_TV_NORM_HD480I (1 << 19)
> >>> +#define DRM_MODE_TV_NORM_HD480P (1 << 20)
> >>> +#define DRM_MODE_TV_NORM_HD576I (1 << 21)
> >>> +#define DRM_MODE_TV_NORM_HD576P (1 << 22)
> >>> +#define DRM_MODE_TV_NORM_HD720P (1 << 23)
> >>> +#define DRM_MODE_TV_NORM_HD1080I (1 << 24)
> >>> +
> >>
> >> This is an area where DRM overlaps with v4l2, see:
> >> - include/dt-bindings/display/sdtv-standards.h
> >> - v4l2_norm_to_name()
> >>
> >> Maybe we should follow suit, but if we do our own thing please mention
> >> why in the commit message.
> >
> > Are you suggesting that we'd share that definition with v4l2?
> >
>
> If possible, yes.
>
> > I've tried to share some code in the past between v4l2 and DRM, and it
> > got completely shut down so it's not something I'd like to try again, if
> > possible.
> >
>
> But that is a good enough reason not to do so. I just got the impression
> from some of Laurent's emails a while back that there was some
> cooperativ atmosphere, but I might be mistaken in my reading/understanding.

Here's the original thread:
https://lore.kernel.org/lkml/cover.8ec406bf8f4f097e9dc909d5aac466556822f592.1555487650.git-series.maxime.ripard@bootlin.com/

It ended up stalling completely, without any will from either DRM or
v4l2 to get this through. So I will not work on anything like that until
both maintainership teams have expressed that it's something they
actually want.

> It is ofc possible to just copy the values from sdtv-standards.h, but I
> see that hd* is missing from that list, so not sure if there's much
> point if it has to be extended without changing the source.

HD formats were dropped, so it's not a big deal. However, we are missing
a few formats, but that were never used by either nouveau, i915 or any
other driver. I'm not sure it's worth adding at that point, and we can
always extend it later.

Maxime


Attachments:
(No filename) (3.30 kB)
signature.asc (235.00 B)
Download all attachments

2022-08-29 12:58:32

by Maxime Ripard

[permalink] [raw]
Subject: Re: [PATCH v1 23/35] drm/vc4: vec: Convert to the new TV mode property

Hi Noralf,

On Thu, Aug 25, 2022 at 03:14:01PM +0200, Noralf Tr?nnes wrote:
> Den 24.08.2022 17.26, skrev Maxime Ripard:
> > On Sat, Aug 20, 2022 at 07:22:48PM +0200, Noralf Tr?nnes wrote:
> >> Den 29.07.2022 18.35, skrev Maxime Ripard:
> >>> 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 <[email protected]>
> >>>
> >>> diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c
> >>
> >>> static int vc4_vec_connector_get_modes(struct drm_connector *connector)
> >>> {
> >>> - struct drm_connector_state *state = connector->state;
> >>> struct drm_display_mode *mode;
> >>>
> >>> - mode = drm_mode_duplicate(connector->dev,
> >>> - vc4_vec_tv_modes[state->tv.mode].mode);
> >>> + mode = drm_mode_duplicate(connector->dev, &drm_mode_480i);
> >>> + if (!mode) {
> >>> + DRM_ERROR("Failed to create a new display mode\n");
> >>> + return -ENOMEM;
> >>> + }
> >>> +
> >>> + drm_mode_probed_add(connector, mode);
> >>> +
> >>> + mode = drm_mode_duplicate(connector->dev, &drm_mode_576i);
> >>
> >> Maybe the mode that matches tv.norm should be marked as preferred so
> >> userspace knows which one to pick?
> >
> > I'm not sure how realistic that would be. Doing this based on the driver
> > / cmdline preference is going to be fairly easy, but then it's a
> > property, it's going to be updated, and we probably don't want to mess
> > around the mode flags based on new property values?
> >
>
> Strictly speaking we need to fire an event to userspace if the mode
> changes, and this is probably not straightforward to do underneath
> modeset locks, would probably need a worker.

I'm not sure this would work in all cases. Kodi for example doesn't
handle hotplug events at all, so we might end up in situations where the
state is not consistent anymore.

Even if we were to only expose one mode to the userspace, depending on
the current TV mode, userspace could still end up trying to push a mode
into KMS that isn't the one we expose anymore, so I'm not sure we can
solve this entirely.

> Clever userspace like GNOME will try to use the active mode, so it will
> handle this that way. If someone has set up the pipeline first that is.
> drm_client/fbdev and plymouth can do that because they honour userdef modes.
>
> Other userspace that don't know the userdef flag will fallback to the
> first mode which is NTSC which is also the default tvmode, so maybe this
> is good enough. PAL users will have to specify the mode, or teach their
> program about the userdef flag.
>
> But ofc relying on the userdef flag depends on the fact that there's a
> mode on the kernel command line, but maybe there's no way to avoid that
> since much/most? userspace treat "unknown" connector status as
> disconnected so many will have to force the connector to "connected"
> anyway. At least I don't know any way to permanetly force the connector
> status other than using video=.

You can do it through sysfs as well, in .../status

Maxime


Attachments:
(No filename) (3.22 kB)
signature.asc (235.00 B)
Download all attachments

2022-08-29 13:49:38

by Maxime Ripard

[permalink] [raw]
Subject: Re: [PATCH v1 04/35] drm/modes: Introduce 480i and 576i modes

Hi Mateusz

On Wed, Aug 24, 2022 at 06:42:18PM +0200, Mateusz Kwiatkowski wrote:
> Hi Maxime,
>
> W dniu 18.08.2022 o 17:56, Geert Uytterhoeven pisze:
> > Hi Maxime,
> >
> > On Thu, Aug 18, 2022 at 5:46 PM Maxime Ripard <[email protected]> wrote:
> >> On Thu, Aug 18, 2022 at 05:34:30PM +0200, Geert Uytterhoeven wrote:
> >>> On Thu, Aug 18, 2022 at 3:42 PM Maxime Ripard <[email protected]> wrote:
> >>>> I started adding more sanity checks to my code, and I just realised I
> >>>> don't seem to be able to reach 720 pixels over a single line though. If
> >>>> I understood it properly, and according to [1] the active part of a line
> >>>> is supposed to be 51.95us, and the blanking period taking 12.05us. [2]
> >>>> in the timing section has pretty much the same numbers, so it looks
> >>>> sane.
> >>>>
> >>>> At 13.5Mhz, a pixel is going to take roughly 74ns, and 51950 / 74 = 702
> >>>> pixels
> >>>>
> >>>> It seems we can go push it to 52350 ns, but that still gives us only 706
> >>>> pixels.
> >>>>
> >>>> Similarly, if I just choose to ignore that limit and just take the
> >>>> active time I need, 720 * 74 = 53280ns
> >>>>
> >>>> That leaves us 10720ns for the blanking period, and that's not enough to
> >>>> fit even the minimum of the front porch, hsync and back porch (1.55 +
> >>>> 4.5 + 5.5 = 11.55us).
> >>>>
> >>>> Are those constraints merely recommendations, or am I missing something?
> >>>
> >>> You are missing that the parts near the borders of the full image are
> >>> part of the overscan range, and may or may not be visible, depending
> >>> on your actual display.
> >>> The full 768x576 image size from BT.656 is not visible on a typical PAL display,
> >>> and is more of an "absolute maximum rating", guaranteed to cover more
> >>> than analog PAL.
> >>
> >> So the overscan range is not part of the active area, unlike what HDMI
> >> is doing for example?
> >
> > Indeed. DVI-D and HDMI etc. are pure digital (let's ignore they are a
> > digitized variant of old analog VGA ;-), hence there is a one-to-one
> > match between pixels in the image and pixels on the screen (ignoring
> > scaling).? But even when using an analog VGA input on a modern
> > digital display, you have controls to e.g. move the image.
> >
> >> Is there some minimal timings available somewhere to fit those absolute
> >> maximum ratings?
> >
> > I guess they can be found on the Internet...
>
> Here are some references that I personally found useful:
>
> - ITU-R BT.601 <https://www.itu.int/rec/R-REC-BT.601/en>
> ? This is *the* standard that pretty much every modern device that deals with
> ? analog-style TV signal follows then converting to and from the digital domain.
> ? For example in the figures on page 10 (12 in the PDF numbering) you can see
> ? that the "time datum", i.e. start of horizontal sync pulse is canonically
> ? supposed to happen on sample 732 for 50 Hz or sample 736 for 59.94 Hz modes.
>
> ? BT.601 assumes 13.5 MHz sample rate / pixel clock, but you can proportionally
> ? scale those for other pixel clocks.
>
> - ITU-R BT.1700 <https://www.itu.int/rec/R-REC-BT.1700/en>
> ? This is *the* standard in force for actual analog composite video signals.
> ? The vertical sync specs are discrete, so they don't really change between
> ? analog and digital domains. For horizontal sync, the values in those specs
> ? are given in microseconds/nanoseconds, but you can multiply those by the
> ? sampling rate for equivalent pixel counts.
>
> - Pembers' Ponderings
> ? <https://web.archive.org/web/20160423225838/http://www.pembers.freeserve.co.uk/>
> ? An old archived website with a ton of resources about analog TV.
> ? The "Line Standards" article will probably be most interesting to you.

Thanks so much for all those resources, it's been super helpful :)

> By the way, please note a couple of things:
>
> - The analog standards are very imprecise for modern digital norms, giving
> ? considerable leeway for just about every timing. The allowed leeways are
> ? usually equivalent to a couple of pixels at the standard 13.5 MHz sampling
> ? rate - and those are meant for the transmitting end. Receivers are usually
> ? much more forgiving to maximize compatibility.

Ok

> - The 720-pixel standard of BT.601 is considerably wider than the active width
> ? specified in the analog standards. AFAIK this is intentional, to ensure that
> ? no part of the actual image is missed during digitization, and to keep the
> ? number a nice multiply of 16. The picture width given in the analog standards
> ? is equivalent to somewhere between 702 and 714 pixels (at 13.5 MHz clock),
> ? depending on the specific standard. And that includes overscan.

Ok. I think it still makes sense to allow it, if only we were using it so far :)

I've done a first implementation in the v2 I just sent that seems to
work ok, please let me know if I did anything stupid :)

In particular, I chose, if we were between 702 and 720 pixels to disable
all duration checks, and take the missing time from the front and back
porch, in equal proportions.

> - Same goes for the vertical active area. Original analog standards varied
> ? wildly from country to country, before finally settling on 575 lines for the
> ? 50 Hz standard and 485 lines for the 59.94 Hz standard. Or 576/486, depending
> ? on how you count. The topmost line of those 576/486 starts at half the screen,
> ? and the bottommost line ends at half the screen - so they are often combined
> ? when counting and given as 575/485. The digital 576i50 standard includes
> ? those half-lines. In the 59.94 Hz regions, 480 active digial lines ended up
> ? the norm, because 486 does not have nice dividers, and also some of the
> ? outermost lines which were always overscanned anyway, ended up used for things
> ? like closed captioning over the years.

Ok

> - Speaking of closed captioning... a lot of different stuff were put in the
> ? blanking interval over the years. Like teletext in Europe. There are projects
> ? like VBIT2 <https://github.com/peterkvt80/vbit2> which intentionally
> ? reconfigure the Raspberry Pi composite output to include the blanking interval
> ? in the framebuffer so that teletext can be output by drawing on the edge of
> ? the "screen" (from the computer point of view).

I'm not sure how we would support this in KMS to be honest. Asking for a
wider mode and the userspace putting whatever it wants in the margins
seems like a good choice.

> - A lot of equipment outside the broadcast industry willingly violated those
> ? standards, and there are real world use cases for that. Film studios used very
> ? slightly modified TVs to make them sync with 24fps cameras - in that variant,
> ? "NTSC" could have e.g. 655 lines so that the TV would refresh at 48 Hz with
> ? the same line frequency. Home computers and video game consoles output
> ? progressive 262/312-line modes instead of interlaced 525/625 lines. And often
> ? changed the line frequency slightly as well, for various reasons. Those
> ? progressive modes are still favored by retro gaming and emulation enthusiasts,
> ? because they incur a specific look on CRT displays. Even playing back video
> ? from a tape (especially home-grade, like VHS) could cause timings to go wildly
> ? out of spec, because of mechanical imprecisions.

Ok

> - There were multitude of standards predating the ubiquitous 525/60 and 625/50
> ? modes. The British 405-line and French 819-line standards are the most
> ? notorious, having lasted well into the 1980s, but there were also a lot of
> ? wildly varying pre-WW2 television systems. And there are enthusiasts dedicated
> ? to preserving those.
>
> My point is that the norms for analog TV are rather loose, and I think we
> shouldn't limit the drivers to only accepting the "proper" modes as defined in
> the spec. Those should of course be the default, but if non-standard modelines
> can be generated - there are legitimate use cases why people might want those.

Yep, that part has been dropped. I'm still wondering if we'd need to
still have a bunch of restrictions (like a total number of lines of 625
with NTSC would be obviously invalid), but that can always be added
later on if such a need comes up

Maxime


Attachments:
(No filename) (8.20 kB)
signature.asc (235.00 B)
Download all attachments

2022-08-29 14:55:58

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH v1 04/35] drm/modes: Introduce 480i and 576i modes

Hi Maxime,

On Mon, Aug 29, 2022 at 3:30 PM Maxime Ripard <[email protected]> wrote:
> On Wed, Aug 24, 2022 at 06:42:18PM +0200, Mateusz Kwiatkowski wrote:
> > - Speaking of closed captioning... a lot of different stuff were put in the
> > blanking interval over the years. Like teletext in Europe. There are projects
> > like VBIT2 <https://github.com/peterkvt80/vbit2> which intentionally
> > reconfigure the Raspberry Pi composite output to include the blanking interval
> > in the framebuffer so that teletext can be output by drawing on the edge of
> > the "screen" (from the computer point of view).
>
> I'm not sure how we would support this in KMS to be honest. Asking for a
> wider mode and the userspace putting whatever it wants in the margins
> seems like a good choice.

s/wider/higher/

Teletext is transmitted in the "visible" parts of (horizontal) lines, but during
the vertical blank.

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

2022-08-29 14:57:09

by Maxime Ripard

[permalink] [raw]
Subject: Re: [PATCH v1 04/35] drm/modes: Introduce 480i and 576i modes

On Mon, Aug 29, 2022 at 04:14:54PM +0200, Geert Uytterhoeven wrote:
> Hi Maxime,
>
> On Mon, Aug 29, 2022 at 3:30 PM Maxime Ripard <[email protected]> wrote:
> > On Wed, Aug 24, 2022 at 06:42:18PM +0200, Mateusz Kwiatkowski wrote:
> > > - Speaking of closed captioning... a lot of different stuff were put in the
> > > blanking interval over the years. Like teletext in Europe. There are projects
> > > like VBIT2 <https://github.com/peterkvt80/vbit2> which intentionally
> > > reconfigure the Raspberry Pi composite output to include the blanking interval
> > > in the framebuffer so that teletext can be output by drawing on the edge of
> > > the "screen" (from the computer point of view).
> >
> > I'm not sure how we would support this in KMS to be honest. Asking for a
> > wider mode and the userspace putting whatever it wants in the margins
> > seems like a good choice.
>
> s/wider/higher/
>
> Teletext is transmitted in the "visible" parts of (horizontal) lines, but during
> the vertical blank.

Yeah, sorry I meant wider as in larger than the active area, without any
direction in mind. Thanks for the correction :)

Maxime


Attachments:
(No filename) (1.15 kB)
signature.asc (235.00 B)
Download all attachments

2022-08-30 22:44:53

by Mateusz Kwiatkowski

[permalink] [raw]
Subject: Re: [PATCH v1 00/35] drm: Analog TV Improvements

W dniu 26.08.2022 o 16:56, Dom Cobley pisze:
> On Fri, 26 Aug 2022 at 05:08, Mateusz Kwiatkowski <[email protected]> wrote:
>> - Commenting out the pm_runtime_put() / pm_runtime_get_sync() calls in vc4_vec.c
>> - Reverting this PR by Dom Cobley a.k.a. popcornmix:
>> https://github.com/raspberrypi/linux/pull/4639
>>
>> Either of these approaches makes VEC mode switching work again. Obviously
>> neither is appropriate for a permanent solution.
> Might be worth trying the latest rpi-update firmware.
> There was a change that affects restoring PIXEL/VEC clocks after a
> power domain cycle.
> There is also a fix for a USB boot breakage.
>
> If you still have an issue that occurs in downstream pi tree but not
> upstream, then create a linux github issue.

Hi Dom,

I just tested the 868f1cf firmware and its associated kernel, and everything
works like a charm for me, both USB boot and VEC power management.

Thanks!