diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2012-11-15 03:56:02 -0500 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2012-11-28 18:57:53 -0500 |
commit | 6c8e4633d351f6f794c8a5c03f19e8d5a25f9639 (patch) | |
tree | c7a834aed353c7dfc2e34e71c4dda40a51b48318 /drivers/gpu/drm/nouveau/nouveau_dp.c | |
parent | b6e4ad200a726a32c7083f491383713bc8680f86 (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.c | 34 |
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 | *****************************************************************************/ |
84 | struct dp_state { | 86 | struct 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 | |||
97 | dp_set_link_config(struct drm_device *dev, struct dp_state *dp) | 99 | dp_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 | |||
118 | dp_set_training_pattern(struct drm_device *dev, struct dp_state *dp, u8 pattern) | 127 | dp_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 | |||
134 | dp_link_train_commit(struct drm_device *dev, struct dp_state *dp) | 146 | dp_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 | ||
287 | static bool | 303 | static bool |
288 | nouveau_dp_link_train(struct drm_encoder *encoder, u32 datarate, | 304 | nouveau_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 | ||
366 | void | 382 | void |
367 | nouveau_dp_dpms(struct drm_encoder *encoder, int mode, u32 datarate, | 383 | nouveau_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 | ||
391 | static void | 407 | static void |