From 73fd8102d31b8a8396ba55eb21da35f482ec02dc Mon Sep 17 00:00:00 2001 From: Job Date: Sun, 7 Jun 2015 12:35:48 +0200 Subject: [PATCH 1/2] IT6251: Some fixes to the initialization --- drivers/gpu/drm/bridge/it6251.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/it6251.c b/drivers/gpu/drm/bridge/it6251.c index a583d31931843..2ce8f1d2f6ee6 100644 --- a/drivers/gpu/drm/bridge/it6251.c +++ b/drivers/gpu/drm/bridge/it6251.c @@ -248,6 +248,8 @@ static void it6251_init(struct work_struct *work) return; } + /* Reset DP */ + it6251_write(priv, 0x05, 0xff); it6251_write(priv, 0x05, 0x00); udelay(1000); @@ -267,7 +269,7 @@ static void it6251_init(struct work_struct *work) it6251_lvds_write(priv, 0x3c, 0x0f); // Enable DeSSC on LVDS port it6251_lvds_write(priv, 0x0b, 0x88); // don't swap links, but writing reserved registers - it6251_lvds_write(priv, 0x2c, 0x41); // JEIDA, 8-bit depth, DeSSC enabled + it6251_lvds_write(priv, 0x2c, 0x01); // JEIDA, 8-bit depth, DeSSC enabled it6251_lvds_write(priv, 0x32, 0x04); // "reserved" it6251_lvds_write(priv, 0x35, 0xe0); // "reserved" it6251_lvds_write(priv, 0x2b, 0x24); // "reserved" + clock delay From 9065c43c5e198d35392a247279362e5727253f39 Mon Sep 17 00:00:00 2001 From: Job Date: Sun, 7 Jun 2015 20:36:45 +0200 Subject: [PATCH 2/2] IT6251: More fixes and more robust retry. --- drivers/gpu/drm/bridge/it6251.c | 40 ++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/bridge/it6251.c b/drivers/gpu/drm/bridge/it6251.c index 2ce8f1d2f6ee6..9925d765064d1 100644 --- a/drivers/gpu/drm/bridge/it6251.c +++ b/drivers/gpu/drm/bridge/it6251.c @@ -185,6 +185,7 @@ static int it6251_is_stable(struct it6251_bridge *priv) int rpclkcnt; int clkcnt; int refstate; + int reg; status = it6251_read(priv, IT6251_SYSTEM_STATUS); dev_info(&priv->client->dev, "System status: 0x%02x\n", status); @@ -192,6 +193,14 @@ static int it6251_is_stable(struct it6251_bridge *priv) if (!(status & IT6251_SYSTEM_STATUS_RVIDEOSTABLE)) return 0; + /* Reset counter first */ + reg = it6251_read(priv, 0x12); + reg |= 0x80; + it6251_write(priv, 0x12, reg); + usleep_range(1000, 2000); + reg &= 0x7f; + it6251_write(priv, 0x12, reg); + rpclkcnt = ((it6251_read(priv, 0x13) & 0xff) | ((it6251_read(priv, 0x14) << 8) & 0x0f00)); dev_info(&priv->client->dev, "RPCLKCnt: %d\n", rpclkcnt); @@ -324,15 +333,34 @@ static void it6251_init(struct work_struct *work) for (tries = 0; tries < 100; tries++) { - reg = it6251_read(priv, 0x17); - if (reg == 0xe0) { - reg = it6251_read(priv, IT6251_SYSTEM_STATUS); - if (reg & IT6251_SYSTEM_STATUS_RVIDEOSTABLE) - break; + /* Check interrupt state and clear if set */ + reg = it6251_read(priv, 0x06); + if (reg !=0 ) { + dev_dbg(&priv->client->dev, "Intr(0x06) state: %02x\n",reg); + it6251_write(priv, 0x06, reg); + } + + reg = it6251_read(priv, IT6251_REF_STATE); + if ((reg & 0x1f) == 0x10) { + reg = it6251_read(priv, 0x17); + if ((reg & 0xe0) != 0xe0) { + reg = it6251_read(priv, IT6251_SYSTEM_STATUS); + if (reg & IT6251_SYSTEM_STATUS_RVIDEOSTABLE) + break; + } else { + /* Unexpected Link state */ + dev_dbg(&priv->client->dev, "Link 0x17 state: %02x\n",reg); + } + } else { + /* wait for Link training */ + dev_dbg(&priv->client->dev, "REF_STATE fail: %02x\n",reg); + it6251_write(priv, 0x05, 0x00); + it6251_write(priv, 0x17, 0x04); + it6251_write(priv, 0x17, 0x01); // start link training } udelay(2000); } - + /* * If we couldn't stabilize, requeue and try again, because it means * that the LVDS channel isn't stable yet.