summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDouglas Anderson <dianders@chromium.org>2015-10-27 16:05:15 -0700
committerPatrick Georgi <pgeorgi@google.com>2015-11-18 16:29:16 +0100
commit7760a47892bfec559d11e14c075770e79b1293e1 (patch)
tree3c56cd1bc33e82045c255c4747ef2b59fbe6fa62 /src
parentc494c7d68dceeeff007e6b2743669fdbdfbcf50a (diff)
downloadcoreboot-7760a47892bfec559d11e14c075770e79b1293e1.tar.xz
google/veyron*: Pulse the i2c clock once if sda was low
On one particular TV the TV was holding SDA low when it came up. It would release the SDA when the SCL went low the first time. Unfortunately the HDMI i2c port wouldn't transmit until the SDA was released. Let's detect this case and insert a bogus clock pulse to try to get the other side to release SDA. It's unclear why the kernel doesn't have this problem. BRANCH=none BUG=chrome-os-partner:46256 TEST=Insignia TV works now Change-Id: Ic9d27eb69bdc9c5fb11a68258e0c755cdc8b79d7 Signed-off-by: Patrick Georgi <pgeorgi@chromium.org> Original-Commit-Id: 356ee7503f04e741a41be37ad573b588067b7114 Original-Change-Id: I4b6361877e0576cc4ea2f643f073f1aab660e434 Original-Signed-off-by: Douglas Anderson <dianders@chromium.org> Original-Reviewed-on: https://chromium-review.googlesource.com/309258 Original-Reviewed-by: Agnes Cheng <agnescheng@google.com> Original-Commit-Queue: Agnes Cheng <agnescheng@google.com> Original-Trybot-Ready: Agnes Cheng <agnescheng@google.com> Original-Tested-by: Agnes Cheng <agnescheng@google.com> Original-Reviewed-on: https://chromium-review.googlesource.com/309546 Original-Commit-Ready: David Hendricks <dhendrix@chromium.org> Original-Tested-by: David Hendricks <dhendrix@chromium.org> Original-Reviewed-by: David Hendricks <dhendrix@chromium.org> Reviewed-on: http://review.coreboot.org/12451 Tested-by: build bot (Jenkins) Reviewed-by: Martin Roth <martinroth@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/mainboard/google/veyron_brain/mainboard.c4
-rw-r--r--src/mainboard/google/veyron_danger/mainboard.c4
-rw-r--r--src/mainboard/google/veyron_mickey/mainboard.c4
-rw-r--r--src/soc/rockchip/rk3288/hdmi.c16
4 files changed, 16 insertions, 12 deletions
diff --git a/src/mainboard/google/veyron_brain/mainboard.c b/src/mainboard/google/veyron_brain/mainboard.c
index 336879c61b..22faf6440b 100644
--- a/src/mainboard/google/veyron_brain/mainboard.c
+++ b/src/mainboard/google/veyron_brain/mainboard.c
@@ -82,10 +82,6 @@ static void configure_hdmi(void)
/* set POWER_HDMI_ON */
gpio_output(GPIO(7, A, 2), 1);
-
- /* HDMI I2C */
- write32(&rk3288_grf->iomux_i2c5sda, IOMUX_HDMI_EDP_I2C_SDA);
- write32(&rk3288_grf->iomux_i2c5scl, IOMUX_HDMI_EDP_I2C_SCL);
}
static void mainboard_init(device_t dev)
diff --git a/src/mainboard/google/veyron_danger/mainboard.c b/src/mainboard/google/veyron_danger/mainboard.c
index 8288e4d8dd..f923da9d01 100644
--- a/src/mainboard/google/veyron_danger/mainboard.c
+++ b/src/mainboard/google/veyron_danger/mainboard.c
@@ -137,10 +137,6 @@ static void configure_hdmi(void)
gpio_output(GPIO(5, C, 3), 1);
break;
}
-
- /* HDMI I2C */
- write32(&rk3288_grf->iomux_i2c5sda, IOMUX_HDMI_EDP_I2C_SDA);
- write32(&rk3288_grf->iomux_i2c5scl, IOMUX_HDMI_EDP_I2C_SCL);
}
static void mainboard_init(device_t dev)
diff --git a/src/mainboard/google/veyron_mickey/mainboard.c b/src/mainboard/google/veyron_mickey/mainboard.c
index f07e5f22fd..27e9f745e5 100644
--- a/src/mainboard/google/veyron_mickey/mainboard.c
+++ b/src/mainboard/google/veyron_mickey/mainboard.c
@@ -75,10 +75,6 @@ static void configure_vop(void)
static void configure_hdmi(void)
{
- /* HDMI I2C */
- write32(&rk3288_grf->iomux_i2c5sda, IOMUX_HDMI_EDP_I2C_SDA);
- write32(&rk3288_grf->iomux_i2c5scl, IOMUX_HDMI_EDP_I2C_SCL);
-
gpio_output(GPIO(7, B, 3), 1); /* POWER_HDMI_ON */
}
diff --git a/src/soc/rockchip/rk3288/hdmi.c b/src/soc/rockchip/rk3288/hdmi.c
index 805b98a6e5..1a825abfca 100644
--- a/src/soc/rockchip/rk3288/hdmi.c
+++ b/src/soc/rockchip/rk3288/hdmi.c
@@ -15,6 +15,7 @@
#include <console/console.h>
#include <delay.h>
#include <edid.h>
+#include <gpio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
@@ -774,8 +775,23 @@ int rk_hdmi_get_edid(struct edid *edid)
{
u8 edid_buf[HDMI_EDID_BLOCK_SIZE * 2];
u32 edid_size = HDMI_EDID_BLOCK_SIZE;
+ gpio_t hdmi_i2c_sda = GPIO(7, C, 3);
+ gpio_t hdmi_i2c_scl = GPIO(7, C, 4);
int ret;
+ /* If SDA is low, try to clock once to fix it */
+ gpio_input_pullup(hdmi_i2c_sda);
+ if (gpio_get(hdmi_i2c_sda) == 0) {
+ gpio_output(hdmi_i2c_scl, 0);
+ udelay(1000);
+ gpio_input_pullup(hdmi_i2c_scl);
+ udelay(1000);
+ }
+
+ /* HDMI I2C */
+ write32(&rk3288_grf->iomux_i2c5sda, IOMUX_HDMI_EDP_I2C_SDA);
+ write32(&rk3288_grf->iomux_i2c5scl, IOMUX_HDMI_EDP_I2C_SCL);
+
ret = hdmi_read_edid(0, edid_buf);
if (ret) {
hdmi_debug("failed to read edid.\n");