Skip to content

Commit 9776c0a

Browse files
committed
nouveau/dp: handle retries for AUX CH transfers with GSP.
eb284f4 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: eb284f4 ("drm/nouveau/dp: Honor GSP link training retry timeouts") Cc: [email protected] Reviewed-by: Lyude Paul <[email protected]> Signed-off-by: Dave Airlie <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent b6ad7de commit 9776c0a

File tree

1 file changed

+34
-23
lines changed
  • drivers/gpu/drm/nouveau/nvkm/engine/disp

1 file changed

+34
-23
lines changed

drivers/gpu/drm/nouveau/nvkm/engine/disp/r535.c

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1060,33 +1060,44 @@ r535_dp_aux_xfer(struct nvkm_outp *outp, u8 type, u32 addr, u8 *data, u8 *psize)
10601060
NV0073_CTRL_DP_AUXCH_CTRL_PARAMS *ctrl;
10611061
u8 size = *psize;
10621062
int ret;
1063+
int retries;
10631064

1064-
ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom, NV0073_CTRL_CMD_DP_AUXCH_CTRL, sizeof(*ctrl));
1065-
if (IS_ERR(ctrl))
1066-
return PTR_ERR(ctrl);
1065+
for (retries = 0; retries < 3; ++retries) {
1066+
ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom, NV0073_CTRL_CMD_DP_AUXCH_CTRL, sizeof(*ctrl));
1067+
if (IS_ERR(ctrl))
1068+
return PTR_ERR(ctrl);
10671069

1068-
ctrl->subDeviceInstance = 0;
1069-
ctrl->displayId = BIT(outp->index);
1070-
ctrl->bAddrOnly = !size;
1071-
ctrl->cmd = type;
1072-
if (ctrl->bAddrOnly) {
1073-
ctrl->cmd = NVDEF_SET(ctrl->cmd, NV0073_CTRL, DP_AUXCH_CMD, REQ_TYPE, WRITE);
1074-
ctrl->cmd = NVDEF_SET(ctrl->cmd, NV0073_CTRL, DP_AUXCH_CMD, I2C_MOT, FALSE);
1075-
}
1076-
ctrl->addr = addr;
1077-
ctrl->size = !ctrl->bAddrOnly ? (size - 1) : 0;
1078-
memcpy(ctrl->data, data, size);
1070+
ctrl->subDeviceInstance = 0;
1071+
ctrl->displayId = BIT(outp->index);
1072+
ctrl->bAddrOnly = !size;
1073+
ctrl->cmd = type;
1074+
if (ctrl->bAddrOnly) {
1075+
ctrl->cmd = NVDEF_SET(ctrl->cmd, NV0073_CTRL, DP_AUXCH_CMD, REQ_TYPE, WRITE);
1076+
ctrl->cmd = NVDEF_SET(ctrl->cmd, NV0073_CTRL, DP_AUXCH_CMD, I2C_MOT, FALSE);
1077+
}
1078+
ctrl->addr = addr;
1079+
ctrl->size = !ctrl->bAddrOnly ? (size - 1) : 0;
1080+
memcpy(ctrl->data, data, size);
10791081

1080-
ret = nvkm_gsp_rm_ctrl_push(&disp->rm.objcom, &ctrl, sizeof(*ctrl));
1081-
if (ret) {
1082-
nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
1083-
return ret;
1082+
ret = nvkm_gsp_rm_ctrl_push(&disp->rm.objcom, &ctrl, sizeof(*ctrl));
1083+
if ((ret == -EAGAIN || ret == -EBUSY) && ctrl->retryTimeMs) {
1084+
/*
1085+
* Device (likely an eDP panel) isn't ready yet, wait for the time specified
1086+
* by GSP before retrying again
1087+
*/
1088+
nvkm_debug(&disp->engine.subdev,
1089+
"Waiting %dms for GSP LT panel delay before retrying in AUX\n",
1090+
ctrl->retryTimeMs);
1091+
msleep(ctrl->retryTimeMs);
1092+
nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
1093+
} else {
1094+
memcpy(data, ctrl->data, size);
1095+
*psize = ctrl->size;
1096+
ret = ctrl->replyType;
1097+
nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
1098+
break;
1099+
}
10841100
}
1085-
1086-
memcpy(data, ctrl->data, size);
1087-
*psize = ctrl->size;
1088-
ret = ctrl->replyType;
1089-
nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
10901101
return ret;
10911102
}
10921103

0 commit comments

Comments
 (0)