drm: handle override/firmware edid at the lowest level
Subsystems (2)
cover drm: handle override/firmware edid at the lowest level
This is a simplified version of the perhaps too ambitious RFC [1].
Here we simply handle debugfs override edid and the firmware edid at the drm_do_get_edid() level, not at the probe helper level. With this, everything from EDID gets transparently overridden.
BR,
Jani.
[1] http://mid.mail-archive.com/[email protected]
Jani Nikula (3):
drm: move edid property update and add modes out of edid firmware
loader
drm: reset ELD if NULL edid is passed to drm_edid_to_eld
drm: handle override edid and firmware EDID at drm_do_get_edid() level
drivers/gpu/drm/drm_edid.c | 18 ++++++++++++++++++ drivers/gpu/drm/drm_edid_load.c | 17 ++++------------- drivers/gpu/drm/drm_probe_helper.c | 13 +------------ include/drm/drm_edid.h | 7 ++++--- 4 files changed, 27 insertions(+), 28 deletions(-)
Signature · 6 lines
2.1.4 _______________________________________________ Intel-gfx mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/intel-gfx
PATCH 1/3 drm: move edid property update and add modes out of edid firmware loader
Make the firmware loader more generic and generally useful.
--- drivers/gpu/drm/drm_edid_load.c | 17 ++++------------- drivers/gpu/drm/drm_probe_helper.c | 8 +++++++- include/drm/drm_edid.h | 7 ++++--- 3 files changed, 15 insertions(+), 17 deletions(-)
drivers/gpu/drm/drm_edid_load.c +4 -13
@@ -256,15 +256,14 @@ static void *edid_load(struct drm_connector *connector, const char *name,return edid; } -int drm_load_edid_firmware (struct drm_connector *connector) +struct edid *drm_load_edid_firmware (struct drm_connector *connector) {const char *connector_name = connector->name;char *edidname, *last, *colon, *fwstr, *edidstr, *fallback =NULL ; -int ret;struct edid *edid;if (edid_firmware[0 ] =='\0' ) -return 0 ; +return ERR_PTR (-ENOENT );/* * If there are multiple edid files specified and separated
@@ -293,7 +292,7 @@ int drm_load_edid_firmware(struct drm_connector *connector)if (!edidname) {if (!fallback) {kfree (fwstr); -return 0 ; +return ERR_PTR (-ENOENT ); } edidname = fallback; }
@@ -305,13 +304,5 @@ int drm_load_edid_firmware(struct drm_connector *connector) edid =edid_load (connector, edidname, connector_name);kfree (fwstr); -if (IS_ERR_OR_NULL (edid)) -return 0 ; - -drm_mode_connector_update_edid_property (connector, edid); - ret =drm_add_edid_modes (connector, edid); -drm_edid_to_eld (connector, edid); -kfree (edid); - -return ret; +return edid; }
drivers/gpu/drm/drm_probe_helper.c +7 -1
@@ -311,7 +311,13 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, count =drm_add_edid_modes (connector, edid);drm_edid_to_eld (connector, edid); }else { - count =drm_load_edid_firmware (connector); +struct edid *edid =drm_load_edid_firmware (connector); +if (!IS_ERR_OR_NULL (edid)) { +drm_mode_connector_update_edid_property (connector, edid); + count =drm_add_edid_modes (connector, edid); +drm_edid_to_eld (connector, edid); +kfree (edid); + }if (count ==0 ) count = (*connector_funcs->get_modes)(connector); }
include/drm/drm_edid.h +4 -3
@@ -331,11 +331,12 @@ int drm_av_sync_delay(struct drm_connector *connector, const struct drm_display_mode *mode);#ifdef CONFIG_DRM_LOAD_EDID_FIRMWARE -int drm_load_edid_firmware (struct drm_connector *connector); +struct edid *drm_load_edid_firmware (struct drm_connector *connector);#else -static inline int drm_load_edid_firmware (struct drm_connector *connector) +static inline struct edid * +drm_load_edid_firmware (struct drm_connector *connector) { -return 0 ; +return ERR_PTR (-ENOENT ); }#endif
Signature · 6 lines
2.1.4 _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
PATCH 2/3 drm: reset ELD if NULL edid is passed to drm_edid_to_eld
In reply to Jani NikulaMake the function useful for resetting, not just setting, the ELD.
--- drivers/gpu/drm/drm_edid.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/gpu/drm/drm_edid.c +3 -0
@@ -3430,6 +3430,9 @@ void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid)memset (eld,0 ,sizeof (connector->eld)); +if (!edid) +return ; + connector->latency_present[0 ] = false; connector->latency_present[1 ] = false; connector->video_latency[0 ] =0 ;
Signature · 6 lines
2.1.4 _______________________________________________ Intel-gfx mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/intel-gfx
PATCH 3/3 drm: handle override edid and firmware adid at drm_do_get_edid()
In reply to Jani NikulaHandle override edid and firmware edid at the low level to transparently and completely replace the real edid. This also prevents actual edid reads for them, but retains ddc probe.
FIXME: validate override edid, deduplicate firmware edid validation.
--- drivers/gpu/drm/drm_edid.c | 15 +++++++++++++++ drivers/gpu/drm/drm_probe_helper.c | 19 +------------------ 2 files changed, 16 insertions(+), 18 deletions(-)
drivers/gpu/drm/drm_edid.c +15 -0
@@ -1309,6 +1309,10 @@ static void connector_bad_edid(struct drm_connector *connector,* level, drivers must make all reasonable efforts to expose it as an I2C * adapter and use drm_get_edid() instead of abusing this function. * +* The EDID may be overridden using debugfs override_edid or firmare EDID +* (drm_load_edid_firmware()), in this priority order. Having either of them +* bypasses actual EDID reads. +* * Return: Pointer to valid EDID or NULL if we couldn't find any. */ struct edid *drm_do_get_edid(struct drm_connector *connector,
@@ -1318,6 +1322,17 @@ struct edid *drm_do_get_edid(struct drm_connector *connector, {int i, j =0 , valid_extensions =0 ;u8 *edid, *new; +struct edid *override =NULL ; + +if (connector->override_edid) + override =drm_edid_duplicate ((const struct edid *) + connector->edid_blob_ptr->data); + +if (!override) + override =drm_load_edid_firmware (connector); + +if (!IS_ERR_OR_NULL (override)) +return override;if ((edid =kmalloc (EDID_LENGTH ,GFP_KERNEL )) ==NULL )return NULL ;
drivers/gpu/drm/drm_probe_helper.c +1 -18
@@ -199,8 +199,6 @@ drm_connector_detect(struct drm_connector *connector, bool force)* drm_mode_probed_add(). New modes start their life with status as OK. * Modes are added from a single source using the following priority order. * -* - debugfs 'override_edid' (used for testing only) -* - firmware EDID (drm_load_edid_firmware()) * - &drm_connector_helper_funcs.get_modes vfunc * - if the connector status is connector_status_connected, standard * VESA DMT modes up to 1024x768 are automatically added
@@ -305,22 +303,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, goto prune; } -if (connector->override_edid) { -struct edid *edid = (struct edid *) connector->edid_blob_ptr->data; - - count =drm_add_edid_modes (connector, edid); -drm_edid_to_eld (connector, edid); - }else { -struct edid *edid =drm_load_edid_firmware (connector); -if (!IS_ERR_OR_NULL (edid)) { -drm_mode_connector_update_edid_property (connector, edid); - count =drm_add_edid_modes (connector, edid); -drm_edid_to_eld (connector, edid); -kfree (edid); - } -if (count ==0 ) - count = (*connector_funcs->get_modes)(connector); - } + count = (*connector_funcs->get_modes)(connector);if (count ==0 && connector->status == connector_status_connected) count =drm_add_modes_noedid (connector,1024 ,768 );
Signature · 6 lines
2.1.4 _______________________________________________ Intel-gfx mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/intel-gfx
PATCH 3/3 drm: handle override edid and firmware EDID at drm_do_get_edid() level
In reply to Jani NikulaHandle debugfs override edid and firmware edid at the low level to transparently and completely replace the real edid. Previously, we practically only used the modes from the override EDID, and none of the other data. This also prevents actual EDID reads when the EDID is to be overridden, but retains the DDC probe.
FIXME: validate override edid, deduplicate firmware edid validation.
--- drivers/gpu/drm/drm_edid.c | 15 +++++++++++++++ drivers/gpu/drm/drm_probe_helper.c | 19 +------------------ 2 files changed, 16 insertions(+), 18 deletions(-)
drivers/gpu/drm/drm_edid.c +15 -0
@@ -1309,6 +1309,10 @@ static void connector_bad_edid(struct drm_connector *connector,* level, drivers must make all reasonable efforts to expose it as an I2C * adapter and use drm_get_edid() instead of abusing this function. * +* The EDID may be overridden using debugfs override_edid or firmare EDID +* (drm_load_edid_firmware()), in this priority order. Having either of them +* bypasses actual EDID reads. +* * Return: Pointer to valid EDID or NULL if we couldn't find any. */ struct edid *drm_do_get_edid(struct drm_connector *connector,
@@ -1318,6 +1322,17 @@ struct edid *drm_do_get_edid(struct drm_connector *connector, {int i, j =0 , valid_extensions =0 ;u8 *edid, *new; +struct edid *override =NULL ; + +if (connector->override_edid) + override =drm_edid_duplicate ((const struct edid *) + connector->edid_blob_ptr->data); + +if (!override) + override =drm_load_edid_firmware (connector); + +if (!IS_ERR_OR_NULL (override)) +return override;if ((edid =kmalloc (EDID_LENGTH ,GFP_KERNEL )) ==NULL )return NULL ;
drivers/gpu/drm/drm_probe_helper.c +1 -18
@@ -199,8 +199,6 @@ drm_connector_detect(struct drm_connector *connector, bool force)* drm_mode_probed_add(). New modes start their life with status as OK. * Modes are added from a single source using the following priority order. * -* - debugfs 'override_edid' (used for testing only) -* - firmware EDID (drm_load_edid_firmware()) * - &drm_connector_helper_funcs.get_modes vfunc * - if the connector status is connector_status_connected, standard * VESA DMT modes up to 1024x768 are automatically added
@@ -305,22 +303,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, goto prune; } -if (connector->override_edid) { -struct edid *edid = (struct edid *) connector->edid_blob_ptr->data; - - count =drm_add_edid_modes (connector, edid); -drm_edid_to_eld (connector, edid); - }else { -struct edid *edid =drm_load_edid_firmware (connector); -if (!IS_ERR_OR_NULL (edid)) { -drm_mode_connector_update_edid_property (connector, edid); - count =drm_add_edid_modes (connector, edid); -drm_edid_to_eld (connector, edid); -kfree (edid); - } -if (count ==0 ) - count = (*connector_funcs->get_modes)(connector); - } + count = (*connector_funcs->get_modes)(connector);if (count ==0 && connector->status == connector_status_connected) count =drm_add_modes_noedid (connector,1024 ,768 );
Signature · 6 lines
2.1.4 _______________________________________________ Intel-gfx mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [PATCH 3/3] drm: handle override edid and firmware adid at drm_do_get_edid()
In reply to Jani NikulaQuoted 3 lines · Jani Nikula
Handle override edid and firmware edid at the low level to transparently and completely replace the real edid. This also prevents actual edid reads for them, but retains ddc probe.
Please ignore this stray patch, and look at the series at
https://patchwork.freedesktop.org/series/19764/
Sorry for the noise,
Jani.
Signature · 5 lines
Jani Nikula, Intel Open Source Technology Center _______________________________________________ Intel-gfx mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Patchwork
CI✗ Fi.CI.BAT: failure for drm: handle override/firmware edid at the lowest level
In reply to Jani Nikula== Series Details ==
== Series Details ==
Series: drm: handle override/firmware edid at the lowest level
URL : https://patchwork.freedesktop.org/series/19764/
State : failure
== Summary ==
Series 19764v1 drm: handle override/firmware edid at the lowest level
https://patchwork.freedesktop.org/api/1.0/series/19764/revisions/1/mbox/
Test kms_force_connector_basic:
Subgroup force-edid:
pass -> FAIL (fi-byt-j1900)
pass -> FAIL (fi-snb-2520m)
pass -> FAIL (fi-ivb-3770)
pass -> FAIL (fi-ivb-3520m)
pass -> FAIL (fi-snb-2600)
Subgroup prune-stale-modes:
pass -> FAIL (fi-byt-j1900)
pass -> FAIL (fi-snb-2520m)
pass -> FAIL (fi-ivb-3770)
pass -> FAIL (fi-ivb-3520m)
pass -> FAIL (fi-snb-2600)fi-bdw-5557u total:252 pass:241 dwarn:0 dfail:0 fail:0 skip:11 fi-bsw-n3050 total:252 pass:213 dwarn:0 dfail:0 fail:0 skip:39 fi-bxt-j4205 total:252 pass:233 dwarn:0 dfail:0 fail:0 skip:19 fi-bxt-t5700 total:83 pass:70 dwarn:0 dfail:0 fail:0 skip:12 fi-byt-j1900 total:252 pass:223 dwarn:0 dfail:0 fail:2 skip:27 fi-byt-n2820 total:252 pass:221 dwarn:0 dfail:0 fail:0 skip:31 fi-hsw-4770 total:252 pass:236 dwarn:0 dfail:0 fail:0 skip:16 fi-hsw-4770r total:252 pass:236 dwarn:0 dfail:0 fail:0 skip:16 fi-ilk-650 total:252 pass:202 dwarn:0 dfail:0 fail:0 skip:50 fi-ivb-3520m total:252 pass:232 dwarn:0 dfail:0 fail:2 skip:18 fi-ivb-3770 total:252 pass:232 dwarn:0 dfail:0 fail:2 skip:18 fi-kbl-7500u total:252 pass:234 dwarn:0 dfail:0 fail:0 skip:18 fi-skl-6260u total:252 pass:242 dwarn:0 dfail:0 fail:0 skip:10 fi-skl-6700hq total:252 pass:235 dwarn:0 dfail:0 fail:0 skip:17 fi-skl-6700k total:252 pass:230 dwarn:4 dfail:0 fail:0 skip:18 fi-skl-6770hq total:252 pass:242 dwarn:0 dfail:0 fail:0 skip:10 fi-snb-2520m total:252 pass:222 dwarn:0 dfail:0 fail:2 skip:28 fi-snb-2600 total:252 pass:221 dwarn:0 dfail:0 fail:2 skip:29
89a932d98b6e1733011019c9872583a9c7c8fda3 drm-tip: 2017y-02m-16d-10h-06m-42s UTC integration manifest ee36efc drm: handle override edid and firmware adid at drm_do_get_edid()
21cd354 drm: reset ELD if NULL edid is passed to drm_edid_to_eld
a0f096f drm: move edid property update and add modes out of edid firmware loader
== Logs ==
For more details see: https://intel-gfx-ci.01.org/CI/Patchwork_3852/
_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [PATCH 2/3] drm: reset ELD if NULL edid is passed to drm_edid_to_eld
In reply to Jani NikulaQuoted 12 lines · Jani Nikula
Make the function useful for resetting, not just setting, the ELD.
Signed-off-by Jani Nikula <[email protected]>--- drivers/gpu/drm/drm_edid.c | 3 +++ 1 file changed, 3 insertions(+)drivers/gpu/drm/drm_edid.c +0
-0
drivers/gpu/drm/drm_edid.c void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid) · line 3438
Quoted 9 lines
drivers/gpu/drm/drm_edid.c +3
-0@@ -3430,6 +3430,9 @@ void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid)memset (eld,0 ,sizeof (connector->eld)); +if (!edid) +return ; + connector->latency_present[0 ] = false; connector->latency_present[1 ] = false; connector->video_latency[0 ] =0 ;
/me thinks the check should be after all these.
Hmm. Actually the cea ext block check below should be safe wrt. edid==NULL, so not sure we need this at all.
Signature · 6 lines
Ville Syrjälä Intel OTC _______________________________________________ Intel-gfx mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [PATCH 3/3] drm: handle override edid and firmware EDID at drm_do_get_edid() level
In reply to Jani NikulaQuoted 5 lines · Jani Nikula
Handle debugfs override edid and firmware edid at the low level to transparently and completely replace the real edid. Previously, we practically only used the modes from the override EDID, and none of the other data. This also prevents actual EDID reads when the EDID is to be overridden, but retains the DDC probe.
Hmm. Isn't that a bad thing? If someone has broken DDC on their cable or somethign then the override EDID wouldn't be returned by drm_get_edid().
Quoted 81 lines
FIXME: validate override edid, deduplicate firmware edid validation.
Signed-off-by Jani Nikula <[email protected]>--- drivers/gpu/drm/drm_edid.c | 15 +++++++++++++++ drivers/gpu/drm/drm_probe_helper.c | 19 +------------------ 2 files changed, 16 insertions(+), 18 deletions(-)drivers/gpu/drm/drm_edid.c +15
-0@@ -1309,6 +1309,10 @@ static void connector_bad_edid(struct drm_connector *connector,* level, drivers must make all reasonable efforts to expose it as an I2C * adapter and use drm_get_edid() instead of abusing this function. * +* The EDID may be overridden using debugfs override_edid or firmare EDID +* (drm_load_edid_firmware()), in this priority order. Having either of them +* bypasses actual EDID reads. +* * Return: Pointer to valid EDID or NULL if we couldn't find any. */ struct edid *drm_do_get_edid(struct drm_connector *connector,@@ -1318,6 +1322,17 @@ struct edid *drm_do_get_edid(struct drm_connector *connector, {int i, j =0 , valid_extensions =0 ;u8 *edid, *new; +struct edid *override =NULL ; + +if (connector->override_edid) + override =drm_edid_duplicate ((const struct edid *) + connector->edid_blob_ptr->data); + +if (!override) + override =drm_load_edid_firmware (connector); + +if (!IS_ERR_OR_NULL (override)) +return override;if ((edid =kmalloc (EDID_LENGTH ,GFP_KERNEL )) ==NULL )return NULL ;drivers/gpu/drm/drm_probe_helper.c +1
-18@@ -199,8 +199,6 @@ drm_connector_detect(struct drm_connector *connector, bool force)* drm_mode_probed_add(). New modes start their life with status as OK. * Modes are added from a single source using the following priority order. * -* - debugfs 'override_edid' (used for testing only) -* - firmware EDID (drm_load_edid_firmware()) * - &drm_connector_helper_funcs.get_modes vfunc * - if the connector status is connector_status_connected, standard * VESA DMT modes up to 1024x768 are automatically added @@ -305,22 +303,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, goto prune; } -if (connector->override_edid) { -struct edid *edid = (struct edid *) connector->edid_blob_ptr->data; - - count =drm_add_edid_modes (connector, edid); -drm_edid_to_eld (connector, edid); - }else { -struct edid *edid =drm_load_edid_firmware (connector); -if (!IS_ERR_OR_NULL (edid)) { -drm_mode_connector_update_edid_property (connector, edid); - count =drm_add_edid_modes (connector, edid); -drm_edid_to_eld (connector, edid); -kfree (edid); - } -if (count ==0 ) - count = (*connector_funcs->get_modes)(connector); - } + count = (*connector_funcs->get_modes)(connector);if (count ==0 && connector->status == connector_status_connected) count =drm_add_modes_noedid (connector,1024 ,768 );Signature · 1 line
2.1.4
Signature · 6 lines
Ville Syrjälä Intel OTC _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 3/3] drm: handle override edid and firmware EDID at drm_do_get_edid() level
Quoted 9 lines · Ville Syrjälä
Quoted 5 lines · Jani Nikula
Handle debugfs override edid and firmware edid at the low level to transparently and completely replace the real edid. Previously, we practically only used the modes from the override EDID, and none of the other data. This also prevents actual EDID reads when the EDID is to be overridden, but retains the DDC probe.
Hmm. Isn't that a bad thing? If someone has broken DDC on their cable or somethign then the override EDID wouldn't be returned by
drm_get_edid().
Isn't this in line with how this currently works?
BR,
Jani.
Quoted 82 lines
Quoted 82 lines
FIXME: validate override edid, deduplicate firmware edid validation.
Signed-off-by Jani Nikula <[email protected]>--- drivers/gpu/drm/drm_edid.c | 15 +++++++++++++++ drivers/gpu/drm/drm_probe_helper.c | 19 +------------------ 2 files changed, 16 insertions(+), 18 deletions(-)drivers/gpu/drm/drm_edid.c +15
-0@@ -1309,6 +1309,10 @@ static void connector_bad_edid(struct drm_connector *connector,* level, drivers must make all reasonable efforts to expose it as an I2C * adapter and use drm_get_edid() instead of abusing this function. * +* The EDID may be overridden using debugfs override_edid or firmare EDID +* (drm_load_edid_firmware()), in this priority order. Having either of them +* bypasses actual EDID reads. +* * Return: Pointer to valid EDID or NULL if we couldn't find any. */ struct edid *drm_do_get_edid(struct drm_connector *connector,@@ -1318,6 +1322,17 @@ struct edid *drm_do_get_edid(struct drm_connector *connector, {int i, j =0 , valid_extensions =0 ;u8 *edid, *new; +struct edid *override =NULL ; + +if (connector->override_edid) + override =drm_edid_duplicate ((const struct edid *) + connector->edid_blob_ptr->data); + +if (!override) + override =drm_load_edid_firmware (connector); + +if (!IS_ERR_OR_NULL (override)) +return override;if ((edid =kmalloc (EDID_LENGTH ,GFP_KERNEL )) ==NULL )return NULL ;drivers/gpu/drm/drm_probe_helper.c +1
-18@@ -199,8 +199,6 @@ drm_connector_detect(struct drm_connector *connector, bool force)* drm_mode_probed_add(). New modes start their life with status as OK. * Modes are added from a single source using the following priority order. * -* - debugfs 'override_edid' (used for testing only) -* - firmware EDID (drm_load_edid_firmware()) * - &drm_connector_helper_funcs.get_modes vfunc * - if the connector status is connector_status_connected, standard * VESA DMT modes up to 1024x768 are automatically added @@ -305,22 +303,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, goto prune; } -if (connector->override_edid) { -struct edid *edid = (struct edid *) connector->edid_blob_ptr->data; - - count =drm_add_edid_modes (connector, edid); -drm_edid_to_eld (connector, edid); - }else { -struct edid *edid =drm_load_edid_firmware (connector); -if (!IS_ERR_OR_NULL (edid)) { -drm_mode_connector_update_edid_property (connector, edid); - count =drm_add_edid_modes (connector, edid); -drm_edid_to_eld (connector, edid); -kfree (edid); - } -if (count ==0 ) - count = (*connector_funcs->get_modes)(connector); - } + count = (*connector_funcs->get_modes)(connector);if (count ==0 && connector->status == connector_status_connected) count =drm_add_modes_noedid (connector,1024 ,768 );Signature · 1 line
2.1.4
Signature · 5 lines
Jani Nikula, Intel Open Source Technology Center _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 3/3] drm: handle override edid and firmware EDID at drm_do_get_edid() level
Quoted 8 lines · Jani Nikula
Quoted 7 lines · Ville Syrjälä
Quoted 5 lines · Jani Nikula
Handle debugfs override edid and firmware edid at the low level to transparently and completely replace the real edid. Previously, we practically only used the modes from the override EDID, and none of the other data. This also prevents actual EDID reads when the EDID is to be overridden, but retains the DDC probe.
Quoted 4 lines
Quoted 2 lines
Hmm. Isn't that a bad thing? If someone has broken DDC on their cable or somethign then the override EDID wouldn't be returned by
drm_get_edid().Isn't this in line with how this currently works?
Not really. If connector->force is used and an override EDID is provided, then drm_get_edid() likely never gets called, and the modes come directly from the overide EDID. With your change forcing the connector state wouldn't because we still wouldn't get any modes from the override EDID due to the DDC check.
I guess one way around this would be to skip the DDC check if the connector state has been forced.
Quoted 90 lines
BR,
Jani.Quoted 82 lines
Quoted 82 lines
FIXME: validate override edid, deduplicate firmware edid validation.
Signed-off-by Jani Nikula <[email protected]>--- drivers/gpu/drm/drm_edid.c | 15 +++++++++++++++ drivers/gpu/drm/drm_probe_helper.c | 19 +------------------ 2 files changed, 16 insertions(+), 18 deletions(-)drivers/gpu/drm/drm_edid.c +15
-0@@ -1309,6 +1309,10 @@ static void connector_bad_edid(struct drm_connector *connector,* level, drivers must make all reasonable efforts to expose it as an I2C * adapter and use drm_get_edid() instead of abusing this function. * +* The EDID may be overridden using debugfs override_edid or firmare EDID +* (drm_load_edid_firmware()), in this priority order. Having either of them +* bypasses actual EDID reads. +* * Return: Pointer to valid EDID or NULL if we couldn't find any. */ struct edid *drm_do_get_edid(struct drm_connector *connector,@@ -1318,6 +1322,17 @@ struct edid *drm_do_get_edid(struct drm_connector *connector, {int i, j =0 , valid_extensions =0 ;u8 *edid, *new; +struct edid *override =NULL ; + +if (connector->override_edid) + override =drm_edid_duplicate ((const struct edid *) + connector->edid_blob_ptr->data); + +if (!override) + override =drm_load_edid_firmware (connector); + +if (!IS_ERR_OR_NULL (override)) +return override;if ((edid =kmalloc (EDID_LENGTH ,GFP_KERNEL )) ==NULL )return NULL ;drivers/gpu/drm/drm_probe_helper.c +1
-18@@ -199,8 +199,6 @@ drm_connector_detect(struct drm_connector *connector, bool force)* drm_mode_probed_add(). New modes start their life with status as OK. * Modes are added from a single source using the following priority order. * -* - debugfs 'override_edid' (used for testing only) -* - firmware EDID (drm_load_edid_firmware()) * - &drm_connector_helper_funcs.get_modes vfunc * - if the connector status is connector_status_connected, standard * VESA DMT modes up to 1024x768 are automatically added @@ -305,22 +303,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, goto prune; } -if (connector->override_edid) { -struct edid *edid = (struct edid *) connector->edid_blob_ptr->data; - - count =drm_add_edid_modes (connector, edid); -drm_edid_to_eld (connector, edid); - }else { -struct edid *edid =drm_load_edid_firmware (connector); -if (!IS_ERR_OR_NULL (edid)) { -drm_mode_connector_update_edid_property (connector, edid); - count =drm_add_edid_modes (connector, edid); -drm_edid_to_eld (connector, edid); -kfree (edid); - } -if (count ==0 ) - count = (*connector_funcs->get_modes)(connector); - } + count = (*connector_funcs->get_modes)(connector);if (count ==0 && connector->status == connector_status_connected) count =drm_add_modes_noedid (connector,1024 ,768 );Signature · 1 line
2.1.4Signature · 1 line
Jani Nikula, Intel Open Source Technology Center
Signature · 6 lines
Ville Syrjälä Intel OTC _______________________________________________ Intel-gfx mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [PATCH 3/3] drm: handle override edid and firmware EDID at drm_do_get_edid() level
Quoted 12 lines · Ville Syrjälä
Quoted 11 lines · Jani Nikula
Quoted 9 lines · Ville Syrjälä
Quoted 5 lines · Jani Nikula
Handle debugfs override edid and firmware edid at the low level to transparently and completely replace the real edid. Previously, we practically only used the modes from the override EDID, and none of the other data. This also prevents actual EDID reads when the EDID is to be overridden, but retains the DDC probe.
Hmm. Isn't that a bad thing? If someone has broken DDC on their cable or somethign then the override EDID wouldn't be returned by
drm_get_edid().
Quoted 7 lines
Quoted 1 line
Isn't this in line with how this currently works?
Not really. If
connector->forceis used and an override EDID is provided, thendrm_get_edid()likely never gets called, and the modes come directly from the overide EDID. With your change forcing the connector state wouldn't because we still wouldn't get any modes from the override EDID due to the DDC check.
Right.
Quoted 2 lines
I guess one way around this would be to skip the DDC check if the connector state has been forced.
I guess I'm asking if you think the whole approach here is workable. What we currently have is so flaky.
BR,
Jani.
Quoted 91 lines
Quoted 91 lines
BR,
Jani.Quoted 82 lines
Quoted 82 lines
FIXME: validate override edid, deduplicate firmware edid validation.
Signed-off-by Jani Nikula <[email protected]>--- drivers/gpu/drm/drm_edid.c | 15 +++++++++++++++ drivers/gpu/drm/drm_probe_helper.c | 19 +------------------ 2 files changed, 16 insertions(+), 18 deletions(-)drivers/gpu/drm/drm_edid.c +15
-0@@ -1309,6 +1309,10 @@ static void connector_bad_edid(struct drm_connector *connector,* level, drivers must make all reasonable efforts to expose it as an I2C * adapter and use drm_get_edid() instead of abusing this function. * +* The EDID may be overridden using debugfs override_edid or firmare EDID +* (drm_load_edid_firmware()), in this priority order. Having either of them +* bypasses actual EDID reads. +* * Return: Pointer to valid EDID or NULL if we couldn't find any. */ struct edid *drm_do_get_edid(struct drm_connector *connector,@@ -1318,6 +1322,17 @@ struct edid *drm_do_get_edid(struct drm_connector *connector, {int i, j =0 , valid_extensions =0 ;u8 *edid, *new; +struct edid *override =NULL ; + +if (connector->override_edid) + override =drm_edid_duplicate ((const struct edid *) + connector->edid_blob_ptr->data); + +if (!override) + override =drm_load_edid_firmware (connector); + +if (!IS_ERR_OR_NULL (override)) +return override;if ((edid =kmalloc (EDID_LENGTH ,GFP_KERNEL )) ==NULL )return NULL ;drivers/gpu/drm/drm_probe_helper.c +1
-18@@ -199,8 +199,6 @@ drm_connector_detect(struct drm_connector *connector, bool force)* drm_mode_probed_add(). New modes start their life with status as OK. * Modes are added from a single source using the following priority order. * -* - debugfs 'override_edid' (used for testing only) -* - firmware EDID (drm_load_edid_firmware()) * - &drm_connector_helper_funcs.get_modes vfunc * - if the connector status is connector_status_connected, standard * VESA DMT modes up to 1024x768 are automatically added @@ -305,22 +303,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, goto prune; } -if (connector->override_edid) { -struct edid *edid = (struct edid *) connector->edid_blob_ptr->data; - - count =drm_add_edid_modes (connector, edid); -drm_edid_to_eld (connector, edid); - }else { -struct edid *edid =drm_load_edid_firmware (connector); -if (!IS_ERR_OR_NULL (edid)) { -drm_mode_connector_update_edid_property (connector, edid); - count =drm_add_edid_modes (connector, edid); -drm_edid_to_eld (connector, edid); -kfree (edid); - } -if (count ==0 ) - count = (*connector_funcs->get_modes)(connector); - } + count = (*connector_funcs->get_modes)(connector);if (count ==0 && connector->status == connector_status_connected) count =drm_add_modes_noedid (connector,1024 ,768 );Signature · 1 line
2.1.4Signature · 1 line
Jani Nikula, Intel Open Source Technology Center
Signature · 5 lines
Jani Nikula, Intel Open Source Technology Center _______________________________________________ Intel-gfx mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [PATCH 3/3] drm: handle override edid and firmware EDID at drm_do_get_edid() level
Quoted 21 lines · Jani Nikula
Quoted 12 lines · Ville Syrjälä
Quoted 11 lines · Jani Nikula
Quoted 9 lines · Ville Syrjälä
Quoted 5 lines · Jani Nikula
Handle debugfs override edid and firmware edid at the low level to transparently and completely replace the real edid. Previously, we practically only used the modes from the override EDID, and none of the other data. This also prevents actual EDID reads when the EDID is to be overridden, but retains the DDC probe.
Hmm. Isn't that a bad thing? If someone has broken DDC on their cable or somethign then the override EDID wouldn't be returned by
drm_get_edid().Quoted 7 lines
Quoted 1 line
Isn't this in line with how this currently works?
Not really. If
connector->forceis used and an override EDID is provided, thendrm_get_edid()likely never gets called, and the modes come directly from the overide EDID. With your change forcing the connector state wouldn't because we still wouldn't get any modes from the override EDID due to the DDC check.
Quoted 7 lines
Right.
Quoted 2 lines
I guess one way around this would be to skip the DDC check if the connector state has been forced.
I guess I'm asking if you think the whole approach here is workable. What we currently have is so flaky.
I'm 100% with you on that. So yes, I do like the idea.
I think the last time the override EDIDs were discussed someone was suggesting that the EDID override itself should force the connector state. IIRC Daniel didn't agree. I don't have a particularly strong opinion either way, but I guess trying to preserve the current semantics (ie. EDID override and connector status forcing are mostly separate) would be the thing to aim for, at least initially.
Quoted 98 lines
BR,
Jani.Quoted 91 lines
Quoted 91 lines
BR,
Jani.Quoted 82 lines
Quoted 82 lines
FIXME: validate override edid, deduplicate firmware edid validation.
Signed-off-by Jani Nikula <[email protected]>--- drivers/gpu/drm/drm_edid.c | 15 +++++++++++++++ drivers/gpu/drm/drm_probe_helper.c | 19 +------------------ 2 files changed, 16 insertions(+), 18 deletions(-)drivers/gpu/drm/drm_edid.c +15
-0@@ -1309,6 +1309,10 @@ static void connector_bad_edid(struct drm_connector *connector,* level, drivers must make all reasonable efforts to expose it as an I2C * adapter and use drm_get_edid() instead of abusing this function. * +* The EDID may be overridden using debugfs override_edid or firmare EDID +* (drm_load_edid_firmware()), in this priority order. Having either of them +* bypasses actual EDID reads. +* * Return: Pointer to valid EDID or NULL if we couldn't find any. */ struct edid *drm_do_get_edid(struct drm_connector *connector,@@ -1318,6 +1322,17 @@ struct edid *drm_do_get_edid(struct drm_connector *connector, {int i, j =0 , valid_extensions =0 ;u8 *edid, *new; +struct edid *override =NULL ; + +if (connector->override_edid) + override =drm_edid_duplicate ((const struct edid *) + connector->edid_blob_ptr->data); + +if (!override) + override =drm_load_edid_firmware (connector); + +if (!IS_ERR_OR_NULL (override)) +return override;if ((edid =kmalloc (EDID_LENGTH ,GFP_KERNEL )) ==NULL )return NULL ;drivers/gpu/drm/drm_probe_helper.c +1
-18@@ -199,8 +199,6 @@ drm_connector_detect(struct drm_connector *connector, bool force)* drm_mode_probed_add(). New modes start their life with status as OK. * Modes are added from a single source using the following priority order. * -* - debugfs 'override_edid' (used for testing only) -* - firmware EDID (drm_load_edid_firmware()) * - &drm_connector_helper_funcs.get_modes vfunc * - if the connector status is connector_status_connected, standard * VESA DMT modes up to 1024x768 are automatically added @@ -305,22 +303,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, goto prune; } -if (connector->override_edid) { -struct edid *edid = (struct edid *) connector->edid_blob_ptr->data; - - count =drm_add_edid_modes (connector, edid); -drm_edid_to_eld (connector, edid); - }else { -struct edid *edid =drm_load_edid_firmware (connector); -if (!IS_ERR_OR_NULL (edid)) { -drm_mode_connector_update_edid_property (connector, edid); - count =drm_add_edid_modes (connector, edid); -drm_edid_to_eld (connector, edid); -kfree (edid); - } -if (count ==0 ) - count = (*connector_funcs->get_modes)(connector); - } + count = (*connector_funcs->get_modes)(connector);if (count ==0 && connector->status == connector_status_connected) count =drm_add_modes_noedid (connector,1024 ,768 );Signature · 1 line
2.1.4Signature · 1 line
Jani Nikula, Intel Open Source Technology CenterSignature · 1 line
Jani Nikula, Intel Open Source Technology Center
Signature · 6 lines
Ville Syrjälä Intel OTC _______________________________________________ Intel-gfx mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [PATCH 2/3] drm: reset ELD if NULL edid is passed to drm_edid_to_eld
In reply to Ville SyrjäläQuoted 16 lines · Ville Syrjälä
Quoted 15 lines · Jani Nikula
Make the function useful for resetting, not just setting, the ELD.
Signed-off-by Jani Nikula <[email protected]>--- drivers/gpu/drm/drm_edid.c | 3 +++ 1 file changed, 3 insertions(+)drivers/gpu/drm/drm_edid.c +0
-0@@ -3430,6 +3430,9 @@ void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid)memset (eld,0 ,sizeof (connector->eld));
Quoted 8 lines
drivers/gpu/drm/drm_edid.c void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid) · line 3438
Quoted 6 lines
drivers/gpu/drm/drm_edid.c +3
-0+if (!edid) +return ; + connector->latency_present[0 ] = false; connector->latency_present[1 ] = false; connector->video_latency[0 ] =0 ;/me thinks the check should be after all these.
D'oh!
Quoted 2 lines
Hmm. Actually the cea ext block check below should be safe wrt. edid==NULL, so not sure we need this at all.
I'd just like to be explicit and avoid the debug message on missing CEA extensions if the whole EDID is missing.
BR,
Jani.
Signature · 5 lines
Jani Nikula, Intel Open Source Technology Center _______________________________________________ Intel-gfx mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [PATCH 2/3] drm: reset ELD if NULL edid is passed to drm_edid_to_eld
Quoted 26 lines · Jani Nikula
Quoted 16 lines · Ville Syrjälä
Quoted 15 lines · Jani Nikula
Make the function useful for resetting, not just setting, the ELD.
Signed-off-by Jani Nikula <[email protected]>--- drivers/gpu/drm/drm_edid.c | 3 +++ 1 file changed, 3 insertions(+)drivers/gpu/drm/drm_edid.c +0
-0@@ -3430,6 +3430,9 @@ void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid)memset (eld,0 ,sizeof (connector->eld));Quoted 8 lines
drivers/gpu/drm/drm_edid.c void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid) · line 3438
Quoted 6 lines
drivers/gpu/drm/drm_edid.c +3
-0+if (!edid) +return ; + connector->latency_present[0 ] = false; connector->latency_present[1 ] = false; connector->video_latency[0 ] =0 ;/me thinks the check should be after all these.
Quoted 7 lines
D'oh!
Quoted 2 lines
Hmm. Actually the cea ext block check below should be safe wrt. edid==NULL, so not sure we need this at all.
I'd just like to be explicit and avoid the debug message on missing CEA extensions if the whole EDID is missing.
Fair enough.
Signature · 6 lines
Ville Syrjälä Intel OTC _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 3/3] drm: handle override edid and firmware EDID at drm_do_get_edid() level
In reply to Ville SyrjäläQuoted 30 lines · Ville Syrjälä
Quoted 21 lines · Jani Nikula
Quoted 12 lines · Ville Syrjälä
Quoted 11 lines · Jani Nikula
Quoted 9 lines · Ville Syrjälä
Quoted 5 lines · Jani Nikula
Handle debugfs override edid and firmware edid at the low level to transparently and completely replace the real edid. Previously, we practically only used the modes from the override EDID, and none of the other data. This also prevents actual EDID reads when the EDID is to be overridden, but retains the DDC probe.
Hmm. Isn't that a bad thing? If someone has broken DDC on their cable or somethign then the override EDID wouldn't be returned by
drm_get_edid().Quoted 7 lines
Quoted 1 line
Isn't this in line with how this currently works?
Not really. If
connector->forceis used and an override EDID is provided, thendrm_get_edid()likely never gets called, and the modes come directly from the overide EDID. With your change forcing the connector state wouldn't because we still wouldn't get any modes from the override EDID due to the DDC check.Quoted 7 lines
Right.
Quoted 2 lines
I guess one way around this would be to skip the DDC check if the connector state has been forced.
I guess I'm asking if you think the whole approach here is workable. What we currently have is so flaky.
Quoted 8 lines
I'm 100% with you on that. So yes, I do like the idea.
I think the last time the override EDIDs were discussed someone was suggesting that the EDID override itself should force the connector state. IIRC Daniel didn't agree. I don't have a particularly strong opinion either way, but I guess trying to preserve the current semantics (ie. EDID override and connector status forcing are mostly separate) would be the thing to aim for, at least initially.
Iirc I just said (well, I hope that's what I said, didn't check with past self) that the current semantics we expose work like that. They might not be sensible.
But anyway, I guess we need to tackle both the override edid and the connector status forcing in one patch approach, and I guess doing it here in drm_do_get_edid is indeed sensible. And if we can get away with it, deriving the force state from the override edid (if present), but not the other way round, would be good. Or at least the dvi-d vs. dvi-i part of connector forcing (which isn't something we use on i915, but which exists).
-Daniel
Quoted 103 lines
Quoted 99 lines
BR,
Jani.Quoted 91 lines
Quoted 91 lines
BR,
Jani.Quoted 82 lines
Quoted 82 lines
FIXME: validate override edid, deduplicate firmware edid validation.
Signed-off-by Jani Nikula <[email protected]>--- drivers/gpu/drm/drm_edid.c | 15 +++++++++++++++ drivers/gpu/drm/drm_probe_helper.c | 19 +------------------ 2 files changed, 16 insertions(+), 18 deletions(-)drivers/gpu/drm/drm_edid.c +15
-0@@ -1309,6 +1309,10 @@ static void connector_bad_edid(struct drm_connector *connector,* level, drivers must make all reasonable efforts to expose it as an I2C * adapter and use drm_get_edid() instead of abusing this function. * +* The EDID may be overridden using debugfs override_edid or firmare EDID +* (drm_load_edid_firmware()), in this priority order. Having either of them +* bypasses actual EDID reads. +* * Return: Pointer to valid EDID or NULL if we couldn't find any. */ struct edid *drm_do_get_edid(struct drm_connector *connector,@@ -1318,6 +1322,17 @@ struct edid *drm_do_get_edid(struct drm_connector *connector, {int i, j =0 , valid_extensions =0 ;u8 *edid, *new; +struct edid *override =NULL ; + +if (connector->override_edid) + override =drm_edid_duplicate ((const struct edid *) + connector->edid_blob_ptr->data); + +if (!override) + override =drm_load_edid_firmware (connector); + +if (!IS_ERR_OR_NULL (override)) +return override;if ((edid =kmalloc (EDID_LENGTH ,GFP_KERNEL )) ==NULL )return NULL ;drivers/gpu/drm/drm_probe_helper.c +1
-18@@ -199,8 +199,6 @@ drm_connector_detect(struct drm_connector *connector, bool force)* drm_mode_probed_add(). New modes start their life with status as OK. * Modes are added from a single source using the following priority order. * -* - debugfs 'override_edid' (used for testing only) -* - firmware EDID (drm_load_edid_firmware()) * - &drm_connector_helper_funcs.get_modes vfunc * - if the connector status is connector_status_connected, standard * VESA DMT modes up to 1024x768 are automatically added @@ -305,22 +303,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, goto prune; } -if (connector->override_edid) { -struct edid *edid = (struct edid *) connector->edid_blob_ptr->data; - - count =drm_add_edid_modes (connector, edid); -drm_edid_to_eld (connector, edid); - }else { -struct edid *edid =drm_load_edid_firmware (connector); -if (!IS_ERR_OR_NULL (edid)) { -drm_mode_connector_update_edid_property (connector, edid); - count =drm_add_edid_modes (connector, edid); -drm_edid_to_eld (connector, edid); -kfree (edid); - } -if (count ==0 ) - count = (*connector_funcs->get_modes)(connector); - } + count = (*connector_funcs->get_modes)(connector);if (count ==0 && connector->status == connector_status_connected) count =drm_add_modes_noedid (connector,1024 ,768 );Signature · 1 line
2.1.4Signature · 1 line
Jani Nikula, Intel Open Source Technology CenterSignature · 1 line
Jani Nikula, Intel Open Source Technology CenterSignature · 2 lines
Ville Syrjälä Intel OTC
Signature · 7 lines
Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch _______________________________________________ Intel-gfx mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/intel-gfx