drm/rockchip: dw_hdmi: Reset ddc bus when communication error
Signed-off-by: Algea Cao <algea.cao@rock-chips.com> Change-Id: Ia397abda111f20aabff48ccb18ff6b228754d0e1
This commit is contained in:
@@ -689,12 +689,14 @@ static int dw_hdmi_i2c_read(struct dw_hdmi_qp *hdmi,
|
||||
stat = wait_for_completion_timeout(&i2c->cmp, HZ / 10);
|
||||
if (!stat) {
|
||||
dev_err(hdmi->dev, "i2c read time out!\n");
|
||||
hdmi_writel(hdmi, 0x01, I2CM_CONTROL0);
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
/* Check for error condition on the bus */
|
||||
if (i2c->stat & I2CM_NACK_RCVD_IRQ) {
|
||||
dev_err(hdmi->dev, "i2c read err!\n");
|
||||
hdmi_writel(hdmi, 0x01, I2CM_CONTROL0);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
@@ -734,12 +736,14 @@ static int dw_hdmi_i2c_write(struct dw_hdmi_qp *hdmi,
|
||||
stat = wait_for_completion_timeout(&i2c->cmp, HZ / 10);
|
||||
if (!stat) {
|
||||
dev_err(hdmi->dev, "i2c write time out!\n");
|
||||
hdmi_writel(hdmi, 0x01, I2CM_CONTROL0);
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
/* Check for error condition on the bus */
|
||||
if (i2c->stat & I2CM_NACK_RCVD_IRQ) {
|
||||
dev_err(hdmi->dev, "i2c write nack!\n");
|
||||
hdmi_writel(hdmi, 0x01, I2CM_CONTROL0);
|
||||
return -EIO;
|
||||
}
|
||||
hdmi_modb(hdmi, 0, I2CM_WR_MASK, I2CM_INTERFACE_CONTROL0);
|
||||
@@ -1256,12 +1260,6 @@ static int hdmi_start_flt(struct dw_hdmi_qp *hdmi, u8 rate)
|
||||
u8 ffe_lv = 0;
|
||||
int i = 0, stat;
|
||||
|
||||
hdmi_modb(hdmi, SCDC_UPD_FLAGS_RD_IRQ, SCDC_UPD_FLAGS_RD_IRQ,
|
||||
MAINUNIT_1_INT_MASK_N);
|
||||
hdmi_modb(hdmi, SCDC_UPD_FLAGS_POLL_EN | SCDC_UPD_FLAGS_AUTO_CLR,
|
||||
SCDC_UPD_FLAGS_POLL_EN | SCDC_UPD_FLAGS_AUTO_CLR,
|
||||
SCDC_CONFIG0);
|
||||
|
||||
/* FLT_READY & FFE_LEVELS read */
|
||||
for (i = 0; i < 20; i++) {
|
||||
drm_scdc_readb(hdmi->ddc, SCDC_STATUS_FLAGS_0, &val);
|
||||
@@ -1275,6 +1273,12 @@ static int hdmi_start_flt(struct dw_hdmi_qp *hdmi, u8 rate)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
hdmi_modb(hdmi, SCDC_UPD_FLAGS_RD_IRQ, SCDC_UPD_FLAGS_RD_IRQ,
|
||||
MAINUNIT_1_INT_MASK_N);
|
||||
hdmi_modb(hdmi, SCDC_UPD_FLAGS_POLL_EN | SCDC_UPD_FLAGS_AUTO_CLR,
|
||||
SCDC_UPD_FLAGS_POLL_EN | SCDC_UPD_FLAGS_AUTO_CLR,
|
||||
SCDC_CONFIG0);
|
||||
|
||||
/* max ffe level 3 */
|
||||
val = 3 << 4 | hdmi_set_frl_mask(rate);
|
||||
drm_scdc_writeb(hdmi->ddc, 0x31, val);
|
||||
@@ -1292,11 +1296,19 @@ static int hdmi_start_flt(struct dw_hdmi_qp *hdmi, u8 rate)
|
||||
stat = wait_for_completion_timeout(&hdmi->flt_cmp, HZ * 2);
|
||||
if (!stat) {
|
||||
dev_err(hdmi->dev, "wait lts3 finish time out\n");
|
||||
hdmi_modb(hdmi, 0, SCDC_UPD_FLAGS_POLL_EN |
|
||||
SCDC_UPD_FLAGS_AUTO_CLR, SCDC_CONFIG0);
|
||||
hdmi_modb(hdmi, 0, SCDC_UPD_FLAGS_RD_IRQ,
|
||||
MAINUNIT_1_INT_MASK_N);
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
if (!(hdmi->flt_intr & FLT_EXIT_TO_LTSP_IRQ)) {
|
||||
dev_err(hdmi->dev, "not to ltsp\n");
|
||||
hdmi_modb(hdmi, 0, SCDC_UPD_FLAGS_POLL_EN |
|
||||
SCDC_UPD_FLAGS_AUTO_CLR, SCDC_CONFIG0);
|
||||
hdmi_modb(hdmi, 0, SCDC_UPD_FLAGS_RD_IRQ,
|
||||
MAINUNIT_1_INT_MASK_N);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user