summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2016-02-18 08:14:19 +1000
committerBen Skeggs <bskeggs@redhat.com>2016-02-25 13:21:50 +1000
commit8607b0ecabd446c934a1733625bb5b4cd8bde970 (patch)
treee60d54b86239bb61c8632b3cfa387dd28c59048e
parentf8d85a91b0c92c2f0041bbd83ead15059831dcd9 (diff)
downloadnouveau-8607b0ecabd446c934a1733625bb5b4cd8bde970.tar.gz
disp/dp: ensure sink is powered up before attempting link training
This can happen under some annoying circumstances, and is a quick fix until more substantial changes can be made. Fixed eDP mode changes on (at least) the Lenovo P50. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r--drm/nouveau/nvkm/engine/disp/dport.c10
-rw-r--r--drm/nouveau/nvkm/engine/disp/dport.h6
2 files changed, 16 insertions, 0 deletions
diff --git a/drm/nouveau/nvkm/engine/disp/dport.c b/drm/nouveau/nvkm/engine/disp/dport.c
index 74e2f7c6c..9688970ec 100644
--- a/drm/nouveau/nvkm/engine/disp/dport.c
+++ b/drm/nouveau/nvkm/engine/disp/dport.c
@@ -328,6 +328,7 @@ nvkm_dp_train(struct work_struct *w)
.outp = outp,
}, *dp = &_dp;
u32 datarate = 0;
+ u8 pwr;
int ret;
if (!outp->base.info.location && disp->func->sor.magic)
@@ -355,6 +356,15 @@ nvkm_dp_train(struct work_struct *w)
/* disable link interrupt handling during link training */
nvkm_notify_put(&outp->irq);
+ /* ensure sink is not in a low-power state */
+ if (!nvkm_rdaux(outp->aux, DPCD_SC00, &pwr, 1)) {
+ if ((pwr & DPCD_SC00_SET_POWER) != DPCD_SC00_SET_POWER_D0) {
+ pwr &= ~DPCD_SC00_SET_POWER;
+ pwr |= DPCD_SC00_SET_POWER_D0;
+ nvkm_wraux(outp->aux, DPCD_SC00, &pwr, 1);
+ }
+ }
+
/* enable down-spreading and execute pre-train script from vbios */
dp_link_train_init(dp, outp->dpcd[3] & 0x01);
diff --git a/drm/nouveau/nvkm/engine/disp/dport.h b/drm/nouveau/nvkm/engine/disp/dport.h
index 959629032..6e10c5e0e 100644
--- a/drm/nouveau/nvkm/engine/disp/dport.h
+++ b/drm/nouveau/nvkm/engine/disp/dport.h
@@ -71,5 +71,11 @@
#define DPCD_LS0C_LANE1_POST_CURSOR2 0x0c
#define DPCD_LS0C_LANE0_POST_CURSOR2 0x03
+/* DPCD Sink Control */
+#define DPCD_SC00 0x00600
+#define DPCD_SC00_SET_POWER 0x03
+#define DPCD_SC00_SET_POWER_D0 0x01
+#define DPCD_SC00_SET_POWER_D3 0x03
+
void nvkm_dp_train(struct work_struct *);
#endif