From 1bf29c99f1550d56d1f1aabb2953ea2221d45e64 Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Tue, 27 Oct 2015 16:05:15 -0700 Subject: [PATCH] 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: I4b6361877e0576cc4ea2f643f073f1aab660e434 Signed-off-by: Douglas Anderson Reviewed-on: https://chromium-review.googlesource.com/309258 Reviewed-by: Agnes Cheng Commit-Queue: Agnes Cheng Trybot-Ready: Agnes Cheng Tested-by: Agnes Cheng --- src/mainboard/google/veyron_brain/mainboard.c | 4 ---- src/mainboard/google/veyron_danger/mainboard.c | 4 ---- src/mainboard/google/veyron_mickey/mainboard.c | 4 ---- src/soc/rockchip/rk3288/hdmi.c | 16 ++++++++++++++++ 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 fddae95514..00110be94e 100644 --- a/src/mainboard/google/veyron_brain/mainboard.c +++ b/src/mainboard/google/veyron_brain/mainboard.c @@ -86,10 +86,6 @@ static void configure_hdmi(void) /* set POWER_HDMI_ON */ gpio_output(GPIO(7, A, 2), 1); - - /* HDMI I2C */ - writel(IOMUX_HDMI_EDP_I2C_SDA, &rk3288_grf->iomux_i2c5sda); - writel(IOMUX_HDMI_EDP_I2C_SCL, &rk3288_grf->iomux_i2c5scl); } 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 a40ac84556..808cfafba6 100644 --- a/src/mainboard/google/veyron_danger/mainboard.c +++ b/src/mainboard/google/veyron_danger/mainboard.c @@ -141,10 +141,6 @@ static void configure_hdmi(void) gpio_output(GPIO(5, C, 3), 1); break; } - - /* HDMI I2C */ - writel(IOMUX_HDMI_EDP_I2C_SDA, &rk3288_grf->iomux_i2c5sda); - writel(IOMUX_HDMI_EDP_I2C_SCL, &rk3288_grf->iomux_i2c5scl); } 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 0644c4ad80..35e7e5f59e 100644 --- a/src/mainboard/google/veyron_mickey/mainboard.c +++ b/src/mainboard/google/veyron_mickey/mainboard.c @@ -82,10 +82,6 @@ static void configure_vop(void) static void configure_hdmi(void) { - /* HDMI I2C */ - writel(IOMUX_HDMI_EDP_I2C_SDA, &rk3288_grf->iomux_i2c5sda); - writel(IOMUX_HDMI_EDP_I2C_SCL, &rk3288_grf->iomux_i2c5scl); - 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 33e4a0a4a3..639f733266 100644 --- a/src/soc/rockchip/rk3288/hdmi.c +++ b/src/soc/rockchip/rk3288/hdmi.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -775,8 +776,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 */ + writel(IOMUX_HDMI_EDP_I2C_SDA, &rk3288_grf->iomux_i2c5sda); + writel(IOMUX_HDMI_EDP_I2C_SCL, &rk3288_grf->iomux_i2c5scl); + ret = hdmi_read_edid(0, edid_buf); if (ret) { hdmi_debug("failed to read edid.\n");