From: Liviu Dudau Date: Mon, 21 Jul 2014 11:31:11 +0000 (+0100) Subject: drm: i2c: tda998x: Retry fetching the EDID if it fails first time. X-Git-Tag: submit/tizen/20141203.153721~53 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b725ac31bf2ed1a4b42791c5653b52cd9556b700;p=platform%2Fkernel%2Flinux-arm64.git drm: i2c: tda998x: Retry fetching the EDID if it fails first time. Fetching the EDID from a connected monitor is an automated thing with NXP TDA19988. But on some boards the fetching fails for the first time silently without any indication that an error has occured. More than that, subsequent fetches of the EDID succeed until the monitor(s) are pluged out. Add a function to validate the read EDID and retry if the block retrieved is not valid. Signed-off-by: Andrew Jackson Signed-off-by: Liviu Dudau --- diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index db5440dc9e2..27632aa61ea 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c @@ -1073,13 +1073,38 @@ read_edid_block(struct drm_encoder *encoder, uint8_t *buf, int blk) return 0; } +static int +read_validate_edid_block(struct drm_encoder *encoder, uint8_t *buf, int blk) +{ + bool print_bad_edid = drm_debug & DRM_UT_KMS; + int ret; + int retries = 1; + + do + { + bool print_bad = print_bad_edid && (retries == 0); + + ret = read_edid_block(encoder, buf, blk); + /* Fail on I2C error */ + if (ret) + break; + + /* But retry checksum errored blocks */ + if (drm_edid_block_valid(buf, blk, print_bad)) + break; + else + ret = -EINVAL; + } while (retries-- > 0); + + return ret; +} + static uint8_t * do_get_edid(struct drm_encoder *encoder) { struct tda998x_priv *priv = to_tda998x_priv(encoder); int j, valid_extensions = 0; uint8_t *block, *new; - bool print_bad_edid = drm_debug & DRM_UT_KMS; if ((block = kmalloc(EDID_LENGTH, GFP_KERNEL)) == NULL) return NULL; @@ -1088,10 +1113,7 @@ do_get_edid(struct drm_encoder *encoder) reg_clear(priv, REG_TX4, TX4_PD_RAM); /* base block fetch */ - if (read_edid_block(encoder, block, 0)) - goto fail; - - if (!drm_edid_block_valid(block, 0, print_bad_edid)) + if (read_validate_edid_block(encoder, block, 0)) goto fail; /* if there's no extensions, we're done */ @@ -1105,10 +1127,7 @@ do_get_edid(struct drm_encoder *encoder) for (j = 1; j <= block[0x7e]; j++) { uint8_t *ext_block = block + (valid_extensions + 1) * EDID_LENGTH; - if (read_edid_block(encoder, ext_block, j)) - goto fail; - - if (!drm_edid_block_valid(ext_block, j, print_bad_edid)) + if (read_validate_edid_block(encoder, ext_block, j)) goto fail; valid_extensions++;