From: Ben Skeggs <bskeggs@xxxxxxxxxx> - fixes bug preventing this on SST - implement for MST Signed-off-by: Ben Skeggs <bskeggs@xxxxxxxxxx> Reviewed-by: Lyude Paul <lyude@xxxxxxxxxx> Acked-by: Danilo Krummrich <me@xxxxxxxx> Signed-off-by: Lyude Paul <lyude@xxxxxxxxxx> --- drivers/gpu/drm/nouveau/dispnv50/disp.c | 13 +++---------- drivers/gpu/drm/nouveau/nouveau_dp.c | 15 +++++++++++++++ drivers/gpu/drm/nouveau/nouveau_encoder.h | 1 + 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index 1fcd1b36a2751..1ea4b113058cd 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -1300,6 +1300,7 @@ nv50_mstm_cleanup(struct drm_atomic_state *state, } if (mstm->disabled) { + nouveau_dp_power_down(mstm->outp); nvif_outp_release(&mstm->outp->outp); mstm->disabled = false; } @@ -1551,7 +1552,6 @@ nv50_sor_atomic_disable(struct drm_encoder *encoder, struct drm_atomic_state *st #endif struct drm_dp_aux *aux = &nv_connector->aux; int ret; - u8 pwr; #ifdef CONFIG_DRM_NOUVEAU_BACKLIGHT if (backlight && backlight->uses_dpcd) { @@ -1568,15 +1568,8 @@ nv50_sor_atomic_disable(struct drm_encoder *encoder, struct drm_atomic_state *st nv_encoder->hdmi.enabled = false; } - if (nv_encoder->dcb->type == DCB_OUTPUT_DP) { - ret = drm_dp_dpcd_readb(aux, DP_SET_POWER, &pwr); - - if (ret == 0) { - pwr &= ~DP_SET_POWER_MASK; - pwr |= DP_SET_POWER_D3; - drm_dp_dpcd_writeb(aux, DP_SET_POWER, pwr); - } - } + if (nv_encoder->dcb->type == DCB_OUTPUT_DP) + nouveau_dp_power_down(nv_encoder); nv_encoder->update(nv_encoder, nv_crtc->index, NULL, 0, 0); nv50_audio_disable(encoder, nv_crtc); diff --git a/drivers/gpu/drm/nouveau/nouveau_dp.c b/drivers/gpu/drm/nouveau/nouveau_dp.c index f26769bca1950..1c0b992fe2416 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dp.c +++ b/drivers/gpu/drm/nouveau/nouveau_dp.c @@ -284,6 +284,21 @@ nouveau_dp_detect(struct nouveau_connector *nv_connector, return ret; } +void +nouveau_dp_power_down(struct nouveau_encoder *outp) +{ + struct drm_dp_aux *aux = &outp->conn->aux; + int ret; + u8 pwr; + + ret = drm_dp_dpcd_readb(aux, DP_SET_POWER, &pwr); + if (ret == 1) { + pwr &= ~DP_SET_POWER_MASK; + pwr |= DP_SET_POWER_D3; + drm_dp_dpcd_writeb(aux, DP_SET_POWER, pwr); + } +} + bool nouveau_dp_link_check(struct nouveau_connector *nv_connector) { diff --git a/drivers/gpu/drm/nouveau/nouveau_encoder.h b/drivers/gpu/drm/nouveau/nouveau_encoder.h index 123d0ecf5f586..ed31db58176c3 100644 --- a/drivers/gpu/drm/nouveau/nouveau_encoder.h +++ b/drivers/gpu/drm/nouveau/nouveau_encoder.h @@ -155,6 +155,7 @@ enum nouveau_dp_status { }; int nouveau_dp_detect(struct nouveau_connector *, struct nouveau_encoder *); +void nouveau_dp_power_down(struct nouveau_encoder *); bool nouveau_dp_link_check(struct nouveau_connector *); void nouveau_dp_irq(struct work_struct *); enum drm_mode_status nv50_dp_mode_valid(struct nouveau_encoder *, -- 2.41.0