aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nouveau_dp.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-10-04 02:29:23 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-04 02:29:23 -0400
commit612a9aab56a93533e76e3ad91642db7033e03b69 (patch)
tree8402096973f67af941f9392f7da06cca03e0b58a /drivers/gpu/drm/nouveau/nouveau_dp.c
parent3a494318b14b1bc0f59d2d6ce84c505c74d82d2a (diff)
parent268d28371cd326be4dfcd7eba5917bf4b9d30c8f (diff)
Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux
Pull drm merge (part 1) from Dave Airlie: "So first of all my tree and uapi stuff has a conflict mess, its my fault as the nouveau stuff didn't hit -next as were trying to rebase regressions out of it before we merged. Highlights: - SH mobile modesetting driver and associated helpers - some DRM core documentation - i915 modesetting rework, haswell hdmi, haswell and vlv fixes, write combined pte writing, ilk rc6 support, - nouveau: major driver rework into a hw core driver, makes features like SLI a lot saner to implement, - psb: add eDP/DP support for Cedarview - radeon: 2 layer page tables, async VM pte updates, better PLL selection for > 2 screens, better ACPI interactions The rest is general grab bag of fixes. So why part 1? well I have the exynos pull req which came in a bit late but was waiting for me to do something they shouldn't have and it looks fairly safe, and David Howells has some more header cleanups he'd like me to pull, that seem like a good idea, but I'd like to get this merge out of the way so -next dosen't get blocked." Tons of conflicts mostly due to silly include line changes, but mostly mindless. A few other small semantic conflicts too, noted from Dave's pre-merged branch. * 'drm-next' of git://people.freedesktop.org/~airlied/linux: (447 commits) drm/nv98/crypt: fix fuc build with latest envyas drm/nouveau/devinit: fixup various issues with subdev ctor/init ordering drm/nv41/vm: fix and enable use of "real" pciegart drm/nv44/vm: fix and enable use of "real" pciegart drm/nv04/dmaobj: fixup vm target handling in preparation for nv4x pcie drm/nouveau: store supported dma mask in vmmgr drm/nvc0/ibus: initial implementation of subdev drm/nouveau/therm: add support for fan-control modes drm/nouveau/hwmon: rename pwm0* to pmw1* to follow hwmon's rules drm/nouveau/therm: calculate the pwm divisor on nv50+ drm/nouveau/fan: rewrite the fan tachometer driver to get more precision, faster drm/nouveau/therm: move thermal-related functions to the therm subdev drm/nouveau/bios: parse the pwm divisor from the perf table drm/nouveau/therm: use the EXTDEV table to detect i2c monitoring devices drm/nouveau/therm: rework thermal table parsing drm/nouveau/gpio: expose the PWM/TOGGLE parameter found in the gpio vbios table drm/nouveau: fix pm initialization order drm/nouveau/bios: check that fixed tvdac gpio data is valid before using it drm/nouveau: log channel debug/error messages from client object rather than drm client drm/nouveau: have drm debugging macros build on top of core macros ...
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_dp.c')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_dp.c280
1 files changed, 53 insertions, 227 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_dp.c b/drivers/gpu/drm/nouveau/nouveau_dp.c
index 898e5e32293c..978a108ba7a1 100644
--- a/drivers/gpu/drm/nouveau/nouveau_dp.c
+++ b/drivers/gpu/drm/nouveau/nouveau_dp.c
@@ -23,164 +23,37 @@
23 */ 23 */
24 24
25#include <drm/drmP.h> 25#include <drm/drmP.h>
26#include <drm/drm_dp_helper.h>
26 27
27#include "nouveau_drv.h" 28#include "nouveau_drm.h"
28#include "nouveau_i2c.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#include "nouveau_gpio.h"
33 32
34/****************************************************************************** 33#include <subdev/gpio.h>
35 * aux channel util functions 34#include <subdev/i2c.h>
36 *****************************************************************************/
37#define AUX_DBG(fmt, args...) do { \
38 if (nouveau_reg_debug & NOUVEAU_REG_DEBUG_AUXCH) { \
39 NV_PRINTK(KERN_DEBUG, dev, "AUXCH(%d): " fmt, ch, ##args); \
40 } \
41} while (0)
42#define AUX_ERR(fmt, args...) NV_ERROR(dev, "AUXCH(%d): " fmt, ch, ##args)
43
44static void
45auxch_fini(struct drm_device *dev, int ch)
46{
47 nv_mask(dev, 0x00e4e4 + (ch * 0x50), 0x00310000, 0x00000000);
48}
49
50static int
51auxch_init(struct drm_device *dev, int ch)
52{
53 const u32 unksel = 1; /* nfi which to use, or if it matters.. */
54 const u32 ureq = unksel ? 0x00100000 : 0x00200000;
55 const u32 urep = unksel ? 0x01000000 : 0x02000000;
56 u32 ctrl, timeout;
57
58 /* wait up to 1ms for any previous transaction to be done... */
59 timeout = 1000;
60 do {
61 ctrl = nv_rd32(dev, 0x00e4e4 + (ch * 0x50));
62 udelay(1);
63 if (!timeout--) {
64 AUX_ERR("begin idle timeout 0x%08x", ctrl);
65 return -EBUSY;
66 }
67 } while (ctrl & 0x03010000);
68
69 /* set some magic, and wait up to 1ms for it to appear */
70 nv_mask(dev, 0x00e4e4 + (ch * 0x50), 0x00300000, ureq);
71 timeout = 1000;
72 do {
73 ctrl = nv_rd32(dev, 0x00e4e4 + (ch * 0x50));
74 udelay(1);
75 if (!timeout--) {
76 AUX_ERR("magic wait 0x%08x\n", ctrl);
77 auxch_fini(dev, ch);
78 return -EBUSY;
79 }
80 } while ((ctrl & 0x03000000) != urep);
81
82 return 0;
83}
84
85static int
86auxch_tx(struct drm_device *dev, int ch, u8 type, u32 addr, u8 *data, u8 size)
87{
88 u32 ctrl, stat, timeout, retries;
89 u32 xbuf[4] = {};
90 int ret, i;
91
92 AUX_DBG("%d: 0x%08x %d\n", type, addr, size);
93
94 ret = auxch_init(dev, ch);
95 if (ret)
96 goto out;
97
98 stat = nv_rd32(dev, 0x00e4e8 + (ch * 0x50));
99 if (!(stat & 0x10000000)) {
100 AUX_DBG("sink not detected\n");
101 ret = -ENXIO;
102 goto out;
103 }
104
105 if (!(type & 1)) {
106 memcpy(xbuf, data, size);
107 for (i = 0; i < 16; i += 4) {
108 AUX_DBG("wr 0x%08x\n", xbuf[i / 4]);
109 nv_wr32(dev, 0x00e4c0 + (ch * 0x50) + i, xbuf[i / 4]);
110 }
111 }
112
113 ctrl = nv_rd32(dev, 0x00e4e4 + (ch * 0x50));
114 ctrl &= ~0x0001f0ff;
115 ctrl |= type << 12;
116 ctrl |= size - 1;
117 nv_wr32(dev, 0x00e4e0 + (ch * 0x50), addr);
118
119 /* retry transaction a number of times on failure... */
120 ret = -EREMOTEIO;
121 for (retries = 0; retries < 32; retries++) {
122 /* reset, and delay a while if this is a retry */
123 nv_wr32(dev, 0x00e4e4 + (ch * 0x50), 0x80000000 | ctrl);
124 nv_wr32(dev, 0x00e4e4 + (ch * 0x50), 0x00000000 | ctrl);
125 if (retries)
126 udelay(400);
127
128 /* transaction request, wait up to 1ms for it to complete */
129 nv_wr32(dev, 0x00e4e4 + (ch * 0x50), 0x00010000 | ctrl);
130
131 timeout = 1000;
132 do {
133 ctrl = nv_rd32(dev, 0x00e4e4 + (ch * 0x50));
134 udelay(1);
135 if (!timeout--) {
136 AUX_ERR("tx req timeout 0x%08x\n", ctrl);
137 goto out;
138 }
139 } while (ctrl & 0x00010000);
140
141 /* read status, and check if transaction completed ok */
142 stat = nv_mask(dev, 0x00e4e8 + (ch * 0x50), 0, 0);
143 if (!(stat & 0x000f0f00)) {
144 ret = 0;
145 break;
146 }
147
148 AUX_DBG("%02d 0x%08x 0x%08x\n", retries, ctrl, stat);
149 }
150
151 if (type & 1) {
152 for (i = 0; i < 16; i += 4) {
153 xbuf[i / 4] = nv_rd32(dev, 0x00e4d0 + (ch * 0x50) + i);
154 AUX_DBG("rd 0x%08x\n", xbuf[i / 4]);
155 }
156 memcpy(data, xbuf, size);
157 }
158
159out:
160 auxch_fini(dev, ch);
161 return ret;
162}
163 35
164u8 * 36u8 *
165nouveau_dp_bios_data(struct drm_device *dev, struct dcb_entry *dcb, u8 **entry) 37nouveau_dp_bios_data(struct drm_device *dev, struct dcb_output *dcb, u8 **entry)
166{ 38{
39 struct nouveau_drm *drm = nouveau_drm(dev);
167 struct bit_entry d; 40 struct bit_entry d;
168 u8 *table; 41 u8 *table;
169 int i; 42 int i;
170 43
171 if (bit_table(dev, 'd', &d)) { 44 if (bit_table(dev, 'd', &d)) {
172 NV_ERROR(dev, "BIT 'd' table not found\n"); 45 NV_ERROR(drm, "BIT 'd' table not found\n");
173 return NULL; 46 return NULL;
174 } 47 }
175 48
176 if (d.version != 1) { 49 if (d.version != 1) {
177 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);
178 return NULL; 51 return NULL;
179 } 52 }
180 53
181 table = ROMPTR(dev, d.data[0]); 54 table = ROMPTR(dev, d.data[0]);
182 if (!table) { 55 if (!table) {
183 NV_ERROR(dev, "displayport table pointer invalid\n"); 56 NV_ERROR(drm, "displayport table pointer invalid\n");
184 return NULL; 57 return NULL;
185 } 58 }
186 59
@@ -191,7 +64,7 @@ nouveau_dp_bios_data(struct drm_device *dev, struct dcb_entry *dcb, u8 **entry)
191 case 0x40: 64 case 0x40:
192 break; 65 break;
193 default: 66 default:
194 NV_ERROR(dev, "displayport table 0x%02x unknown\n", table[0]); 67 NV_ERROR(drm, "displayport table 0x%02x unknown\n", table[0]);
195 return NULL; 68 return NULL;
196 } 69 }
197 70
@@ -201,7 +74,7 @@ nouveau_dp_bios_data(struct drm_device *dev, struct dcb_entry *dcb, u8 **entry)
201 return table; 74 return table;
202 } 75 }
203 76
204 NV_ERROR(dev, "displayport encoder table not found\n"); 77 NV_ERROR(drm, "displayport encoder table not found\n");
205 return NULL; 78 return NULL;
206} 79}
207 80
@@ -209,9 +82,9 @@ nouveau_dp_bios_data(struct drm_device *dev, struct dcb_entry *dcb, u8 **entry)
209 * link training 82 * link training
210 *****************************************************************************/ 83 *****************************************************************************/
211struct dp_state { 84struct dp_state {
85 struct nouveau_i2c_port *auxch;
212 struct dp_train_func *func; 86 struct dp_train_func *func;
213 struct dcb_entry *dcb; 87 struct dcb_output *dcb;
214 int auxch;
215 int crtc; 88 int crtc;
216 u8 *dpcd; 89 u8 *dpcd;
217 int link_nr; 90 int link_nr;
@@ -223,9 +96,10 @@ struct dp_state {
223static void 96static void
224dp_set_link_config(struct drm_device *dev, struct dp_state *dp) 97dp_set_link_config(struct drm_device *dev, struct dp_state *dp)
225{ 98{
99 struct nouveau_drm *drm = nouveau_drm(dev);
226 u8 sink[2]; 100 u8 sink[2];
227 101
228 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);
229 103
230 /* set desired link configuration on the source */ 104 /* set desired link configuration on the source */
231 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,
@@ -237,27 +111,29 @@ dp_set_link_config(struct drm_device *dev, struct dp_state *dp)
237 if (dp->dpcd[2] & DP_ENHANCED_FRAME_CAP) 111 if (dp->dpcd[2] & DP_ENHANCED_FRAME_CAP)
238 sink[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN; 112 sink[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
239 113
240 auxch_tx(dev, dp->auxch, 8, DP_LINK_BW_SET, sink, 2); 114 nv_wraux(dp->auxch, DP_LINK_BW_SET, sink, 2);
241} 115}
242 116
243static void 117static void
244dp_set_training_pattern(struct drm_device *dev, struct dp_state *dp, u8 pattern) 118dp_set_training_pattern(struct drm_device *dev, struct dp_state *dp, u8 pattern)
245{ 119{
120 struct nouveau_drm *drm = nouveau_drm(dev);
246 u8 sink_tp; 121 u8 sink_tp;
247 122
248 NV_DEBUG_KMS(dev, "training pattern %d\n", pattern); 123 NV_DEBUG(drm, "training pattern %d\n", pattern);
249 124
250 dp->func->train_set(dev, dp->dcb, pattern); 125 dp->func->train_set(dev, dp->dcb, pattern);
251 126
252 auxch_tx(dev, dp->auxch, 9, DP_TRAINING_PATTERN_SET, &sink_tp, 1); 127 nv_rdaux(dp->auxch, DP_TRAINING_PATTERN_SET, &sink_tp, 1);
253 sink_tp &= ~DP_TRAINING_PATTERN_MASK; 128 sink_tp &= ~DP_TRAINING_PATTERN_MASK;
254 sink_tp |= pattern; 129 sink_tp |= pattern;
255 auxch_tx(dev, dp->auxch, 8, DP_TRAINING_PATTERN_SET, &sink_tp, 1); 130 nv_wraux(dp->auxch, DP_TRAINING_PATTERN_SET, &sink_tp, 1);
256} 131}
257 132
258static int 133static int
259dp_link_train_commit(struct drm_device *dev, struct dp_state *dp) 134dp_link_train_commit(struct drm_device *dev, struct dp_state *dp)
260{ 135{
136 struct nouveau_drm *drm = nouveau_drm(dev);
261 int i; 137 int i;
262 138
263 for (i = 0; i < dp->link_nr; i++) { 139 for (i = 0; i < dp->link_nr; i++) {
@@ -271,27 +147,26 @@ dp_link_train_commit(struct drm_device *dev, struct dp_state *dp)
271 if ((lpre << 3) == DP_TRAIN_PRE_EMPHASIS_9_5) 147 if ((lpre << 3) == DP_TRAIN_PRE_EMPHASIS_9_5)
272 dp->conf[i] |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED; 148 dp->conf[i] |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
273 149
274 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]);
275 dp->func->train_adj(dev, dp->dcb, i, lvsw, lpre); 151 dp->func->train_adj(dev, dp->dcb, i, lvsw, lpre);
276 } 152 }
277 153
278 return auxch_tx(dev, dp->auxch, 8, DP_TRAINING_LANE0_SET, dp->conf, 4); 154 return nv_wraux(dp->auxch, DP_TRAINING_LANE0_SET, dp->conf, 4);
279} 155}
280 156
281static int 157static int
282dp_link_train_update(struct drm_device *dev, struct dp_state *dp, u32 delay) 158dp_link_train_update(struct drm_device *dev, struct dp_state *dp, u32 delay)
283{ 159{
160 struct nouveau_drm *drm = nouveau_drm(dev);
284 int ret; 161 int ret;
285 162
286 udelay(delay); 163 udelay(delay);
287 164
288 ret = auxch_tx(dev, dp->auxch, 9, DP_LANE0_1_STATUS, dp->stat, 6); 165 ret = nv_rdaux(dp->auxch, DP_LANE0_1_STATUS, dp->stat, 6);
289 if (ret) 166 if (ret)
290 return ret; 167 return ret;
291 168
292 NV_DEBUG_KMS(dev, "status %02x %02x %02x %02x %02x %02x\n", 169 NV_DEBUG(drm, "status %*ph\n", 6, dp->stat);
293 dp->stat[0], dp->stat[1], dp->stat[2], dp->stat[3],
294 dp->stat[4], dp->stat[5]);
295 return 0; 170 return 0;
296} 171}
297 172
@@ -409,7 +284,7 @@ dp_link_train_fini(struct drm_device *dev, struct dp_state *dp)
409 nouveau_bios_run_init_table(dev, script, dp->dcb, dp->crtc); 284 nouveau_bios_run_init_table(dev, script, dp->dcb, dp->crtc);
410} 285}
411 286
412bool 287static bool
413nouveau_dp_link_train(struct drm_encoder *encoder, u32 datarate, 288nouveau_dp_link_train(struct drm_encoder *encoder, u32 datarate,
414 struct dp_train_func *func) 289 struct dp_train_func *func)
415{ 290{
@@ -418,19 +293,20 @@ nouveau_dp_link_train(struct drm_encoder *encoder, u32 datarate,
418 struct nouveau_connector *nv_connector = 293 struct nouveau_connector *nv_connector =
419 nouveau_encoder_connector_get(nv_encoder); 294 nouveau_encoder_connector_get(nv_encoder);
420 struct drm_device *dev = encoder->dev; 295 struct drm_device *dev = encoder->dev;
421 struct nouveau_i2c_chan *auxch; 296 struct nouveau_drm *drm = nouveau_drm(dev);
297 struct nouveau_i2c *i2c = nouveau_i2c(drm->device);
298 struct nouveau_gpio *gpio = nouveau_gpio(drm->device);
422 const u32 bw_list[] = { 270000, 162000, 0 }; 299 const u32 bw_list[] = { 270000, 162000, 0 };
423 const u32 *link_bw = bw_list; 300 const u32 *link_bw = bw_list;
424 struct dp_state dp; 301 struct dp_state dp;
425 302
426 auxch = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index); 303 dp.auxch = i2c->find(i2c, nv_encoder->dcb->i2c_index);
427 if (!auxch) 304 if (!dp.auxch)
428 return false; 305 return false;
429 306
430 dp.func = func; 307 dp.func = func;
431 dp.dcb = nv_encoder->dcb; 308 dp.dcb = nv_encoder->dcb;
432 dp.crtc = nv_crtc->index; 309 dp.crtc = nv_crtc->index;
433 dp.auxch = auxch->drive;
434 dp.dpcd = nv_encoder->dp.dpcd; 310 dp.dpcd = nv_encoder->dp.dpcd;
435 311
436 /* adjust required bandwidth for 8B/10B coding overhead */ 312 /* adjust required bandwidth for 8B/10B coding overhead */
@@ -440,7 +316,7 @@ nouveau_dp_link_train(struct drm_encoder *encoder, u32 datarate,
440 * we take during link training (DP_SET_POWER is one), we need 316 * we take during link training (DP_SET_POWER is one), we need
441 * to ignore them for the moment to avoid races. 317 * to ignore them for the moment to avoid races.
442 */ 318 */
443 nouveau_gpio_irq(dev, 0, nv_connector->hpd, 0xff, false); 319 gpio->irq(gpio, 0, nv_connector->hpd, 0xff, false);
444 320
445 /* enable down-spreading, if possible */ 321 /* enable down-spreading, if possible */
446 dp_set_downspread(dev, &dp, nv_encoder->dp.dpcd[3] & 1); 322 dp_set_downspread(dev, &dp, nv_encoder->dp.dpcd[3] & 1);
@@ -483,7 +359,7 @@ nouveau_dp_link_train(struct drm_encoder *encoder, u32 datarate,
483 dp_link_train_fini(dev, &dp); 359 dp_link_train_fini(dev, &dp);
484 360
485 /* re-enable hotplug detect */ 361 /* re-enable hotplug detect */
486 nouveau_gpio_irq(dev, 0, nv_connector->hpd, 0xff, true); 362 gpio->irq(gpio, 0, nv_connector->hpd, 0xff, true);
487 return true; 363 return true;
488} 364}
489 365
@@ -492,10 +368,12 @@ nouveau_dp_dpms(struct drm_encoder *encoder, int mode, u32 datarate,
492 struct dp_train_func *func) 368 struct dp_train_func *func)
493{ 369{
494 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); 370 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
495 struct nouveau_i2c_chan *auxch; 371 struct nouveau_drm *drm = nouveau_drm(encoder->dev);
372 struct nouveau_i2c *i2c = nouveau_i2c(drm->device);
373 struct nouveau_i2c_port *auxch;
496 u8 status; 374 u8 status;
497 375
498 auxch = nouveau_i2c_find(encoder->dev, nv_encoder->dcb->i2c_index); 376 auxch = i2c->find(i2c, nv_encoder->dcb->i2c_index);
499 if (!auxch) 377 if (!auxch)
500 return; 378 return;
501 379
@@ -504,27 +382,28 @@ nouveau_dp_dpms(struct drm_encoder *encoder, int mode, u32 datarate,
504 else 382 else
505 status = DP_SET_POWER_D3; 383 status = DP_SET_POWER_D3;
506 384
507 nouveau_dp_auxch(auxch, 8, DP_SET_POWER, &status, 1); 385 nv_wraux(auxch, DP_SET_POWER, &status, 1);
508 386
509 if (mode == DRM_MODE_DPMS_ON) 387 if (mode == DRM_MODE_DPMS_ON)
510 nouveau_dp_link_train(encoder, datarate, func); 388 nouveau_dp_link_train(encoder, datarate, func);
511} 389}
512 390
513static void 391static void
514nouveau_dp_probe_oui(struct drm_device *dev, struct nouveau_i2c_chan *auxch, 392nouveau_dp_probe_oui(struct drm_device *dev, struct nouveau_i2c_port *auxch,
515 u8 *dpcd) 393 u8 *dpcd)
516{ 394{
395 struct nouveau_drm *drm = nouveau_drm(dev);
517 u8 buf[3]; 396 u8 buf[3];
518 397
519 if (!(dpcd[DP_DOWN_STREAM_PORT_COUNT] & DP_OUI_SUPPORT)) 398 if (!(dpcd[DP_DOWN_STREAM_PORT_COUNT] & DP_OUI_SUPPORT))
520 return; 399 return;
521 400
522 if (!auxch_tx(dev, auxch->drive, 9, DP_SINK_OUI, buf, 3)) 401 if (!nv_rdaux(auxch, DP_SINK_OUI, buf, 3))
523 NV_DEBUG_KMS(dev, "Sink OUI: %02hx%02hx%02hx\n", 402 NV_DEBUG(drm, "Sink OUI: %02hx%02hx%02hx\n",
524 buf[0], buf[1], buf[2]); 403 buf[0], buf[1], buf[2]);
525 404
526 if (!auxch_tx(dev, auxch->drive, 9, DP_BRANCH_OUI, buf, 3)) 405 if (!nv_rdaux(auxch, DP_BRANCH_OUI, buf, 3))
527 NV_DEBUG_KMS(dev, "Branch OUI: %02hx%02hx%02hx\n", 406 NV_DEBUG(drm, "Branch OUI: %02hx%02hx%02hx\n",
528 buf[0], buf[1], buf[2]); 407 buf[0], buf[1], buf[2]);
529 408
530} 409}
@@ -534,24 +413,26 @@ nouveau_dp_detect(struct drm_encoder *encoder)
534{ 413{
535 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); 414 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
536 struct drm_device *dev = encoder->dev; 415 struct drm_device *dev = encoder->dev;
537 struct nouveau_i2c_chan *auxch; 416 struct nouveau_drm *drm = nouveau_drm(dev);
417 struct nouveau_i2c *i2c = nouveau_i2c(drm->device);
418 struct nouveau_i2c_port *auxch;
538 u8 *dpcd = nv_encoder->dp.dpcd; 419 u8 *dpcd = nv_encoder->dp.dpcd;
539 int ret; 420 int ret;
540 421
541 auxch = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index); 422 auxch = i2c->find(i2c, nv_encoder->dcb->i2c_index);
542 if (!auxch) 423 if (!auxch)
543 return false; 424 return false;
544 425
545 ret = auxch_tx(dev, auxch->drive, 9, DP_DPCD_REV, dpcd, 8); 426 ret = nv_rdaux(auxch, DP_DPCD_REV, dpcd, 8);
546 if (ret) 427 if (ret)
547 return false; 428 return false;
548 429
549 nv_encoder->dp.link_bw = 27000 * dpcd[1]; 430 nv_encoder->dp.link_bw = 27000 * dpcd[1];
550 nv_encoder->dp.link_nr = dpcd[2] & DP_MAX_LANE_COUNT_MASK; 431 nv_encoder->dp.link_nr = dpcd[2] & DP_MAX_LANE_COUNT_MASK;
551 432
552 NV_DEBUG_KMS(dev, "display: %dx%d dpcd 0x%02x\n", 433 NV_DEBUG(drm, "display: %dx%d dpcd 0x%02x\n",
553 nv_encoder->dp.link_nr, nv_encoder->dp.link_bw, dpcd[0]); 434 nv_encoder->dp.link_nr, nv_encoder->dp.link_bw, dpcd[0]);
554 NV_DEBUG_KMS(dev, "encoder: %dx%d\n", 435 NV_DEBUG(drm, "encoder: %dx%d\n",
555 nv_encoder->dcb->dpconf.link_nr, 436 nv_encoder->dcb->dpconf.link_nr,
556 nv_encoder->dcb->dpconf.link_bw); 437 nv_encoder->dcb->dpconf.link_bw);
557 438
@@ -560,65 +441,10 @@ nouveau_dp_detect(struct drm_encoder *encoder)
560 if (nv_encoder->dcb->dpconf.link_bw < nv_encoder->dp.link_bw) 441 if (nv_encoder->dcb->dpconf.link_bw < nv_encoder->dp.link_bw)
561 nv_encoder->dp.link_bw = nv_encoder->dcb->dpconf.link_bw; 442 nv_encoder->dp.link_bw = nv_encoder->dcb->dpconf.link_bw;
562 443
563 NV_DEBUG_KMS(dev, "maximum: %dx%d\n", 444 NV_DEBUG(drm, "maximum: %dx%d\n",
564 nv_encoder->dp.link_nr, nv_encoder->dp.link_bw); 445 nv_encoder->dp.link_nr, nv_encoder->dp.link_bw);
565 446
566 nouveau_dp_probe_oui(dev, auxch, dpcd); 447 nouveau_dp_probe_oui(dev, auxch, dpcd);
567 448
568 return true; 449 return true;
569} 450}
570
571int
572nouveau_dp_auxch(struct nouveau_i2c_chan *auxch, int cmd, int addr,
573 uint8_t *data, int data_nr)
574{
575 return auxch_tx(auxch->dev, auxch->drive, cmd, addr, data, data_nr);
576}
577
578static int
579nouveau_dp_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
580{
581 struct nouveau_i2c_chan *auxch = (struct nouveau_i2c_chan *)adap;
582 struct i2c_msg *msg = msgs;
583 int ret, mcnt = num;
584
585 while (mcnt--) {
586 u8 remaining = msg->len;
587 u8 *ptr = msg->buf;
588
589 while (remaining) {
590 u8 cnt = (remaining > 16) ? 16 : remaining;
591 u8 cmd;
592
593 if (msg->flags & I2C_M_RD)
594 cmd = AUX_I2C_READ;
595 else
596 cmd = AUX_I2C_WRITE;
597
598 if (mcnt || remaining > 16)
599 cmd |= AUX_I2C_MOT;
600
601 ret = nouveau_dp_auxch(auxch, cmd, msg->addr, ptr, cnt);
602 if (ret < 0)
603 return ret;
604
605 ptr += cnt;
606 remaining -= cnt;
607 }
608
609 msg++;
610 }
611
612 return num;
613}
614
615static u32
616nouveau_dp_i2c_func(struct i2c_adapter *adap)
617{
618 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
619}
620
621const struct i2c_algorithm nouveau_dp_i2c_algo = {
622 .master_xfer = nouveau_dp_i2c_xfer,
623 .functionality = nouveau_dp_i2c_func
624};