diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_dp.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_dp.c | 74 |
1 files changed, 45 insertions, 29 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_dp.c b/drivers/gpu/drm/nouveau/nouveau_dp.c index 6fe11f8c5f6c..78e54cb8dfbe 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dp.c +++ b/drivers/gpu/drm/nouveau/nouveau_dp.c | |||
@@ -25,31 +25,35 @@ | |||
25 | #include "drmP.h" | 25 | #include "drmP.h" |
26 | #include "drm_dp_helper.h" | 26 | #include "drm_dp_helper.h" |
27 | 27 | ||
28 | #include "nouveau_drv.h" | 28 | #include "nouveau_drm.h" |
29 | #include "nouveau_connector.h" | 29 | #include "nouveau_connector.h" |
30 | #include "nouveau_encoder.h" | 30 | #include "nouveau_encoder.h" |
31 | #include "nouveau_crtc.h" | 31 | #include "nouveau_crtc.h" |
32 | 32 | ||
33 | #include <subdev/gpio.h> | ||
34 | #include <subdev/i2c.h> | ||
35 | |||
33 | u8 * | 36 | u8 * |
34 | nouveau_dp_bios_data(struct drm_device *dev, struct dcb_output *dcb, u8 **entry) | 37 | nouveau_dp_bios_data(struct drm_device *dev, struct dcb_output *dcb, u8 **entry) |
35 | { | 38 | { |
39 | struct nouveau_drm *drm = nouveau_drm(dev); | ||
36 | struct bit_entry d; | 40 | struct bit_entry d; |
37 | u8 *table; | 41 | u8 *table; |
38 | int i; | 42 | int i; |
39 | 43 | ||
40 | if (bit_table(dev, 'd', &d)) { | 44 | if (bit_table(dev, 'd', &d)) { |
41 | NV_ERROR(dev, "BIT 'd' table not found\n"); | 45 | NV_ERROR(drm, "BIT 'd' table not found\n"); |
42 | return NULL; | 46 | return NULL; |
43 | } | 47 | } |
44 | 48 | ||
45 | if (d.version != 1) { | 49 | if (d.version != 1) { |
46 | NV_ERROR(dev, "BIT 'd' table version %d unknown\n", d.version); | 50 | NV_ERROR(drm, "BIT 'd' table version %d unknown\n", d.version); |
47 | return NULL; | 51 | return NULL; |
48 | } | 52 | } |
49 | 53 | ||
50 | table = ROMPTR(dev, d.data[0]); | 54 | table = ROMPTR(dev, d.data[0]); |
51 | if (!table) { | 55 | if (!table) { |
52 | NV_ERROR(dev, "displayport table pointer invalid\n"); | 56 | NV_ERROR(drm, "displayport table pointer invalid\n"); |
53 | return NULL; | 57 | return NULL; |
54 | } | 58 | } |
55 | 59 | ||
@@ -60,7 +64,7 @@ nouveau_dp_bios_data(struct drm_device *dev, struct dcb_output *dcb, u8 **entry) | |||
60 | case 0x40: | 64 | case 0x40: |
61 | break; | 65 | break; |
62 | default: | 66 | default: |
63 | NV_ERROR(dev, "displayport table 0x%02x unknown\n", table[0]); | 67 | NV_ERROR(drm, "displayport table 0x%02x unknown\n", table[0]); |
64 | return NULL; | 68 | return NULL; |
65 | } | 69 | } |
66 | 70 | ||
@@ -70,7 +74,7 @@ nouveau_dp_bios_data(struct drm_device *dev, struct dcb_output *dcb, u8 **entry) | |||
70 | return table; | 74 | return table; |
71 | } | 75 | } |
72 | 76 | ||
73 | NV_ERROR(dev, "displayport encoder table not found\n"); | 77 | NV_ERROR(drm, "displayport encoder table not found\n"); |
74 | return NULL; | 78 | return NULL; |
75 | } | 79 | } |
76 | 80 | ||
@@ -92,9 +96,10 @@ struct dp_state { | |||
92 | static void | 96 | static void |
93 | dp_set_link_config(struct drm_device *dev, struct dp_state *dp) | 97 | dp_set_link_config(struct drm_device *dev, struct dp_state *dp) |
94 | { | 98 | { |
99 | struct nouveau_drm *drm = nouveau_drm(dev); | ||
95 | u8 sink[2]; | 100 | u8 sink[2]; |
96 | 101 | ||
97 | NV_DEBUG_KMS(dev, "%d lanes at %d KB/s\n", dp->link_nr, dp->link_bw); | 102 | NV_DEBUG(drm, "%d lanes at %d KB/s\n", dp->link_nr, dp->link_bw); |
98 | 103 | ||
99 | /* set desired link configuration on the source */ | 104 | /* set desired link configuration on the source */ |
100 | dp->func->link_set(dev, dp->dcb, dp->crtc, dp->link_nr, dp->link_bw, | 105 | dp->func->link_set(dev, dp->dcb, dp->crtc, dp->link_nr, dp->link_bw, |
@@ -106,27 +111,29 @@ dp_set_link_config(struct drm_device *dev, struct dp_state *dp) | |||
106 | if (dp->dpcd[2] & DP_ENHANCED_FRAME_CAP) | 111 | if (dp->dpcd[2] & DP_ENHANCED_FRAME_CAP) |
107 | sink[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN; | 112 | sink[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN; |
108 | 113 | ||
109 | auxch_wr(dev, dp->auxch, DP_LINK_BW_SET, sink, 2); | 114 | nv_wraux(dp->auxch, DP_LINK_BW_SET, sink, 2); |
110 | } | 115 | } |
111 | 116 | ||
112 | static void | 117 | static void |
113 | dp_set_training_pattern(struct drm_device *dev, struct dp_state *dp, u8 pattern) | 118 | dp_set_training_pattern(struct drm_device *dev, struct dp_state *dp, u8 pattern) |
114 | { | 119 | { |
120 | struct nouveau_drm *drm = nouveau_drm(dev); | ||
115 | u8 sink_tp; | 121 | u8 sink_tp; |
116 | 122 | ||
117 | NV_DEBUG_KMS(dev, "training pattern %d\n", pattern); | 123 | NV_DEBUG(drm, "training pattern %d\n", pattern); |
118 | 124 | ||
119 | dp->func->train_set(dev, dp->dcb, pattern); | 125 | dp->func->train_set(dev, dp->dcb, pattern); |
120 | 126 | ||
121 | auxch_rd(dev, dp->auxch, DP_TRAINING_PATTERN_SET, &sink_tp, 1); | 127 | nv_rdaux(dp->auxch, DP_TRAINING_PATTERN_SET, &sink_tp, 1); |
122 | sink_tp &= ~DP_TRAINING_PATTERN_MASK; | 128 | sink_tp &= ~DP_TRAINING_PATTERN_MASK; |
123 | sink_tp |= pattern; | 129 | sink_tp |= pattern; |
124 | auxch_wr(dev, dp->auxch, DP_TRAINING_PATTERN_SET, &sink_tp, 1); | 130 | nv_wraux(dp->auxch, DP_TRAINING_PATTERN_SET, &sink_tp, 1); |
125 | } | 131 | } |
126 | 132 | ||
127 | static int | 133 | static int |
128 | dp_link_train_commit(struct drm_device *dev, struct dp_state *dp) | 134 | dp_link_train_commit(struct drm_device *dev, struct dp_state *dp) |
129 | { | 135 | { |
136 | struct nouveau_drm *drm = nouveau_drm(dev); | ||
130 | int i; | 137 | int i; |
131 | 138 | ||
132 | for (i = 0; i < dp->link_nr; i++) { | 139 | for (i = 0; i < dp->link_nr; i++) { |
@@ -140,25 +147,26 @@ dp_link_train_commit(struct drm_device *dev, struct dp_state *dp) | |||
140 | if ((lpre << 3) == DP_TRAIN_PRE_EMPHASIS_9_5) | 147 | if ((lpre << 3) == DP_TRAIN_PRE_EMPHASIS_9_5) |
141 | dp->conf[i] |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED; | 148 | dp->conf[i] |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED; |
142 | 149 | ||
143 | NV_DEBUG_KMS(dev, "config lane %d %02x\n", i, dp->conf[i]); | 150 | NV_DEBUG(drm, "config lane %d %02x\n", i, dp->conf[i]); |
144 | dp->func->train_adj(dev, dp->dcb, i, lvsw, lpre); | 151 | dp->func->train_adj(dev, dp->dcb, i, lvsw, lpre); |
145 | } | 152 | } |
146 | 153 | ||
147 | return auxch_wr(dev, dp->auxch, DP_TRAINING_LANE0_SET, dp->conf, 4); | 154 | return nv_wraux(dp->auxch, DP_TRAINING_LANE0_SET, dp->conf, 4); |
148 | } | 155 | } |
149 | 156 | ||
150 | static int | 157 | static int |
151 | dp_link_train_update(struct drm_device *dev, struct dp_state *dp, u32 delay) | 158 | dp_link_train_update(struct drm_device *dev, struct dp_state *dp, u32 delay) |
152 | { | 159 | { |
160 | struct nouveau_drm *drm = nouveau_drm(dev); | ||
153 | int ret; | 161 | int ret; |
154 | 162 | ||
155 | udelay(delay); | 163 | udelay(delay); |
156 | 164 | ||
157 | ret = auxch_rd(dev, dp->auxch, DP_LANE0_1_STATUS, dp->stat, 6); | 165 | ret = nv_rdaux(dp->auxch, DP_LANE0_1_STATUS, dp->stat, 6); |
158 | if (ret) | 166 | if (ret) |
159 | return ret; | 167 | return ret; |
160 | 168 | ||
161 | NV_DEBUG_KMS(dev, "status %02x %02x %02x %02x %02x %02x\n", | 169 | NV_DEBUG(drm, "status %02x %02x %02x %02x %02x %02x\n", |
162 | dp->stat[0], dp->stat[1], dp->stat[2], dp->stat[3], | 170 | dp->stat[0], dp->stat[1], dp->stat[2], dp->stat[3], |
163 | dp->stat[4], dp->stat[5]); | 171 | dp->stat[4], dp->stat[5]); |
164 | return 0; | 172 | return 0; |
@@ -287,11 +295,14 @@ nouveau_dp_link_train(struct drm_encoder *encoder, u32 datarate, | |||
287 | struct nouveau_connector *nv_connector = | 295 | struct nouveau_connector *nv_connector = |
288 | nouveau_encoder_connector_get(nv_encoder); | 296 | nouveau_encoder_connector_get(nv_encoder); |
289 | struct drm_device *dev = encoder->dev; | 297 | struct drm_device *dev = encoder->dev; |
298 | struct nouveau_drm *drm = nouveau_drm(dev); | ||
299 | struct nouveau_i2c *i2c = nouveau_i2c(drm->device); | ||
300 | struct nouveau_gpio *gpio = nouveau_gpio(drm->device); | ||
290 | const u32 bw_list[] = { 270000, 162000, 0 }; | 301 | const u32 bw_list[] = { 270000, 162000, 0 }; |
291 | const u32 *link_bw = bw_list; | 302 | const u32 *link_bw = bw_list; |
292 | struct dp_state dp; | 303 | struct dp_state dp; |
293 | 304 | ||
294 | dp.auxch = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index); | 305 | dp.auxch = i2c->find(i2c, nv_encoder->dcb->i2c_index); |
295 | if (!dp.auxch) | 306 | if (!dp.auxch) |
296 | return false; | 307 | return false; |
297 | 308 | ||
@@ -307,7 +318,7 @@ nouveau_dp_link_train(struct drm_encoder *encoder, u32 datarate, | |||
307 | * we take during link training (DP_SET_POWER is one), we need | 318 | * we take during link training (DP_SET_POWER is one), we need |
308 | * to ignore them for the moment to avoid races. | 319 | * to ignore them for the moment to avoid races. |
309 | */ | 320 | */ |
310 | nouveau_gpio_irq(dev, 0, nv_connector->hpd, 0xff, false); | 321 | gpio->irq(gpio, 0, nv_connector->hpd, 0xff, false); |
311 | 322 | ||
312 | /* enable down-spreading, if possible */ | 323 | /* enable down-spreading, if possible */ |
313 | dp_set_downspread(dev, &dp, nv_encoder->dp.dpcd[3] & 1); | 324 | dp_set_downspread(dev, &dp, nv_encoder->dp.dpcd[3] & 1); |
@@ -350,7 +361,7 @@ nouveau_dp_link_train(struct drm_encoder *encoder, u32 datarate, | |||
350 | dp_link_train_fini(dev, &dp); | 361 | dp_link_train_fini(dev, &dp); |
351 | 362 | ||
352 | /* re-enable hotplug detect */ | 363 | /* re-enable hotplug detect */ |
353 | nouveau_gpio_irq(dev, 0, nv_connector->hpd, 0xff, true); | 364 | gpio->irq(gpio, 0, nv_connector->hpd, 0xff, true); |
354 | return true; | 365 | return true; |
355 | } | 366 | } |
356 | 367 | ||
@@ -359,10 +370,12 @@ nouveau_dp_dpms(struct drm_encoder *encoder, int mode, u32 datarate, | |||
359 | struct dp_train_func *func) | 370 | struct dp_train_func *func) |
360 | { | 371 | { |
361 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | 372 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); |
373 | struct nouveau_drm *drm = nouveau_drm(encoder->dev); | ||
374 | struct nouveau_i2c *i2c = nouveau_i2c(drm->device); | ||
362 | struct nouveau_i2c_port *auxch; | 375 | struct nouveau_i2c_port *auxch; |
363 | u8 status; | 376 | u8 status; |
364 | 377 | ||
365 | auxch = nouveau_i2c_find(encoder->dev, nv_encoder->dcb->i2c_index); | 378 | auxch = i2c->find(i2c, nv_encoder->dcb->i2c_index); |
366 | if (!auxch) | 379 | if (!auxch) |
367 | return; | 380 | return; |
368 | 381 | ||
@@ -371,7 +384,7 @@ nouveau_dp_dpms(struct drm_encoder *encoder, int mode, u32 datarate, | |||
371 | else | 384 | else |
372 | status = DP_SET_POWER_D3; | 385 | status = DP_SET_POWER_D3; |
373 | 386 | ||
374 | auxch_wr(encoder->dev, auxch, DP_SET_POWER, &status, 1); | 387 | nv_wraux(auxch, DP_SET_POWER, &status, 1); |
375 | 388 | ||
376 | if (mode == DRM_MODE_DPMS_ON) | 389 | if (mode == DRM_MODE_DPMS_ON) |
377 | nouveau_dp_link_train(encoder, datarate, func); | 390 | nouveau_dp_link_train(encoder, datarate, func); |
@@ -381,17 +394,18 @@ static void | |||
381 | nouveau_dp_probe_oui(struct drm_device *dev, struct nouveau_i2c_port *auxch, | 394 | nouveau_dp_probe_oui(struct drm_device *dev, struct nouveau_i2c_port *auxch, |
382 | u8 *dpcd) | 395 | u8 *dpcd) |
383 | { | 396 | { |
397 | struct nouveau_drm *drm = nouveau_drm(dev); | ||
384 | u8 buf[3]; | 398 | u8 buf[3]; |
385 | 399 | ||
386 | if (!(dpcd[DP_DOWN_STREAM_PORT_COUNT] & DP_OUI_SUPPORT)) | 400 | if (!(dpcd[DP_DOWN_STREAM_PORT_COUNT] & DP_OUI_SUPPORT)) |
387 | return; | 401 | return; |
388 | 402 | ||
389 | if (!auxch_rd(dev, auxch, DP_SINK_OUI, buf, 3)) | 403 | if (!nv_rdaux(auxch, DP_SINK_OUI, buf, 3)) |
390 | NV_DEBUG_KMS(dev, "Sink OUI: %02hx%02hx%02hx\n", | 404 | NV_DEBUG(drm, "Sink OUI: %02hx%02hx%02hx\n", |
391 | buf[0], buf[1], buf[2]); | 405 | buf[0], buf[1], buf[2]); |
392 | 406 | ||
393 | if (!auxch_rd(dev, auxch, DP_BRANCH_OUI, buf, 3)) | 407 | if (!nv_rdaux(auxch, DP_BRANCH_OUI, buf, 3)) |
394 | NV_DEBUG_KMS(dev, "Branch OUI: %02hx%02hx%02hx\n", | 408 | NV_DEBUG(drm, "Branch OUI: %02hx%02hx%02hx\n", |
395 | buf[0], buf[1], buf[2]); | 409 | buf[0], buf[1], buf[2]); |
396 | 410 | ||
397 | } | 411 | } |
@@ -401,24 +415,26 @@ nouveau_dp_detect(struct drm_encoder *encoder) | |||
401 | { | 415 | { |
402 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | 416 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); |
403 | struct drm_device *dev = encoder->dev; | 417 | struct drm_device *dev = encoder->dev; |
418 | struct nouveau_drm *drm = nouveau_drm(dev); | ||
419 | struct nouveau_i2c *i2c = nouveau_i2c(drm->device); | ||
404 | struct nouveau_i2c_port *auxch; | 420 | struct nouveau_i2c_port *auxch; |
405 | u8 *dpcd = nv_encoder->dp.dpcd; | 421 | u8 *dpcd = nv_encoder->dp.dpcd; |
406 | int ret; | 422 | int ret; |
407 | 423 | ||
408 | auxch = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index); | 424 | auxch = i2c->find(i2c, nv_encoder->dcb->i2c_index); |
409 | if (!auxch) | 425 | if (!auxch) |
410 | return false; | 426 | return false; |
411 | 427 | ||
412 | ret = auxch_rd(dev, auxch, DP_DPCD_REV, dpcd, 8); | 428 | ret = nv_rdaux(auxch, DP_DPCD_REV, dpcd, 8); |
413 | if (ret) | 429 | if (ret) |
414 | return false; | 430 | return false; |
415 | 431 | ||
416 | nv_encoder->dp.link_bw = 27000 * dpcd[1]; | 432 | nv_encoder->dp.link_bw = 27000 * dpcd[1]; |
417 | nv_encoder->dp.link_nr = dpcd[2] & DP_MAX_LANE_COUNT_MASK; | 433 | nv_encoder->dp.link_nr = dpcd[2] & DP_MAX_LANE_COUNT_MASK; |
418 | 434 | ||
419 | NV_DEBUG_KMS(dev, "display: %dx%d dpcd 0x%02x\n", | 435 | NV_DEBUG(drm, "display: %dx%d dpcd 0x%02x\n", |
420 | nv_encoder->dp.link_nr, nv_encoder->dp.link_bw, dpcd[0]); | 436 | nv_encoder->dp.link_nr, nv_encoder->dp.link_bw, dpcd[0]); |
421 | NV_DEBUG_KMS(dev, "encoder: %dx%d\n", | 437 | NV_DEBUG(drm, "encoder: %dx%d\n", |
422 | nv_encoder->dcb->dpconf.link_nr, | 438 | nv_encoder->dcb->dpconf.link_nr, |
423 | nv_encoder->dcb->dpconf.link_bw); | 439 | nv_encoder->dcb->dpconf.link_bw); |
424 | 440 | ||
@@ -427,7 +443,7 @@ nouveau_dp_detect(struct drm_encoder *encoder) | |||
427 | if (nv_encoder->dcb->dpconf.link_bw < nv_encoder->dp.link_bw) | 443 | if (nv_encoder->dcb->dpconf.link_bw < nv_encoder->dp.link_bw) |
428 | nv_encoder->dp.link_bw = nv_encoder->dcb->dpconf.link_bw; | 444 | nv_encoder->dp.link_bw = nv_encoder->dcb->dpconf.link_bw; |
429 | 445 | ||
430 | NV_DEBUG_KMS(dev, "maximum: %dx%d\n", | 446 | NV_DEBUG(drm, "maximum: %dx%d\n", |
431 | nv_encoder->dp.link_nr, nv_encoder->dp.link_bw); | 447 | nv_encoder->dp.link_nr, nv_encoder->dp.link_bw); |
432 | 448 | ||
433 | nouveau_dp_probe_oui(dev, auxch, dpcd); | 449 | nouveau_dp_probe_oui(dev, auxch, dpcd); |