aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nouveau_dp.c
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2012-11-15 03:56:02 -0500
committerBen Skeggs <bskeggs@redhat.com>2012-11-28 18:57:53 -0500
commit6c8e4633d351f6f794c8a5c03f19e8d5a25f9639 (patch)
treec7a834aed353c7dfc2e34e71c4dda40a51b48318 /drivers/gpu/drm/nouveau/nouveau_dp.c
parentb6e4ad200a726a32c7083f491383713bc8680f86 (diff)
drm/nouveau/dp: move core link training calls to common code
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_dp.c')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_dp.c34
1 files changed, 25 insertions, 9 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_dp.c b/drivers/gpu/drm/nouveau/nouveau_dp.c
index 978a108ba7a1..e3f6550ae772 100644
--- a/drivers/gpu/drm/nouveau/nouveau_dp.c
+++ b/drivers/gpu/drm/nouveau/nouveau_dp.c
@@ -30,6 +30,8 @@
30#include "nouveau_encoder.h" 30#include "nouveau_encoder.h"
31#include "nouveau_crtc.h" 31#include "nouveau_crtc.h"
32 32
33#include <core/class.h>
34
33#include <subdev/gpio.h> 35#include <subdev/gpio.h>
34#include <subdev/i2c.h> 36#include <subdev/i2c.h>
35 37
@@ -83,7 +85,7 @@ nouveau_dp_bios_data(struct drm_device *dev, struct dcb_output *dcb, u8 **entry)
83 *****************************************************************************/ 85 *****************************************************************************/
84struct dp_state { 86struct dp_state {
85 struct nouveau_i2c_port *auxch; 87 struct nouveau_i2c_port *auxch;
86 struct dp_train_func *func; 88 struct nouveau_object *core;
87 struct dcb_output *dcb; 89 struct dcb_output *dcb;
88 int crtc; 90 int crtc;
89 u8 *dpcd; 91 u8 *dpcd;
@@ -97,13 +99,20 @@ static void
97dp_set_link_config(struct drm_device *dev, struct dp_state *dp) 99dp_set_link_config(struct drm_device *dev, struct dp_state *dp)
98{ 100{
99 struct nouveau_drm *drm = nouveau_drm(dev); 101 struct nouveau_drm *drm = nouveau_drm(dev);
102 struct dcb_output *dcb = dp->dcb;
103 const u32 or = ffs(dcb->or) - 1, link = !(dcb->sorconf.link & 1);
104 const u32 moff = (dp->crtc << 3) | (link << 2) | or;
100 u8 sink[2]; 105 u8 sink[2];
106 u32 data;
101 107
102 NV_DEBUG(drm, "%d lanes at %d KB/s\n", dp->link_nr, dp->link_bw); 108 NV_DEBUG(drm, "%d lanes at %d KB/s\n", dp->link_nr, dp->link_bw);
103 109
104 /* set desired link configuration on the source */ 110 /* set desired link configuration on the source */
105 dp->func->link_set(dev, dp->dcb, dp->crtc, dp->link_nr, dp->link_bw, 111 data = ((dp->link_bw / 27000) << 8) | dp->link_nr;
106 dp->dpcd[2] & DP_ENHANCED_FRAME_CAP); 112 if (dp->dpcd[2] & DP_ENHANCED_FRAME_CAP)
113 data |= NV94_DISP_SOR_DP_LNKCTL_FRAME_ENH;
114
115 nv_call(dp->core, NV94_DISP_SOR_DP_LNKCTL + moff, data);
107 116
108 /* inform the sink of the new configuration */ 117 /* inform the sink of the new configuration */
109 sink[0] = dp->link_bw / 27000; 118 sink[0] = dp->link_bw / 27000;
@@ -118,11 +127,14 @@ static void
118dp_set_training_pattern(struct drm_device *dev, struct dp_state *dp, u8 pattern) 127dp_set_training_pattern(struct drm_device *dev, struct dp_state *dp, u8 pattern)
119{ 128{
120 struct nouveau_drm *drm = nouveau_drm(dev); 129 struct nouveau_drm *drm = nouveau_drm(dev);
130 struct dcb_output *dcb = dp->dcb;
131 const u32 or = ffs(dcb->or) - 1, link = !(dcb->sorconf.link & 1);
132 const u32 moff = (dp->crtc << 3) | (link << 2) | or;
121 u8 sink_tp; 133 u8 sink_tp;
122 134
123 NV_DEBUG(drm, "training pattern %d\n", pattern); 135 NV_DEBUG(drm, "training pattern %d\n", pattern);
124 136
125 dp->func->train_set(dev, dp->dcb, pattern); 137 nv_call(dp->core, NV94_DISP_SOR_DP_TRAIN + moff, pattern);
126 138
127 nv_rdaux(dp->auxch, DP_TRAINING_PATTERN_SET, &sink_tp, 1); 139 nv_rdaux(dp->auxch, DP_TRAINING_PATTERN_SET, &sink_tp, 1);
128 sink_tp &= ~DP_TRAINING_PATTERN_MASK; 140 sink_tp &= ~DP_TRAINING_PATTERN_MASK;
@@ -134,6 +146,9 @@ static int
134dp_link_train_commit(struct drm_device *dev, struct dp_state *dp) 146dp_link_train_commit(struct drm_device *dev, struct dp_state *dp)
135{ 147{
136 struct nouveau_drm *drm = nouveau_drm(dev); 148 struct nouveau_drm *drm = nouveau_drm(dev);
149 struct dcb_output *dcb = dp->dcb;
150 const u32 or = ffs(dcb->or) - 1, link = !(dcb->sorconf.link & 1);
151 const u32 moff = (dp->crtc << 3) | (link << 2) | or;
137 int i; 152 int i;
138 153
139 for (i = 0; i < dp->link_nr; i++) { 154 for (i = 0; i < dp->link_nr; i++) {
@@ -148,7 +163,8 @@ dp_link_train_commit(struct drm_device *dev, struct dp_state *dp)
148 dp->conf[i] |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED; 163 dp->conf[i] |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
149 164
150 NV_DEBUG(drm, "config lane %d %02x\n", i, dp->conf[i]); 165 NV_DEBUG(drm, "config lane %d %02x\n", i, dp->conf[i]);
151 dp->func->train_adj(dev, dp->dcb, i, lvsw, lpre); 166
167 nv_call(dp->core, NV94_DISP_SOR_DP_DRVCTL(i) + moff, (lvsw << 8) | lpre);
152 } 168 }
153 169
154 return nv_wraux(dp->auxch, DP_TRAINING_LANE0_SET, dp->conf, 4); 170 return nv_wraux(dp->auxch, DP_TRAINING_LANE0_SET, dp->conf, 4);
@@ -286,7 +302,7 @@ dp_link_train_fini(struct drm_device *dev, struct dp_state *dp)
286 302
287static bool 303static bool
288nouveau_dp_link_train(struct drm_encoder *encoder, u32 datarate, 304nouveau_dp_link_train(struct drm_encoder *encoder, u32 datarate,
289 struct dp_train_func *func) 305 struct nouveau_object *core)
290{ 306{
291 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); 307 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
292 struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); 308 struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc);
@@ -304,7 +320,7 @@ nouveau_dp_link_train(struct drm_encoder *encoder, u32 datarate,
304 if (!dp.auxch) 320 if (!dp.auxch)
305 return false; 321 return false;
306 322
307 dp.func = func; 323 dp.core = core;
308 dp.dcb = nv_encoder->dcb; 324 dp.dcb = nv_encoder->dcb;
309 dp.crtc = nv_crtc->index; 325 dp.crtc = nv_crtc->index;
310 dp.dpcd = nv_encoder->dp.dpcd; 326 dp.dpcd = nv_encoder->dp.dpcd;
@@ -365,7 +381,7 @@ nouveau_dp_link_train(struct drm_encoder *encoder, u32 datarate,
365 381
366void 382void
367nouveau_dp_dpms(struct drm_encoder *encoder, int mode, u32 datarate, 383nouveau_dp_dpms(struct drm_encoder *encoder, int mode, u32 datarate,
368 struct dp_train_func *func) 384 struct nouveau_object *core)
369{ 385{
370 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); 386 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
371 struct nouveau_drm *drm = nouveau_drm(encoder->dev); 387 struct nouveau_drm *drm = nouveau_drm(encoder->dev);
@@ -385,7 +401,7 @@ nouveau_dp_dpms(struct drm_encoder *encoder, int mode, u32 datarate,
385 nv_wraux(auxch, DP_SET_POWER, &status, 1); 401 nv_wraux(auxch, DP_SET_POWER, &status, 1);
386 402
387 if (mode == DRM_MODE_DPMS_ON) 403 if (mode == DRM_MODE_DPMS_ON)
388 nouveau_dp_link_train(encoder, datarate, func); 404 nouveau_dp_link_train(encoder, datarate, core);
389} 405}
390 406
391static void 407static void