2022-06-01 18:37:54

by Doug Anderson

[permalink] [raw]
Subject: [PATCH v4] drm/probe-helper: Default to 640x480 if no EDID on DP

If we're unable to read the EDID for a display because it's corrupt /
bogus / invalid then we'll add a set of standard modes for the
display. Since we have no true information about the connected
display, these modes are essentially guesses but better than nothing.
At the moment, none of the modes returned is marked as preferred, but
the modes are sorted such that the higher resolution modes are listed
first.

When userspace sees these modes presented by the kernel it needs to
figure out which one to pick. At least one userspace, ChromeOS [1]
seems to use the rules (which seem pretty reasonable):
1. Try to pick the first mode marked as preferred.
2. Try to pick the mode which matches the first detailed timing
descriptor in the EDID.
3. If no modes were marked as preferred then pick the first mode.

Unfortunately, userspace's rules combined with what the kernel is
doing causes us to fail section 4.2.2.6 (EDID Corruption Detection) of
the DP 1.4a Link CTS. That test case says that, while it's OK to allow
some implementation-specific fall-back modes if the EDID is bad that
userspace should _default_ to 640x480.

Let's fix this by marking 640x480 as default for DP in the no-EDID
case.

NOTES:
- In the discussion around v3 of this patch [2] there was talk about
solving this in userspace and I even implemented a patch that would
have solved this for ChromeOS, but then the discussion turned back
to solving this in the kernel.
- Also in the discussion of v3 [2] it was requested to limit this
83;40900;0c change to just DP since folks were worried that it would break some
subtle corner case on VGA or HDMI.

[1] https://source.chromium.org/chromium/chromium/src/+/a051f741d0a15caff2251301efe081c30e0f4a96:ui/ozone/platform/drm/common/drm_util.cc;l=488
[2] https://lore.kernel.org/r/20220513130533.v3.1.I31ec454f8d4ffce51a7708a8092f8a6f9c929092@changeid

Signed-off-by: Douglas Anderson <[email protected]>
Reviewed-by: Abhinav Kumar <[email protected]>
---
I put Abhinav's Reviewed-by tag from v2 here since this is nearly the
same as v2. Hope this is OK.

Changes in v4:
- Code is back to v2, but limit to just DP.
- Beefed up the commit message.

Changes in v3:
- Don't set preferred, just disable the sort.

Changes in v2:
- Don't modify drm_add_modes_noedid() 'cause that'll break others
- Set 640x480 as preferred in drm_helper_probe_single_connector_modes()

drivers/gpu/drm/drm_probe_helper.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
index 425f56280d51..75a71649b64d 100644
--- a/drivers/gpu/drm/drm_probe_helper.c
+++ b/drivers/gpu/drm/drm_probe_helper.c
@@ -569,8 +569,17 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
count = drm_add_override_edid_modes(connector);

if (count == 0 && (connector->status == connector_status_connected ||
- connector->status == connector_status_unknown))
+ connector->status == connector_status_unknown)) {
count = drm_add_modes_noedid(connector, 1024, 768);
+
+ /*
+ * Section 4.2.2.6 (EDID Corruption Detection) of the DP 1.4a
+ * Link CTS specifies that 640x480 (the official "failsafe"
+ * mode) needs to be the default if there's no EDID.
+ */
+ if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort)
+ drm_set_preferred_mode(connector, 640, 480);
+ }
count += drm_helper_probe_add_cmdline_mode(connector);
if (count != 0) {
ret = __drm_helper_update_and_validate(connector, maxX, maxY, &ctx);
--
2.36.1.255.ge46751e96f-goog



2022-06-01 21:38:56

by Sean Paul

[permalink] [raw]
Subject: Re: [Freedreno] [PATCH v4] drm/probe-helper: Default to 640x480 if no EDID on DP

On Wed, Jun 1, 2022 at 2:23 PM Douglas Anderson <[email protected]> wrote:
>
> If we're unable to read the EDID for a display because it's corrupt /
> bogus / invalid then we'll add a set of standard modes for the
> display. Since we have no true information about the connected
> display, these modes are essentially guesses but better than nothing.
> At the moment, none of the modes returned is marked as preferred, but
> the modes are sorted such that the higher resolution modes are listed
> first.
>
> When userspace sees these modes presented by the kernel it needs to
> figure out which one to pick. At least one userspace, ChromeOS [1]
> seems to use the rules (which seem pretty reasonable):
> 1. Try to pick the first mode marked as preferred.
> 2. Try to pick the mode which matches the first detailed timing
> descriptor in the EDID.
> 3. If no modes were marked as preferred then pick the first mode.
>
> Unfortunately, userspace's rules combined with what the kernel is
> doing causes us to fail section 4.2.2.6 (EDID Corruption Detection) of
> the DP 1.4a Link CTS. That test case says that, while it's OK to allow
> some implementation-specific fall-back modes if the EDID is bad that
> userspace should _default_ to 640x480.
>
> Let's fix this by marking 640x480 as default for DP in the no-EDID
> case.
>
> NOTES:
> - In the discussion around v3 of this patch [2] there was talk about
> solving this in userspace and I even implemented a patch that would
> have solved this for ChromeOS, but then the discussion turned back
> to solving this in the kernel.
> - Also in the discussion of v3 [2] it was requested to limit this
> 83;40900;0c change to just DP since folks were worried that it would break some
> subtle corner case on VGA or HDMI.
>
> [1] https://source.chromium.org/chromium/chromium/src/+/a051f741d0a15caff2251301efe081c30e0f4a96:ui/ozone/platform/drm/common/drm_util.cc;l=488
> [2] https://lore.kernel.org/r/20220513130533.v3.1.I31ec454f8d4ffce51a7708a8092f8a6f9c929092@changeid
>
> Signed-off-by: Douglas Anderson <[email protected]>
> Reviewed-by: Abhinav Kumar <[email protected]>


Reviewed-by: Sean Paul <[email protected]>

>
> ---
> I put Abhinav's Reviewed-by tag from v2 here since this is nearly the
> same as v2. Hope this is OK.
>
> Changes in v4:
> - Code is back to v2, but limit to just DP.
> - Beefed up the commit message.
>
> Changes in v3:
> - Don't set preferred, just disable the sort.
>
> Changes in v2:
> - Don't modify drm_add_modes_noedid() 'cause that'll break others
> - Set 640x480 as preferred in drm_helper_probe_single_connector_modes()
>
> drivers/gpu/drm/drm_probe_helper.c | 11 ++++++++++-
> 1 file changed, 10 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
> index 425f56280d51..75a71649b64d 100644
> --- a/drivers/gpu/drm/drm_probe_helper.c
> +++ b/drivers/gpu/drm/drm_probe_helper.c
> @@ -569,8 +569,17 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
> count = drm_add_override_edid_modes(connector);
>
> if (count == 0 && (connector->status == connector_status_connected ||
> - connector->status == connector_status_unknown))
> + connector->status == connector_status_unknown)) {
> count = drm_add_modes_noedid(connector, 1024, 768);
> +
> + /*
> + * Section 4.2.2.6 (EDID Corruption Detection) of the DP 1.4a
> + * Link CTS specifies that 640x480 (the official "failsafe"
> + * mode) needs to be the default if there's no EDID.
> + */
> + if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort)
> + drm_set_preferred_mode(connector, 640, 480);
> + }
> count += drm_helper_probe_add_cmdline_mode(connector);
> if (count != 0) {
> ret = __drm_helper_update_and_validate(connector, maxX, maxY, &ctx);
> --
> 2.36.1.255.ge46751e96f-goog
>

2022-06-01 21:39:01

by Dmitry Baryshkov

[permalink] [raw]
Subject: Re: [PATCH v4] drm/probe-helper: Default to 640x480 if no EDID on DP

On 01/06/2022 21:23, Douglas Anderson wrote:
> If we're unable to read the EDID for a display because it's corrupt /
> bogus / invalid then we'll add a set of standard modes for the
> display. Since we have no true information about the connected
> display, these modes are essentially guesses but better than nothing.
> At the moment, none of the modes returned is marked as preferred, but
> the modes are sorted such that the higher resolution modes are listed
> first.
>
> When userspace sees these modes presented by the kernel it needs to
> figure out which one to pick. At least one userspace, ChromeOS [1]
> seems to use the rules (which seem pretty reasonable):
> 1. Try to pick the first mode marked as preferred.
> 2. Try to pick the mode which matches the first detailed timing
> descriptor in the EDID.
> 3. If no modes were marked as preferred then pick the first mode.
>
> Unfortunately, userspace's rules combined with what the kernel is
> doing causes us to fail section 4.2.2.6 (EDID Corruption Detection) of
> the DP 1.4a Link CTS. That test case says that, while it's OK to allow
> some implementation-specific fall-back modes if the EDID is bad that
> userspace should _default_ to 640x480.
>
> Let's fix this by marking 640x480 as default for DP in the no-EDID
> case.
>
> NOTES:
> - In the discussion around v3 of this patch [2] there was talk about
> solving this in userspace and I even implemented a patch that would
> have solved this for ChromeOS, but then the discussion turned back
> to solving this in the kernel.
> - Also in the discussion of v3 [2] it was requested to limit this
> 83;40900;0c change to just DP since folks were worried that it would break some

Nit: this line seems broken

> subtle corner case on VGA or HDMI.
>
> [1] https://source.chromium.org/chromium/chromium/src/+/a051f741d0a15caff2251301efe081c30e0f4a96:ui/ozone/platform/drm/common/drm_util.cc;l=488
> [2] https://lore.kernel.org/r/20220513130533.v3.1.I31ec454f8d4ffce51a7708a8092f8a6f9c929092@changeid
>
> Signed-off-by: Douglas Anderson <[email protected]>
> Reviewed-by: Abhinav Kumar <[email protected]>

Reviewed-by: Dmitry Baryshkov <[email protected]>

> ---
> I put Abhinav's Reviewed-by tag from v2 here since this is nearly the
> same as v2. Hope this is OK.
>
> Changes in v4:
> - Code is back to v2, but limit to just DP.
> - Beefed up the commit message.
>
> Changes in v3:
> - Don't set preferred, just disable the sort.
>
> Changes in v2:
> - Don't modify drm_add_modes_noedid() 'cause that'll break others
> - Set 640x480 as preferred in drm_helper_probe_single_connector_modes()
>
> drivers/gpu/drm/drm_probe_helper.c | 11 ++++++++++-
> 1 file changed, 10 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
> index 425f56280d51..75a71649b64d 100644
> --- a/drivers/gpu/drm/drm_probe_helper.c
> +++ b/drivers/gpu/drm/drm_probe_helper.c
> @@ -569,8 +569,17 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
> count = drm_add_override_edid_modes(connector);
>
> if (count == 0 && (connector->status == connector_status_connected ||
> - connector->status == connector_status_unknown))
> + connector->status == connector_status_unknown)) {
> count = drm_add_modes_noedid(connector, 1024, 768);
> +
> + /*
> + * Section 4.2.2.6 (EDID Corruption Detection) of the DP 1.4a
> + * Link CTS specifies that 640x480 (the official "failsafe"
> + * mode) needs to be the default if there's no EDID.
> + */
> + if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort)
> + drm_set_preferred_mode(connector, 640, 480);
> + }
> count += drm_helper_probe_add_cmdline_mode(connector);
> if (count != 0) {
> ret = __drm_helper_update_and_validate(connector, maxX, maxY, &ctx);


--
With best wishes
Dmitry

2022-06-02 12:04:30

by Jani Nikula

[permalink] [raw]
Subject: Re: [PATCH v4] drm/probe-helper: Default to 640x480 if no EDID on DP

On Wed, 01 Jun 2022, Douglas Anderson <[email protected]> wrote:
> If we're unable to read the EDID for a display because it's corrupt /
> bogus / invalid then we'll add a set of standard modes for the
> display. Since we have no true information about the connected
> display, these modes are essentially guesses but better than nothing.
> At the moment, none of the modes returned is marked as preferred, but
> the modes are sorted such that the higher resolution modes are listed
> first.
>
> When userspace sees these modes presented by the kernel it needs to
> figure out which one to pick. At least one userspace, ChromeOS [1]
> seems to use the rules (which seem pretty reasonable):
> 1. Try to pick the first mode marked as preferred.
> 2. Try to pick the mode which matches the first detailed timing
> descriptor in the EDID.
> 3. If no modes were marked as preferred then pick the first mode.
>
> Unfortunately, userspace's rules combined with what the kernel is
> doing causes us to fail section 4.2.2.6 (EDID Corruption Detection) of
> the DP 1.4a Link CTS. That test case says that, while it's OK to allow
> some implementation-specific fall-back modes if the EDID is bad that
> userspace should _default_ to 640x480.
>
> Let's fix this by marking 640x480 as default for DP in the no-EDID
> case.
>
> NOTES:
> - In the discussion around v3 of this patch [2] there was talk about
> solving this in userspace and I even implemented a patch that would
> have solved this for ChromeOS, but then the discussion turned back
> to solving this in the kernel.
> - Also in the discussion of v3 [2] it was requested to limit this
> 83;40900;0c change to just DP since folks were worried that it would break some
> subtle corner case on VGA or HDMI.
>
> [1] https://source.chromium.org/chromium/chromium/src/+/a051f741d0a15caff2251301efe081c30e0f4a96:ui/ozone/platform/drm/common/drm_util.cc;l=488
> [2] https://lore.kernel.org/r/20220513130533.v3.1.I31ec454f8d4ffce51a7708a8092f8a6f9c929092@changeid
>
> Signed-off-by: Douglas Anderson <[email protected]>
> Reviewed-by: Abhinav Kumar <[email protected]>
> ---
> I put Abhinav's Reviewed-by tag from v2 here since this is nearly the
> same as v2. Hope this is OK.
>
> Changes in v4:
> - Code is back to v2, but limit to just DP.
> - Beefed up the commit message.
>
> Changes in v3:
> - Don't set preferred, just disable the sort.
>
> Changes in v2:
> - Don't modify drm_add_modes_noedid() 'cause that'll break others
> - Set 640x480 as preferred in drm_helper_probe_single_connector_modes()
>
> drivers/gpu/drm/drm_probe_helper.c | 11 ++++++++++-
> 1 file changed, 10 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
> index 425f56280d51..75a71649b64d 100644
> --- a/drivers/gpu/drm/drm_probe_helper.c
> +++ b/drivers/gpu/drm/drm_probe_helper.c
> @@ -569,8 +569,17 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
> count = drm_add_override_edid_modes(connector);
>
> if (count == 0 && (connector->status == connector_status_connected ||
> - connector->status == connector_status_unknown))
> + connector->status == connector_status_unknown)) {
> count = drm_add_modes_noedid(connector, 1024, 768);
> +
> + /*
> + * Section 4.2.2.6 (EDID Corruption Detection) of the DP 1.4a
> + * Link CTS specifies that 640x480 (the official "failsafe"
> + * mode) needs to be the default if there's no EDID.
> + */
> + if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort)

If we're doing this primarily to appease the CTS, this is fine.

If we think this is a functional improvement for regular use, I suppose
we should consider doing this also for DRM_MODE_CONNECTOR_eDP. Which is
irrelevant for the CTS.

Either way,

Acked-by: Jani Nikula <[email protected]>

> + drm_set_preferred_mode(connector, 640, 480);
> + }
> count += drm_helper_probe_add_cmdline_mode(connector);
> if (count != 0) {
> ret = __drm_helper_update_and_validate(connector, maxX, maxY, &ctx);

--
Jani Nikula, Intel Open Source Graphics Center

2022-06-06 20:47:01

by Doug Anderson

[permalink] [raw]
Subject: Re: [PATCH v4] drm/probe-helper: Default to 640x480 if no EDID on DP

Hi,

On Wed, Jun 1, 2022 at 11:23 AM Douglas Anderson <[email protected]> wrote:
>
> If we're unable to read the EDID for a display because it's corrupt /
> bogus / invalid then we'll add a set of standard modes for the
> display. Since we have no true information about the connected
> display, these modes are essentially guesses but better than nothing.
> At the moment, none of the modes returned is marked as preferred, but
> the modes are sorted such that the higher resolution modes are listed
> first.
>
> When userspace sees these modes presented by the kernel it needs to
> figure out which one to pick. At least one userspace, ChromeOS [1]
> seems to use the rules (which seem pretty reasonable):
> 1. Try to pick the first mode marked as preferred.
> 2. Try to pick the mode which matches the first detailed timing
> descriptor in the EDID.
> 3. If no modes were marked as preferred then pick the first mode.
>
> Unfortunately, userspace's rules combined with what the kernel is
> doing causes us to fail section 4.2.2.6 (EDID Corruption Detection) of
> the DP 1.4a Link CTS. That test case says that, while it's OK to allow
> some implementation-specific fall-back modes if the EDID is bad that
> userspace should _default_ to 640x480.
>
> Let's fix this by marking 640x480 as default for DP in the no-EDID
> case.
>
> NOTES:
> - In the discussion around v3 of this patch [2] there was talk about
> solving this in userspace and I even implemented a patch that would
> have solved this for ChromeOS, but then the discussion turned back
> to solving this in the kernel.
> - Also in the discussion of v3 [2] it was requested to limit this
> 83;40900;0c change to just DP since folks were worried that it would break some
> subtle corner case on VGA or HDMI.
>
> [1] https://source.chromium.org/chromium/chromium/src/+/a051f741d0a15caff2251301efe081c30e0f4a96:ui/ozone/platform/drm/common/drm_util.cc;l=488
> [2] https://lore.kernel.org/r/20220513130533.v3.1.I31ec454f8d4ffce51a7708a8092f8a6f9c929092@changeid
>
> Signed-off-by: Douglas Anderson <[email protected]>
> Reviewed-by: Abhinav Kumar <[email protected]>
> ---
> I put Abhinav's Reviewed-by tag from v2 here since this is nearly the
> same as v2. Hope this is OK.
>
> Changes in v4:
> - Code is back to v2, but limit to just DP.
> - Beefed up the commit message.
>
> Changes in v3:
> - Don't set preferred, just disable the sort.
>
> Changes in v2:
> - Don't modify drm_add_modes_noedid() 'cause that'll break others
> - Set 640x480 as preferred in drm_helper_probe_single_connector_modes()
>
> drivers/gpu/drm/drm_probe_helper.c | 11 ++++++++++-
> 1 file changed, 10 insertions(+), 1 deletion(-)

Pushed to drm-misc-next after cleaning up the turd that I somehow left
in the commit message.

fae7d186403e drm/probe-helper: Default to 640x480 if no EDID on DP

-Doug