WIP: drm: adv7511: potential edid probe fix

Message ID 1479455974-28028-1-git-send-email-john.stultz@linaro.org
State New
Headers show

Commit Message

John Stultz Nov. 18, 2016, 7:59 a.m.
So this improved the edid probing on hotplug.

I'm doing 3 things here (which I'll need to split out eventually):
* Making adv7511_power_on/off reusable for internal uses
* Using adv7511_power_on/off instead of the half-implementation
  of poweron used before edid probing
* Adding a msleep(200) in the power_on path
* Adding some suggested register initialization in the power_on path

Cc: Archit Taneja <architt@codeaurora.org>
Cc: Xinliang Liu <xinliang.liu@linaro.org>
Cc: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Signed-off-by: John Stultz <john.stultz@linaro.org>

---
 drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 42 +++++++++++++++++-----------
 1 file changed, 26 insertions(+), 16 deletions(-)

-- 
2.7.4

Patch hide | download patch | download mbox

diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
index 05b3663..3969d88 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
@@ -328,7 +328,7 @@  static void adv7511_set_link_config(struct adv7511 *adv7511,
 	adv7511->rgb = config->input_colorspace == HDMI_COLORSPACE_RGB;
 }
 
-static void adv7511_power_on(struct adv7511 *adv7511)
+static void __adv7511_power_on(struct adv7511 *adv7511)
 {
 	adv7511->current_edid_segment = -1;
 
@@ -346,6 +346,17 @@  static void adv7511_power_on(struct adv7511 *adv7511)
 			     ADV7511_INT1_DDC_ERROR);
 	}
 
+
+	/* magic table initialization from table 14 in programming guide */
+	regmap_write(adv7511->regmap, 0x98, 0x3);
+	regmap_update_bits(adv7511->regmap, 0x9a,0xfe, 0xe0);
+	regmap_write(adv7511->regmap, 0x9c, 0x30);
+	regmap_update_bits(adv7511->regmap, 0x9d,0x3, 0x1);
+	regmap_write(adv7511->regmap, 0xa2, 0xa4);
+	regmap_write(adv7511->regmap, 0xa3, 0xa4);
+	regmap_write(adv7511->regmap, 0xe0, 0xd0);
+	regmap_write(adv7511->regmap, 0xf9, 0x00);
+
 	/*
 	 * Per spec it is allowed to pulse the HPD signal to indicate that the
 	 * EDID information has changed. Some monitors do this when they wakeup
@@ -363,13 +374,19 @@  static void adv7511_power_on(struct adv7511 *adv7511)
 	 */
 	regcache_sync(adv7511->regmap);
 
+	msleep(200);
+
 	if (adv7511->type == ADV7533)
 		adv7533_dsi_power_on(adv7511);
+}
 
+static void adv7511_power_on(struct adv7511 *adv7511)
+{
+	__adv7511_power_on(adv7511);
 	adv7511->powered = true;
 }
 
-static void adv7511_power_off(struct adv7511 *adv7511)
+static void __adv7511_power_off(struct adv7511 *adv7511)
 {
 	/* TODO: setup additional power down modes */
 	regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER,
@@ -379,7 +396,11 @@  static void adv7511_power_off(struct adv7511 *adv7511)
 
 	if (adv7511->type == ADV7533)
 		adv7533_dsi_power_off(adv7511);
+}
 
+static void adv7511_power_off(struct adv7511 *adv7511)
+{
+	__adv7511_power_off(adv7511);
 	adv7511->powered = false;
 }
 
@@ -548,24 +569,13 @@  static int adv7511_get_modes(struct adv7511 *adv7511,
 	unsigned int count;
 
 	/* Reading the EDID only works if the device is powered */
-	if (!adv7511->powered) {
-		regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER,
-				   ADV7511_POWER_POWER_DOWN, 0);
-		if (adv7511->i2c_main->irq) {
-			regmap_write(adv7511->regmap, ADV7511_REG_INT_ENABLE(0),
-				     ADV7511_INT0_EDID_READY);
-			regmap_write(adv7511->regmap, ADV7511_REG_INT_ENABLE(1),
-				     ADV7511_INT1_DDC_ERROR);
-		}
-		adv7511->current_edid_segment = -1;
-	}
+	if (!adv7511->powered)
+		__adv7511_power_on(adv7511);
 
 	edid = drm_do_get_edid(connector, adv7511_get_edid_block, adv7511);
 
 	if (!adv7511->powered)
-		regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER,
-				   ADV7511_POWER_POWER_DOWN,
-				   ADV7511_POWER_POWER_DOWN);
+		__adv7511_power_off(adv7511);
 
 	kfree(adv7511->edid);
 	adv7511->edid = edid;