public inbox for intel-gfx@lists.freedesktop.org
 help / color / mirror / Atom feed
From: Todd Previte <tprevite@gmail.com>
To: Paulo Zanoni <przanoni@gmail.com>
Cc: Intel Graphics Development <intel-gfx@lists.freedesktop.org>,
	DRI Development <dri-devel@lists.freedesktop.org>
Subject: Re: [PATCH 06/13] drm: Add supporting structure for Displayport Link CTS test 4.2.2.6
Date: Tue, 14 Apr 2015 23:56:25 -0700	[thread overview]
Message-ID: <552E0B99.8010604@gmail.com> (raw)
In-Reply-To: <CA+gsUGTTMTV6WbJ+L+8UDKLiuLiDh+j+XCN4mvn3K7gqLpXpCg@mail.gmail.com>



On 4/13/15 3:18 PM, Paulo Zanoni wrote:
> 2015-04-13 11:53 GMT-03:00 Todd Previte <tprevite@gmail.com>:
>> Displayport compliance test 4.2.2.6 requires that a source device be capable of
>> detecting a corrupt EDID. The test specification states that the sink device
>> sets up the EDID with an invalid checksum. To do this, the sink sets up an
>> invalid EDID header, expecting the source device to generate the checksum and
>> compare it to the value stored in the last byte of the block data.
>>
>> Unfortunately, the DRM EDID reading and parsing functions are actually too good
>> in this case; the header is fixed before the checksum is computed and thus the
>> code never sees the invalid checksum. This results in a failure to pass the
>> compliance test.
>>
>> To correct this issue, a checksum is generated when the EDID header is detected
>> as corrupted. If the checksum is invalid, it sets the header_corrupt flag and
>> logs the errors. In the case of a more seriously damaged header (fixup score
>> less than the threshold) the code does not generate the checksum but does set
>> the header_corrupt flag.
>>
>> V2:
>> - Removed the static bool global
>> - Added a bool to the drm_connector struct to reaplce the static one for
>>    holding the status of raw edid header corruption detection
>> - Modified the function signature of the is_valid function to take an
>>    additional parameter to store the corruption detected value
>> - Fixed the other callers of the above is_valid function
>> V3:
>> - Updated the commit message to be more clear about what and why this
>>    patch does what it does.
>> - Added comment in code to clarify the operations there
>> - Removed compliance variable and check_link_status update; those
>>    have been moved to a later patch
>> - Removed variable assignment from the bottom of the test handler
>> V4:
>> - Removed i915 tag from subject line as the patch is not i915-specific
>> V5:
>> - Moved code causing a compilation error to this patch where the variable
>>    is actually declared
>>
>> Signed-off-by: Todd Previte <tprevite@gmail.com>
>> Cc: dri-devel@lists.freedesktop.org
>> ---
>>   drivers/gpu/drm/drm_edid.c        | 31 ++++++++++++++++++++++++++-----
>>   drivers/gpu/drm/drm_edid_load.c   |  7 +++++--
>>   drivers/gpu/drm/i2c/tda998x_drv.c |  4 ++--
>>   drivers/gpu/drm/i915/intel_dp.c   |  2 +-
>>   include/drm/drm_crtc.h            |  8 +++++++-
>>   5 files changed, 41 insertions(+), 11 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
>> index 53bc7a6..12e5be7 100644
>> --- a/drivers/gpu/drm/drm_edid.c
>> +++ b/drivers/gpu/drm/drm_edid.c
>> @@ -1005,7 +1005,6 @@ int drm_edid_header_is_valid(const u8 *raw_edid)
>>          for (i = 0; i < sizeof(edid_header); i++)
>>                  if (raw_edid[i] == edid_header[i])
>>                          score++;
>> -
>>          return score;
>>   }
>>   EXPORT_SYMBOL(drm_edid_header_is_valid);
> Bad chunk...
Fixed
>
>> @@ -1047,7 +1046,8 @@ static bool drm_edid_is_zero(const u8 *in_edid, int length)
>>    *
>>    * Return: True if the block is valid, false otherwise.
>>    */
>> -bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid)
>> +bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid,
>> +                         bool *header_corrupt)
> Need to add the new parameter description to the documentation above.
Done.
>
>>   {
>>          u8 csum;
>>          struct edid *edid = (struct edid *)raw_edid;
>> @@ -1062,9 +1062,27 @@ bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid)
>>                  int score = drm_edid_header_is_valid(raw_edid);
>>                  if (score == 8) ;
>>                  else if (score >= edid_fixup) {
>> +                       /* Displayport Link CTS Core 1.2 rev1.1 test 4.2.2.6
>> +                        * In order to properly generate the invalid checksum
>> +                        * required for this test, it must be generated using
>> +                        * the raw EDID data. Otherwise, the fix-up code here
>> +                        * will correct the problem, the checksum is then correct
>> +                        * and the test fails
>> +                        */
>> +                       csum = drm_edid_block_checksum(raw_edid);
>> +                       if (csum) {
>> +                               DRM_DEBUG_DRIVER("Invalid EDID header, score = %d\n", score);
>> +                               DRM_DEBUG_DRIVER("Invalid EDID checksum %d\n", csum);
> No one on this file uses DRM_DEBUG_DRIVER (you use 2 calls here and one below).
>
> Also, during "normal operation" we try to calculate the checksum based
> on the fixed EDID header, so if we also print these messages here
> we're always going to have a message complaining about invalid
> checksum: either this one or the other that's already there. My
> bikeshed would be to just remove the messages you added here and below
> to not confuse users. Let's assume that the bad header is due to some
> communication/corruption error, and the HW manufacturers did not
> program an EDID with a bad header and a correct checksum based on bad
> header :)
Works for me. Messages have been removed.
>
>> +                               if (header_corrupt)
>> +                                       *header_corrupt = 1;
>> +                       }
>>                          DRM_DEBUG("Fixing EDID header, your hardware may be failing\n");
>>                          memcpy(raw_edid, edid_header, sizeof(edid_header));
>>                  } else {
>> +                       if (header_corrupt) {
>> +                               DRM_DEBUG_DRIVER("Invalid EDID header\n");
>> +                               *header_corrupt = 1;
>> +                       }
> We don't ever set header_corrupt back to false, so if we ever get a
> corrupt header once, the header_corrupt flag will stay there even if
> it gets fixed somehow (such as a DP compliance tester starting to
> submit the correct header).
This is fixed as well. The flag now is reset to 0 at the end of the test 
handler.
>
>>                          goto bad;
>>                  }
>>          }
>> @@ -1129,7 +1147,7 @@ bool drm_edid_is_valid(struct edid *edid)
>>                  return false;
>>
>>          for (i = 0; i <= edid->extensions; i++)
>> -               if (!drm_edid_block_valid(raw + i * EDID_LENGTH, i, true))
>> +               if (!drm_edid_block_valid(raw + i * EDID_LENGTH, i, true, NULL))
>>                          return false;
>>
>>          return true;
>> @@ -1232,7 +1250,8 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
>>          for (i = 0; i < 4; i++) {
>>                  if (get_edid_block(data, block, 0, EDID_LENGTH))
>>                          goto out;
>> -               if (drm_edid_block_valid(block, 0, print_bad_edid))
>> +               if (drm_edid_block_valid(block, 0, print_bad_edid,
>> +                                        &connector->edid_header_corrupt))
>>                          break;
>>                  if (i == 0 && drm_edid_is_zero(block, EDID_LENGTH)) {
>>                          connector->null_edid_counter++;
>> @@ -1257,7 +1276,9 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
>>                                    block + (valid_extensions + 1) * EDID_LENGTH,
>>                                    j, EDID_LENGTH))
>>                                  goto out;
>> -                       if (drm_edid_block_valid(block + (valid_extensions + 1) * EDID_LENGTH, j, print_bad_edid)) {
>> +                       if (drm_edid_block_valid(block + (valid_extensions + 1) * EDID_LENGTH, j,
>> +                                                print_bad_edid,
>> +                                                &connector->edid_header_corrupt)) {
> You can use NULL here since we're not handling block 0 anymore.
Fixed.
>
>>                                  valid_extensions++;
>>                                  break;
>>                          }
>> diff --git a/drivers/gpu/drm/drm_edid_load.c b/drivers/gpu/drm/drm_edid_load.c
>> index 732cb6f..1505494 100644
>> --- a/drivers/gpu/drm/drm_edid_load.c
>> +++ b/drivers/gpu/drm/drm_edid_load.c
>> @@ -216,7 +216,8 @@ static void *edid_load(struct drm_connector *connector, const char *name,
>>                  goto out;
>>          }
>>
>> -       if (!drm_edid_block_valid(edid, 0, print_bad_edid)) {
>> +       if (!drm_edid_block_valid(edid, 0, print_bad_edid,
>> +                                 &connector->edid_header_corrupt)) {
>>                  connector->bad_edid_counter++;
>>                  DRM_ERROR("Base block of EDID firmware \"%s\" is invalid ",
>>                      name);
>> @@ -229,7 +230,9 @@ static void *edid_load(struct drm_connector *connector, const char *name,
>>                  if (i != valid_extensions + 1)
>>                          memcpy(edid + (valid_extensions + 1) * EDID_LENGTH,
>>                              edid + i * EDID_LENGTH, EDID_LENGTH);
>> -               if (drm_edid_block_valid(edid + i * EDID_LENGTH, i, print_bad_edid))
>> +               if (drm_edid_block_valid(edid + i * EDID_LENGTH, i,
>> +                                        print_bad_edid,
>> +                                        &connector->edid_header_corrupt))
> Same here: not iterating over block 0.
Fixed
> Btw, why can't we just use NULL on edid_load?
I think it's at too high level again and the fix up code will get in the 
way.
>
>>                          valid_extensions++;
>>          }
>>
>> diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
>> index a9041d1..9c3d6b3 100644
>> --- a/drivers/gpu/drm/i2c/tda998x_drv.c
>> +++ b/drivers/gpu/drm/i2c/tda998x_drv.c
>> @@ -1106,7 +1106,7 @@ static uint8_t *do_get_edid(struct tda998x_priv *priv)
>>          if (read_edid_block(priv, block, 0))
>>                  goto fail;
>>
>> -       if (!drm_edid_block_valid(block, 0, print_bad_edid))
>> +       if (!drm_edid_block_valid(block, 0, print_bad_edid, NULL))
>>                  goto fail;
>>
>>          /* if there's no extensions, we're done */
>> @@ -1123,7 +1123,7 @@ static uint8_t *do_get_edid(struct tda998x_priv *priv)
>>                  if (read_edid_block(priv, ext_block, j))
>>                          goto fail;
>>
>> -               if (!drm_edid_block_valid(ext_block, j, print_bad_edid))
>> +               if (!drm_edid_block_valid(ext_block, j, print_bad_edid, NULL))
>>                          goto fail;
>>
>>                  valid_extensions++;
>> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
>> index e1d6e79..77b6b15 100644
>> --- a/drivers/gpu/drm/i915/intel_dp.c
>> +++ b/drivers/gpu/drm/i915/intel_dp.c
>> @@ -3922,7 +3922,7 @@ intel_dp_check_link_status(struct intel_dp *intel_dp)
>>           * 4.2.2.1 - EDID read required for all HPD events
>>            */
>>           edid_read = drm_get_edid(connector, adapter);
>> -        if (!edid_read) {
>> +        if (!edid_read || connector->edid_header_corrupt == 1) {
>>                   DRM_DEBUG_DRIVER("Invalid EDID detected\n");
>>           }
>>
>> diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
>> index 0261417..e31a4b3 100644
>> --- a/include/drm/drm_crtc.h
>> +++ b/include/drm/drm_crtc.h
>> @@ -719,6 +719,11 @@ struct drm_connector {
>>          int null_edid_counter; /* needed to workaround some HW bugs where we get all 0s */
>>          unsigned bad_edid_counter;
>>
>> +       /* Flag for raw EDID header corruption - used in Displayport compliance testing
>> +        * Displayport Link CTS Core 1.2 rev1.1 4.2.2.6
>> +        */
>> +       bool edid_header_corrupt;
>> +
>>          struct dentry *debugfs_entry;
>>
>>          struct drm_connector_state *state;
>> @@ -1436,7 +1441,8 @@ extern void drm_set_preferred_mode(struct drm_connector *connector,
>>                                     int hpref, int vpref);
>>
>>   extern int drm_edid_header_is_valid(const u8 *raw_edid);
>> -extern bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid);
>> +extern bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid, bool *header_corrupt);
>> +
>>   extern bool drm_edid_is_valid(struct edid *edid);
>>
>>   extern struct drm_tile_group *drm_mode_create_tile_group(struct drm_device *dev,
>> --
>> 1.9.1
>>
>> _______________________________________________
>> dri-devel mailing list
>> dri-devel@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/dri-devel
>
>

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

  reply	other threads:[~2015-04-15  6:56 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-04-10 16:12 [intel-gfx][PATCH V5] Displayport compliance testing V5 Todd Previte
2015-04-10 16:12 ` [PATCH 01/11] drm/i915: Add automated testing support for Displayport compliance testing Todd Previte
2015-04-13 17:30   ` Paulo Zanoni
2015-04-10 16:12 ` [PATCH 02/11] drm/i915: Ignore disconnected Displayport connectors in check_link_status Todd Previte
2015-04-10 16:12 ` [PATCH 03/11] drm/i915: Move the DPCD read further up in intel_dp_check_link_status() Todd Previte
2015-04-14 17:48   ` Todd Previte
2015-04-10 16:12 ` [PATCH 04/11] drm/i915: Add EDID read in intel_dp_check_link_status() for Link CTS 4.2.2.1 Todd Previte
2015-04-13 14:10   ` Paulo Zanoni
2015-04-13 14:57     ` Todd Previte
2015-04-13 14:53   ` [PATCH 04/13] " Todd Previte
2015-04-14 16:53     ` Paulo Zanoni
2015-04-15  8:48       ` Daniel Vetter
2015-04-15 15:37       ` Todd Previte
2015-04-15 17:42         ` Paulo Zanoni
2015-04-16 15:41           ` Todd Previte
2015-04-16 16:31             ` Daniel Vetter
2015-04-16 17:32               ` Todd Previte
2015-04-20  5:10               ` Todd Previte
2015-04-10 16:12 ` [PATCH 05/11] drm/i915: Add a delay in Displayport AUX transactions for compliance testing Todd Previte
2015-04-13 21:05   ` Paulo Zanoni
2015-04-10 16:12 ` [PATCH 06/11] drm/i915: Add supporting structure for Displayport Link CTS test 4.2.2.6 Todd Previte
2015-04-10 17:38   ` [PATCH 06/13] drm: " Todd Previte
2015-04-10 17:45   ` [PATCH 06/11] drm/i915: " Emil Velikov
2015-04-10 17:38     ` Todd Previte
2015-04-13 14:53   ` [PATCH 06/13] drm: " Todd Previte
2015-04-13 22:18     ` Paulo Zanoni
2015-04-15  6:56       ` Todd Previte [this message]
2015-04-10 16:12 ` [PATCH 07/11] drm/i915: Update intel_dp_hpd_pulse() for non-MST operation Todd Previte
2015-04-14 11:29   ` Paulo Zanoni
2015-04-14 17:36     ` Todd Previte
2015-04-14 19:00       ` Paulo Zanoni
2015-04-15  2:00         ` Todd Previte
2015-04-10 16:12 ` [PATCH 08/11] drm/i915: Support EDID compliance tests with the intel_dp_autotest_edid() function Todd Previte
2015-04-10 17:42   ` [PATCH 08/13] " Todd Previte
2015-04-14 13:35     ` Paulo Zanoni
2015-04-14 17:42       ` Todd Previte
2015-04-10 16:12 ` [PATCH 09/11] drm/i915: Fix for DP CTS test 4.2.2.5 - I2C DEFER handling Todd Previte
2015-04-10 17:41   ` [PATCH 09/13] drm: " Todd Previte
2015-04-10 16:12 ` [PATCH 10/11] drm/i915: Add debugfs test control files for Displayport compliance testing Todd Previte
2015-04-10 16:12 ` [PATCH 11/11] drm: Fix the 'native defer' message in drm_dp_i2c_do_msg() Todd Previte
2015-04-10 16:18   ` Alex Deucher

Reply instructions:

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

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

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

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

  git send-email \
    --in-reply-to=552E0B99.8010604@gmail.com \
    --to=tprevite@gmail.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=przanoni@gmail.com \
    /path/to/YOUR_REPLY

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

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