mirror of
https://github.com/torvalds/linux.git
synced 2024-11-21 19:46:16 +00:00
nouveau/dp: handle retries for AUX CH transfers with GSP.
eb284f4b37
drm/nouveau/dp: Honor GSP link training retry timeouts tried to fix a problem with panel retires, however it appears the auxch also needs the same treatment, so add the same retry wrapper around it. This fixes some eDP panels after a suspend/resume cycle. Fixes:eb284f4b37
("drm/nouveau/dp: Honor GSP link training retry timeouts") Cc: stable@vger.kernel.org Reviewed-by: Lyude Paul <lyude@redhat.com> Signed-off-by: Dave Airlie <airlied@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20241111034126.2028401-2-airlied@gmail.com
This commit is contained in:
parent
b6ad7debf5
commit
9776c0a75a
@ -1060,33 +1060,44 @@ r535_dp_aux_xfer(struct nvkm_outp *outp, u8 type, u32 addr, u8 *data, u8 *psize)
|
||||
NV0073_CTRL_DP_AUXCH_CTRL_PARAMS *ctrl;
|
||||
u8 size = *psize;
|
||||
int ret;
|
||||
int retries;
|
||||
|
||||
ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom, NV0073_CTRL_CMD_DP_AUXCH_CTRL, sizeof(*ctrl));
|
||||
if (IS_ERR(ctrl))
|
||||
return PTR_ERR(ctrl);
|
||||
for (retries = 0; retries < 3; ++retries) {
|
||||
ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom, NV0073_CTRL_CMD_DP_AUXCH_CTRL, sizeof(*ctrl));
|
||||
if (IS_ERR(ctrl))
|
||||
return PTR_ERR(ctrl);
|
||||
|
||||
ctrl->subDeviceInstance = 0;
|
||||
ctrl->displayId = BIT(outp->index);
|
||||
ctrl->bAddrOnly = !size;
|
||||
ctrl->cmd = type;
|
||||
if (ctrl->bAddrOnly) {
|
||||
ctrl->cmd = NVDEF_SET(ctrl->cmd, NV0073_CTRL, DP_AUXCH_CMD, REQ_TYPE, WRITE);
|
||||
ctrl->cmd = NVDEF_SET(ctrl->cmd, NV0073_CTRL, DP_AUXCH_CMD, I2C_MOT, FALSE);
|
||||
ctrl->subDeviceInstance = 0;
|
||||
ctrl->displayId = BIT(outp->index);
|
||||
ctrl->bAddrOnly = !size;
|
||||
ctrl->cmd = type;
|
||||
if (ctrl->bAddrOnly) {
|
||||
ctrl->cmd = NVDEF_SET(ctrl->cmd, NV0073_CTRL, DP_AUXCH_CMD, REQ_TYPE, WRITE);
|
||||
ctrl->cmd = NVDEF_SET(ctrl->cmd, NV0073_CTRL, DP_AUXCH_CMD, I2C_MOT, FALSE);
|
||||
}
|
||||
ctrl->addr = addr;
|
||||
ctrl->size = !ctrl->bAddrOnly ? (size - 1) : 0;
|
||||
memcpy(ctrl->data, data, size);
|
||||
|
||||
ret = nvkm_gsp_rm_ctrl_push(&disp->rm.objcom, &ctrl, sizeof(*ctrl));
|
||||
if ((ret == -EAGAIN || ret == -EBUSY) && ctrl->retryTimeMs) {
|
||||
/*
|
||||
* Device (likely an eDP panel) isn't ready yet, wait for the time specified
|
||||
* by GSP before retrying again
|
||||
*/
|
||||
nvkm_debug(&disp->engine.subdev,
|
||||
"Waiting %dms for GSP LT panel delay before retrying in AUX\n",
|
||||
ctrl->retryTimeMs);
|
||||
msleep(ctrl->retryTimeMs);
|
||||
nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
|
||||
} else {
|
||||
memcpy(data, ctrl->data, size);
|
||||
*psize = ctrl->size;
|
||||
ret = ctrl->replyType;
|
||||
nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
|
||||
break;
|
||||
}
|
||||
}
|
||||
ctrl->addr = addr;
|
||||
ctrl->size = !ctrl->bAddrOnly ? (size - 1) : 0;
|
||||
memcpy(ctrl->data, data, size);
|
||||
|
||||
ret = nvkm_gsp_rm_ctrl_push(&disp->rm.objcom, &ctrl, sizeof(*ctrl));
|
||||
if (ret) {
|
||||
nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
|
||||
return ret;
|
||||
}
|
||||
|
||||
memcpy(data, ctrl->data, size);
|
||||
*psize = ctrl->size;
|
||||
ret = ctrl->replyType;
|
||||
nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user