Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

nouveau/dp: handle retries for AUX CH transfers with GSP.

eb284f4b3781 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: eb284f4b3781 ("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

+35 -24
+35 -24
drivers/gpu/drm/nouveau/nvkm/engine/disp/r535.c
··· 1060 1060 NV0073_CTRL_DP_AUXCH_CTRL_PARAMS *ctrl; 1061 1061 u8 size = *psize; 1062 1062 int ret; 1063 + int retries; 1063 1064 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); 1067 1069 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); 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); 1081 + 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 + } 1075 1100 } 1076 - ctrl->addr = addr; 1077 - ctrl->size = !ctrl->bAddrOnly ? (size - 1) : 0; 1078 - memcpy(ctrl->data, data, size); 1079 - 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; 1084 - } 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); 1090 1101 return ret; 1091 1102 } 1092 1103