From: Amit Bhanagay Date: Fri, 30 Mar 2012 02:43:23 +0000 (-0700) Subject: gfx: Fix for HDMI i2c operation not detected by some monitors. X-Git-Tag: 2.1b_release~180 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=8df7d69bed62420aafb34874d9f8373e6453a455;p=kernel%2Fkernel-mfld-blackbay.git gfx: Fix for HDMI i2c operation not detected by some monitors. HDMI i2c operations are streamlined by adding appropriate sleeps between the operations to complete properly and avoid subsequent failures. HDMI i2c write operation to write 2 messages (message and payload) is changed to writing 1 message instead (message and payload combined). Some monitors don't handle 2 messages properly. Issue: ANDROID-238 Signed-off-by: Amit Bhanagay Signed-off-by: Artem Bityutskiy --- diff --git a/drivers/staging/mrst/drv/otm_hdmi/Makefile b/drivers/staging/mrst/drv/otm_hdmi/Makefile index 74779e8..d52c583 100644 --- a/drivers/staging/mrst/drv/otm_hdmi/Makefile +++ b/drivers/staging/mrst/drv/otm_hdmi/Makefile @@ -81,6 +81,9 @@ ccflags-y += \ #only for internal testing ccflags-y += -DOTM_HDMI_UNIT_TEST +#enable HDCP +ccflags-y += -DOTM_HDMI_HDCP_ENABLE + ifeq ($(CONFIG_MDFD_HDMI_GREENRIDGE),y) ccflags-y += \ -I$(srctree)/$(src)/drv/otm_hdmi/pil/specific/oktl \ diff --git a/drivers/staging/mrst/drv/otm_hdmi/os/android/android_hdmi.c b/drivers/staging/mrst/drv/otm_hdmi/os/android/android_hdmi.c index 0ab960f..516a3a9 100644 --- a/drivers/staging/mrst/drv/otm_hdmi/os/android/android_hdmi.c +++ b/drivers/staging/mrst/drv/otm_hdmi/os/android/android_hdmi.c @@ -127,6 +127,7 @@ static u32 debug_modes_count; /*OTM_HDMI_FIXME: this should be from get attribute interface*/ #define OTM_HDMI_I2C_ADAPTER_NUM 8 +#define OTM_HDMI_MAX_DDC_WRITE_SIZE 20 #define SWITCH_DEV_HDMI_NAME "hdmi" #define SWITCH_DEV_DVI_NAME "dvi" @@ -298,21 +299,41 @@ static int hdmi_ddc_read_write(bool read, int size) { struct i2c_adapter *adapter = i2c_get_adapter(OTM_HDMI_I2C_ADAPTER_NUM); - struct i2c_msg msgs[] = { - { - .addr = i2c_addr, - .flags = 0, - .len = 1, - .buf = &offset, - }, { - .addr = i2c_addr, - .flags = ((read) ? I2C_M_RD : 0), - .len = size, - .buf = buffer, - } - }; + struct i2c_msg msgs[2]; + int num_of_msgs = 0; + uint8_t wr_buffer[OTM_HDMI_MAX_DDC_WRITE_SIZE]; + + /* Use one i2c message to write and two to read as some + * monitors don't handle two write messages properly + */ + if (read) { + msgs[0].addr = i2c_addr, + msgs[0].flags = 0, + msgs[0].len = 1, + msgs[0].buf = &offset, + + msgs[1].addr = i2c_addr, + msgs[1].flags = ((read) ? I2C_M_RD : 0), + msgs[1].len = size, + msgs[1].buf = buffer, + + num_of_msgs = 2; + } else { + BUG_ON(size + 1 > OTM_HDMI_MAX_DDC_WRITE_SIZE); + + wr_buffer[0] = offset; + memcpy(&wr_buffer[1], buffer, size); + + msgs[0].addr = i2c_addr, + msgs[0].flags = 0, + msgs[0].len = size + 1, + msgs[0].buf = wr_buffer, + + num_of_msgs = 1; + } - if (adapter != NULL && i2c_transfer(adapter, msgs, 2) == 2) + if (adapter != NULL && i2c_transfer(adapter, msgs, num_of_msgs) == + num_of_msgs) return 1; return 0; diff --git a/drivers/staging/mrst/drv/otm_hdmi/pil/common/hdcp.c b/drivers/staging/mrst/drv/otm_hdmi/pil/common/hdcp.c index 6f99bdd..557cce1 100644 --- a/drivers/staging/mrst/drv/otm_hdmi/pil/common/hdcp.c +++ b/drivers/staging/mrst/drv/otm_hdmi/pil/common/hdcp.c @@ -326,6 +326,8 @@ static bool hdcp_send_an_aksv(uint8_t *an, uint8_t an_size, aksv != NULL && aksv_size == HDCP_KSV_SIZE) { if (hdcp_ddc_write(HDCP_RX_AN_ADDR, an, HDCP_AN_SIZE) == true) { + /* wait 20ms for i2c write for An to complete */ + msleep(20); if (hdcp_ddc_write(HDCP_RX_AKSV_ADDR, aksv, HDCP_KSV_SIZE) == true) ret = true; @@ -417,10 +419,16 @@ static int hdcp_stage1_authentication(bool *is_repeater) pr_debug("hdcp: bksv: %02x%02x%02x%02x%02x\n", bksv[0], bksv[1], bksv[2], bksv[3], bksv[4]); + /* wait 20ms for i2c read for bksv to complete */ + msleep(20); + if (hdcp_read_bcaps(&bcaps.value) == false) return false; pr_debug("hdcp: bcaps: %x\n", bcaps.value); + /* wait 20ms for i2c read for bcaps to complete */ + msleep(20); + /* Read BSTATUS */ if (hdcp_read_bstatus(&bstatus.value) == false) return false; @@ -445,15 +453,15 @@ static int hdcp_stage1_authentication(bool *is_repeater) pr_debug("hdcp: auth started\n"); - /* Wait for 100ms */ - msleep_interruptible(100); + /* Wait for 120ms before reading R0' */ + msleep(120); /* Check if R0 Ready */ retry = 20; do { if (ipil_hdcp_is_r0_ready() == true) break; - msleep_interruptible(5); + msleep(5); retry--; } while (retry); diff --git a/drivers/staging/mrst/drv/psb_intel_hdmi.c b/drivers/staging/mrst/drv/psb_intel_hdmi.c index e985487..78696f3 100644 --- a/drivers/staging/mrst/drv/psb_intel_hdmi.c +++ b/drivers/staging/mrst/drv/psb_intel_hdmi.c @@ -337,6 +337,8 @@ static void mdfld_hdmi_dpms(struct drm_encoder *encoder, int mode) } REG_READ(hdmi_priv->hdmib_reg); + android_hdmi_dpms(encoder, mode); + ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND); }