From d9c9134f5968f2a882395305e1f55648de63d328 Mon Sep 17 00:00:00 2001 From: Damien Diederen Date: Sat, 22 Mar 2014 17:59:55 +0100 Subject: [PATCH] [RFC] drm/nv50: (Partially) re-enable DPMS over DP Commit 0a0afd28 (drm/nv50-/disp: move DP link training to core and train from supervisor) removed a call to 'nouveau_dp_dpms' at the bottom of nv50_display.c. Without this call, 'xset dpms force {on,off}' does not have any effect on my DP-attached monitor. This proof-of-concept patch re-adds the call, as well as a partial version of nouveau_dp_dpms which causes 'force off' to work again. It is not clear to me how to trigger link training in the supervisor, so nouveau_dp_dpms skips that step when handling DRM_MODE_DPMS_ON. The result is that 'force on' does not cause the monitor to wake up, and the connection is effectively dead. Could somebody familiar with the driver could comment on the next steps to undertake to restore the full {on,off} functionality? --- drivers/gpu/drm/nouveau/nouveau_dp.c | 26 ++++++++++++++++++++++++++ drivers/gpu/drm/nouveau/nv50_display.c | 3 +++ 2 files changed, 29 insertions(+) diff --git a/drivers/gpu/drm/nouveau/nouveau_dp.c b/drivers/gpu/drm/nouveau/nouveau_dp.c index 36fd225..4c8c554 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dp.c +++ b/drivers/gpu/drm/nouveau/nouveau_dp.c @@ -94,3 +94,29 @@ nouveau_dp_detect(struct drm_encoder *encoder) return true; } + +void +nouveau_dp_dpms(struct drm_encoder *encoder, int mode, u32 datarate, + struct nouveau_object *core) +{ + struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); + struct nouveau_i2c_port *auxch; + u8 status; + + auxch = nv_encoder->i2c; + if (!auxch) + return; + + if (mode == DRM_MODE_DPMS_ON) + status = DP_SET_POWER_D0; + else + status = DP_SET_POWER_D3; + + nv_wraux(auxch, DP_SET_POWER, &status, 1); + + /* FIXME */ + /* + if (mode == DRM_MODE_DPMS_ON) + nouveau_dp_train(...); + */ +} diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 2dccafc..0c6ceb1 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -1740,6 +1740,9 @@ nv50_sor_dpms(struct drm_encoder *encoder, int mode) } nv_call(disp->core, NV50_DISP_SOR_PWR + or, (mode == DRM_MODE_DPMS_ON)); + + if (nv_encoder->dcb->type == DCB_OUTPUT_DP) + nouveau_dp_dpms(encoder, mode, nv_encoder->dp.datarate, disp->core); } static bool -- 1.9.1