Skip to content

Commit

Permalink
drm/edid: limit printk when facing bad edid
Browse files Browse the repository at this point in the history
Limit printing bad edid information at one time per connector.
Connector that are connected to a bad monitor/kvm will likely
stay connected to the same bad monitor/kvm and it makes no
sense to keep printing the bad edid message.

Signed-off-by: Jerome Glisse <jglisse@redhat.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
  • Loading branch information
Jerome Glisse authored and Dave Airlie committed Sep 17, 2012
1 parent 09e7dcf commit 0b2443e
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 11 deletions.
22 changes: 14 additions & 8 deletions drivers/gpu/drm/drm_edid.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ MODULE_PARM_DESC(edid_fixup,
* Sanity check the EDID block (base or extension). Return 0 if the block
* doesn't check out, or 1 if it's valid.
*/
bool drm_edid_block_valid(u8 *raw_edid, int block)
bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid)
{
int i;
u8 csum = 0;
Expand All @@ -181,7 +181,9 @@ bool drm_edid_block_valid(u8 *raw_edid, int block)
for (i = 0; i < EDID_LENGTH; i++)
csum += raw_edid[i];
if (csum) {
DRM_ERROR("EDID checksum is invalid, remainder is %d\n", csum);
if (print_bad_edid) {
DRM_ERROR("EDID checksum is invalid, remainder is %d\n", csum);
}

/* allow CEA to slide through, switches mangle this */
if (raw_edid[0] != 0x02)
Expand All @@ -207,7 +209,7 @@ bool drm_edid_block_valid(u8 *raw_edid, int block)
return 1;

bad:
if (raw_edid) {
if (raw_edid && print_bad_edid) {
printk(KERN_ERR "Raw EDID:\n");
print_hex_dump(KERN_ERR, " \t", DUMP_PREFIX_NONE, 16, 1,
raw_edid, EDID_LENGTH, false);
Expand All @@ -231,7 +233,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))
if (!drm_edid_block_valid(raw + i * EDID_LENGTH, i, true))
return false;

return true;
Expand Down Expand Up @@ -316,6 +318,7 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)
{
int i, j = 0, valid_extensions = 0;
u8 *block, *new;
bool print_bad_edid = !connector->bad_edid_counter || (drm_debug & DRM_UT_KMS);

if ((block = kmalloc(EDID_LENGTH, GFP_KERNEL)) == NULL)
return NULL;
Expand All @@ -324,7 +327,7 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)
for (i = 0; i < 4; i++) {
if (drm_do_probe_ddc_edid(adapter, block, 0, EDID_LENGTH))
goto out;
if (drm_edid_block_valid(block, 0))
if (drm_edid_block_valid(block, 0, print_bad_edid))
break;
if (i == 0 && drm_edid_is_zero(block, EDID_LENGTH)) {
connector->null_edid_counter++;
Expand All @@ -349,7 +352,7 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)
block + (valid_extensions + 1) * EDID_LENGTH,
j, EDID_LENGTH))
goto out;
if (drm_edid_block_valid(block + (valid_extensions + 1) * EDID_LENGTH, j)) {
if (drm_edid_block_valid(block + (valid_extensions + 1) * EDID_LENGTH, j, print_bad_edid)) {
valid_extensions++;
break;
}
Expand All @@ -372,8 +375,11 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)
return block;

carp:
dev_warn(connector->dev->dev, "%s: EDID block %d invalid.\n",
drm_get_connector_name(connector), j);
if (print_bad_edid) {
dev_warn(connector->dev->dev, "%s: EDID block %d invalid.\n",
drm_get_connector_name(connector), j);
}
connector->bad_edid_counter++;

out:
kfree(block);
Expand Down
6 changes: 4 additions & 2 deletions drivers/gpu/drm/drm_edid_load.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ static u8 *edid_load(struct drm_connector *connector, char *name,
int fwsize, expected;
int builtin = 0, err = 0;
int i, valid_extensions = 0;
bool print_bad_edid = !connector->bad_edid_counter || (drm_debug & DRM_UT_KMS);

pdev = platform_device_register_simple(connector_name, -1, NULL, 0);
if (IS_ERR(pdev)) {
Expand Down Expand Up @@ -173,7 +174,8 @@ static u8 *edid_load(struct drm_connector *connector, char *name,
}
memcpy(edid, fwdata, fwsize);

if (!drm_edid_block_valid(edid, 0)) {
if (!drm_edid_block_valid(edid, 0, print_bad_edid)) {
connector->bad_edid_counter++;
DRM_ERROR("Base block of EDID firmware \"%s\" is invalid ",
name);
kfree(edid);
Expand All @@ -185,7 +187,7 @@ static u8 *edid_load(struct drm_connector *connector, 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))
if (drm_edid_block_valid(edid + i * EDID_LENGTH, i, print_bad_edid))
valid_extensions++;
}

Expand Down
3 changes: 2 additions & 1 deletion include/drm/drm_crtc.h
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,7 @@ struct drm_connector {
int video_latency[2]; /* [0]: progressive, [1]: interlaced */
int audio_latency[2];
int null_edid_counter; /* needed to workaround some HW bugs where we get all 0s */
unsigned bad_edid_counter;
};

/**
Expand Down Expand Up @@ -1032,7 +1033,7 @@ extern int drm_add_modes_noedid(struct drm_connector *connector,
int hdisplay, int vdisplay);

extern int drm_edid_header_is_valid(const u8 *raw_edid);
extern bool drm_edid_block_valid(u8 *raw_edid, int block);
extern bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid);
extern bool drm_edid_is_valid(struct edid *edid);
struct drm_display_mode *drm_mode_find_dmt(struct drm_device *dev,
int hsize, int vsize, int fresh,
Expand Down

0 comments on commit 0b2443e

Please sign in to comment.