046b8e2
From 95664e66fad964c3dd7945d6edfb1d0931844664 Mon Sep 17 00:00:00 2001
046b8e2
From: Ben Skeggs <bskeggs@redhat.com>
046b8e2
Date: Thu, 18 Feb 2016 08:14:19 +1000
046b8e2
Subject: drm/nouveau/disp/dp: ensure sink is powered up before attempting link
046b8e2
 training
046b8e2
046b8e2
This can happen under some annoying circumstances, and is a quick fix
046b8e2
until more substantial changes can be made.
046b8e2
046b8e2
Fixed eDP mode changes on (at least) the Lenovo P50.
046b8e2
046b8e2
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
046b8e2
Cc: stable@vger.kernel.org
046b8e2
046b8e2
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dport.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dport.c
046b8e2
index 74e2f7c..9688970 100644
046b8e2
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dport.c
046b8e2
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dport.c
046b8e2
@@ -328,6 +328,7 @@ nvkm_dp_train(struct work_struct *w)
046b8e2
 		.outp = outp,
046b8e2
 	}, *dp = &_dp;
046b8e2
 	u32 datarate = 0;
046b8e2
+	u8  pwr;
046b8e2
 	int ret;
046b8e2
 
046b8e2
 	if (!outp->base.info.location && disp->func->sor.magic)
046b8e2
@@ -355,6 +356,15 @@ nvkm_dp_train(struct work_struct *w)
046b8e2
 	/* disable link interrupt handling during link training */
046b8e2
 	nvkm_notify_put(&outp->irq);
046b8e2
 
046b8e2
+	/* ensure sink is not in a low-power state */
046b8e2
+	if (!nvkm_rdaux(outp->aux, DPCD_SC00, &pwr, 1)) {
046b8e2
+		if ((pwr & DPCD_SC00_SET_POWER) != DPCD_SC00_SET_POWER_D0) {
046b8e2
+			pwr &= ~DPCD_SC00_SET_POWER;
046b8e2
+			pwr |=  DPCD_SC00_SET_POWER_D0;
046b8e2
+			nvkm_wraux(outp->aux, DPCD_SC00, &pwr, 1);
046b8e2
+		}
046b8e2
+	}
046b8e2
+
046b8e2
 	/* enable down-spreading and execute pre-train script from vbios */
046b8e2
 	dp_link_train_init(dp, outp->dpcd[3] & 0x01);
046b8e2
 
046b8e2
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dport.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dport.h
046b8e2
index 9596290..6e10c5e 100644
046b8e2
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dport.h
046b8e2
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dport.h
046b8e2
@@ -71,5 +71,11 @@
046b8e2
 #define DPCD_LS0C_LANE1_POST_CURSOR2                                       0x0c
046b8e2
 #define DPCD_LS0C_LANE0_POST_CURSOR2                                       0x03
046b8e2
 
046b8e2
+/* DPCD Sink Control */
046b8e2
+#define DPCD_SC00                                                       0x00600
046b8e2
+#define DPCD_SC00_SET_POWER                                                0x03
046b8e2
+#define DPCD_SC00_SET_POWER_D0                                             0x01
046b8e2
+#define DPCD_SC00_SET_POWER_D3                                             0x03
046b8e2
+
046b8e2
 void nvkm_dp_train(struct work_struct *);
046b8e2
 #endif
046b8e2
-- 
046b8e2
cgit v0.10.2
046b8e2