Skip to content

Commit eb284f4

Browse files
Lyudeairlied
authored andcommitted
drm/nouveau/dp: Honor GSP link training retry timeouts
Turns out that one of the ways that Nvidia's driver handles the pre-LT timeout for eDP panels is by providing a retry timeout in their link training callbacks that we're expected to wait for. Up until now we didn't pay any attention to this parameter. So, start honoring the timeout if link training fails - and retry up to 3 times. The "3 times" bit comes from OpenRM's link training code. [airlied: this fixes the panel on one of my laptops] Signed-off-by: Lyude Paul <lyude@redhat.com> Signed-off-by: Dave Airlie <airlied@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20231222043308.3090089-12-airlied@gmail.com
1 parent eacabb5 commit eb284f4

File tree

1 file changed

+42
-22
lines changed
  • drivers/gpu/drm/nouveau/nvkm/engine/disp

1 file changed

+42
-22
lines changed

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

Lines changed: 42 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -957,40 +957,60 @@ r535_dp_train_target(struct nvkm_outp *outp, u8 target, bool mst, u8 link_nr, u8
957957
{
958958
struct nvkm_disp *disp = outp->disp;
959959
NV0073_CTRL_DP_CTRL_PARAMS *ctrl;
960-
int ret;
961-
962-
ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom, NV0073_CTRL_CMD_DP_CTRL, sizeof(*ctrl));
963-
if (IS_ERR(ctrl))
964-
return PTR_ERR(ctrl);
960+
int ret, retries;
961+
u32 cmd, data;
965962

966-
ctrl->subDeviceInstance = 0;
967-
ctrl->displayId = BIT(outp->index);
968-
ctrl->cmd = NVDEF(NV0073_CTRL, DP_CMD, SET_LANE_COUNT, TRUE) |
969-
NVDEF(NV0073_CTRL, DP_CMD, SET_LINK_BW, TRUE) |
970-
NVDEF(NV0073_CTRL, DP_CMD, TRAIN_PHY_REPEATER, YES);
971-
ctrl->data = NVVAL(NV0073_CTRL, DP_DATA, SET_LANE_COUNT, link_nr) |
972-
NVVAL(NV0073_CTRL, DP_DATA, SET_LINK_BW, link_bw) |
973-
NVVAL(NV0073_CTRL, DP_DATA, TARGET, target);
963+
cmd = NVDEF(NV0073_CTRL, DP_CMD, SET_LANE_COUNT, TRUE) |
964+
NVDEF(NV0073_CTRL, DP_CMD, SET_LINK_BW, TRUE) |
965+
NVDEF(NV0073_CTRL, DP_CMD, TRAIN_PHY_REPEATER, YES);
966+
data = NVVAL(NV0073_CTRL, DP_DATA, SET_LANE_COUNT, link_nr) |
967+
NVVAL(NV0073_CTRL, DP_DATA, SET_LINK_BW, link_bw) |
968+
NVVAL(NV0073_CTRL, DP_DATA, TARGET, target);
974969

975970
if (mst)
976-
ctrl->cmd |= NVDEF(NV0073_CTRL, DP_CMD, SET_FORMAT_MODE, MULTI_STREAM);
971+
cmd |= NVDEF(NV0073_CTRL, DP_CMD, SET_FORMAT_MODE, MULTI_STREAM);
977972

978973
if (outp->dp.dpcd[DPCD_RC02] & DPCD_RC02_ENHANCED_FRAME_CAP)
979-
ctrl->cmd |= NVDEF(NV0073_CTRL, DP_CMD, SET_ENHANCED_FRAMING, TRUE);
974+
cmd |= NVDEF(NV0073_CTRL, DP_CMD, SET_ENHANCED_FRAMING, TRUE);
980975

981976
if (target == 0 &&
982977
(outp->dp.dpcd[DPCD_RC02] & 0x20) &&
983978
!(outp->dp.dpcd[DPCD_RC03] & DPCD_RC03_TPS4_SUPPORTED))
984-
ctrl->cmd |= NVDEF(NV0073_CTRL, DP_CMD, POST_LT_ADJ_REQ_GRANTED, YES);
979+
cmd |= NVDEF(NV0073_CTRL, DP_CMD, POST_LT_ADJ_REQ_GRANTED, YES);
985980

986-
ret = nvkm_gsp_rm_ctrl_push(&disp->rm.objcom, &ctrl, sizeof(*ctrl));
987-
if (ret) {
988-
nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
989-
return ret;
981+
/* We should retry up to 3 times, but only if GSP asks politely */
982+
for (retries = 0; retries < 3; ++retries) {
983+
ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom, NV0073_CTRL_CMD_DP_CTRL,
984+
sizeof(*ctrl));
985+
if (IS_ERR(ctrl))
986+
return PTR_ERR(ctrl);
987+
988+
ctrl->subDeviceInstance = 0;
989+
ctrl->displayId = BIT(outp->index);
990+
ctrl->retryTimeMs = 0;
991+
ctrl->cmd = cmd;
992+
ctrl->data = data;
993+
994+
ret = nvkm_gsp_rm_ctrl_push(&disp->rm.objcom, &ctrl, sizeof(*ctrl));
995+
if (ret == -EAGAIN && ctrl->retryTimeMs) {
996+
/*
997+
* Device (likely an eDP panel) isn't ready yet, wait for the time specified
998+
* by GSP before retrying again
999+
*/
1000+
nvkm_debug(&disp->engine.subdev,
1001+
"Waiting %dms for GSP LT panel delay before retrying\n",
1002+
ctrl->retryTimeMs);
1003+
msleep(ctrl->retryTimeMs);
1004+
nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
1005+
} else {
1006+
/* GSP didn't say to retry, or we were successful */
1007+
if (ctrl->err)
1008+
ret = -EIO;
1009+
nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
1010+
break;
1011+
}
9901012
}
9911013

992-
ret = ctrl->err ? -EIO : 0;
993-
nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
9941014
return ret;
9951015
}
9961016

0 commit comments

Comments
 (0)