Commit d44ba844 authored by Lin Huang's avatar Lin Huang Committed by Andrzej Hajda

drm/bridge: analogix_dp: Reset aux channel if an error occurred

AUX errors are caused by many different reasons. We may not know what
happened in aux channel on failure, so let's reset aux channel if some
errors occurred.

Cc: 征增 王 <wzz@rock-chips.com>
Cc: Douglas Anderson <dianders@chromium.org>
Signed-off-by: default avatarLin Huang <hl@rock-chips.com>
Signed-off-by: default avatarSean Paul <seanpaul@chromium.org>
Signed-off-by: default avatarThierry Escande <thierry.escande@collabora.com>
Reviewed-by: default avatarAndrzej Hajda <a.hajda@samsung.com>
Tested-by: default avatarMarek Szyprowski <m.szyprowski@samsung.com>
Reviewed-by: default avatarArchit Taneja <architt@codeaurora.org>
Signed-off-by: default avatarEnric Balletbo i Serra <enric.balletbo@collabora.com>
Signed-off-by: default avatarAndrzej Hajda <a.hajda@samsung.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180423105003.9004-13-enric.balletbo@collabora.com
parent f12da687
......@@ -466,6 +466,10 @@ void analogix_dp_init_aux(struct analogix_dp_device *dp)
reg = RPLY_RECEIV | AUX_ERR;
writel(reg, dp->reg_base + ANALOGIX_DP_INT_STA);
analogix_dp_set_analog_power_down(dp, AUX_BLOCK, true);
usleep_range(10, 11);
analogix_dp_set_analog_power_down(dp, AUX_BLOCK, false);
analogix_dp_reset_aux(dp);
/* Disable AUX transaction H/W retry */
......@@ -1159,7 +1163,7 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
reg, !(reg & AUX_EN), 25, 500 * 1000);
if (ret) {
dev_err(dp->dev, "AUX CH enable timeout!\n");
return -ETIMEDOUT;
goto aux_error;
}
/* TODO: Wait for an interrupt instead of looping? */
......@@ -1168,7 +1172,7 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
reg, reg & RPLY_RECEIV, 10, 20 * 1000);
if (ret) {
dev_err(dp->dev, "AUX CH cmd reply timeout!\n");
return -ETIMEDOUT;
goto aux_error;
}
/* Clear interrupt source for AUX CH command reply */
......@@ -1178,7 +1182,7 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA);
if (reg & AUX_ERR) {
writel(AUX_ERR, dp->reg_base + ANALOGIX_DP_INT_STA);
return -EREMOTEIO;
goto aux_error;
}
/* Check AUX CH error access status */
......@@ -1186,7 +1190,7 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
if ((reg & AUX_STATUS_MASK)) {
dev_err(dp->dev, "AUX CH error happened: %d\n\n",
reg & AUX_STATUS_MASK);
return -EREMOTEIO;
goto aux_error;
}
if (msg->request & DP_AUX_I2C_READ) {
......@@ -1212,4 +1216,10 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
msg->reply = DP_AUX_NATIVE_REPLY_ACK;
return num_transferred > 0 ? num_transferred : -EBUSY;
aux_error:
/* if aux err happen, reset aux */
analogix_dp_init_aux(dp);
return -EREMOTEIO;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment