nouveau_connector.c 40.5 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/*
 * Copyright (C) 2008 Maarten Maathuis.
 * All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice (including the
 * next paragraph) shall be included in all copies or substantial
 * portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 */

27
28
#include <acpi/button.h>

29
#include <linux/pm_runtime.h>
30
#include <linux/vga_switcheroo.h>
31

32
#include <drm/drmP.h>
33
#include <drm/drm_atomic_helper.h>
34
35
#include <drm/drm_edid.h>
#include <drm/drm_crtc_helper.h>
36

37
#include "nouveau_reg.h"
38
#include "nouveau_drv.h"
39
#include "dispnv04/hw.h"
40
#include "nouveau_acpi.h"
41

42
43
#include "nouveau_display.h"
#include "nouveau_connector.h"
44
45
#include "nouveau_encoder.h"
#include "nouveau_crtc.h"
46

47
#include <nvif/class.h>
48
#include <nvif/cl0046.h>
49
50
#include <nvif/event.h>

51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
struct drm_display_mode *
nouveau_conn_native_mode(struct drm_connector *connector)
{
	const struct drm_connector_helper_funcs *helper = connector->helper_private;
	struct nouveau_drm *drm = nouveau_drm(connector->dev);
	struct drm_device *dev = connector->dev;
	struct drm_display_mode *mode, *largest = NULL;
	int high_w = 0, high_h = 0, high_v = 0;

	list_for_each_entry(mode, &connector->probed_modes, head) {
		mode->vrefresh = drm_mode_vrefresh(mode);
		if (helper->mode_valid(connector, mode) != MODE_OK ||
		    (mode->flags & DRM_MODE_FLAG_INTERLACE))
			continue;

		/* Use preferred mode if there is one.. */
		if (mode->type & DRM_MODE_TYPE_PREFERRED) {
			NV_DEBUG(drm, "native mode from preferred\n");
			return drm_mode_duplicate(dev, mode);
		}

		/* Otherwise, take the resolution with the largest width, then
		 * height, then vertical refresh
		 */
		if (mode->hdisplay < high_w)
			continue;

		if (mode->hdisplay == high_w && mode->vdisplay < high_h)
			continue;

		if (mode->hdisplay == high_w && mode->vdisplay == high_h &&
		    mode->vrefresh < high_v)
			continue;

		high_w = mode->hdisplay;
		high_h = mode->vdisplay;
		high_v = mode->vrefresh;
		largest = mode;
	}

	NV_DEBUG(drm, "native mode from largest: %dx%d@%d\n",
		      high_w, high_h, high_v);
	return largest ? drm_mode_duplicate(dev, largest) : NULL;
}

int
nouveau_conn_atomic_get_property(struct drm_connector *connector,
				 const struct drm_connector_state *state,
				 struct drm_property *property, u64 *val)
{
	struct nouveau_conn_atom *asyc = nouveau_conn_atom(state);
	struct nouveau_display *disp = nouveau_display(connector->dev);
	struct drm_device *dev = connector->dev;

	if (property == dev->mode_config.scaling_mode_property)
		*val = asyc->scaler.mode;
	else if (property == disp->underscan_property)
		*val = asyc->scaler.underscan.mode;
	else if (property == disp->underscan_hborder_property)
		*val = asyc->scaler.underscan.hborder;
	else if (property == disp->underscan_vborder_property)
		*val = asyc->scaler.underscan.vborder;
	else if (property == disp->dithering_mode)
		*val = asyc->dither.mode;
	else if (property == disp->dithering_depth)
		*val = asyc->dither.depth;
	else if (property == disp->vibrant_hue_property)
		*val = asyc->procamp.vibrant_hue;
	else if (property == disp->color_vibrance_property)
		*val = asyc->procamp.color_vibrance;
	else
		return -EINVAL;

	return 0;
}

int
nouveau_conn_atomic_set_property(struct drm_connector *connector,
				 struct drm_connector_state *state,
				 struct drm_property *property, u64 val)
{
	struct drm_device *dev = connector->dev;
	struct nouveau_conn_atom *asyc = nouveau_conn_atom(state);
	struct nouveau_display *disp = nouveau_display(dev);

	if (property == dev->mode_config.scaling_mode_property) {
		switch (val) {
		case DRM_MODE_SCALE_NONE:
			/* We allow 'None' for EDID modes, even on a fixed
			 * panel (some exist with support for lower refresh
			 * rates, which people might want to use for power-
			 * saving purposes).
			 *
			 * Non-EDID modes will force the use of GPU scaling
			 * to the native mode regardless of this setting.
			 */
			switch (connector->connector_type) {
			case DRM_MODE_CONNECTOR_LVDS:
			case DRM_MODE_CONNECTOR_eDP:
				/* ... except prior to G80, where the code
				 * doesn't support such things.
				 */
				if (disp->disp.oclass < NV50_DISP)
					return -EINVAL;
				break;
			default:
				break;
			}
		case DRM_MODE_SCALE_FULLSCREEN:
		case DRM_MODE_SCALE_CENTER:
		case DRM_MODE_SCALE_ASPECT:
			break;
		default:
			return -EINVAL;
		}

		if (asyc->scaler.mode != val) {
			asyc->scaler.mode = val;
			asyc->set.scaler = true;
		}
	} else
	if (property == disp->underscan_property) {
		if (asyc->scaler.underscan.mode != val) {
			asyc->scaler.underscan.mode = val;
			asyc->set.scaler = true;
		}
	} else
	if (property == disp->underscan_hborder_property) {
		if (asyc->scaler.underscan.hborder != val) {
			asyc->scaler.underscan.hborder = val;
			asyc->set.scaler = true;
		}
	} else
	if (property == disp->underscan_vborder_property) {
		if (asyc->scaler.underscan.vborder != val) {
			asyc->scaler.underscan.vborder = val;
			asyc->set.scaler = true;
		}
	} else
	if (property == disp->dithering_mode) {
		if (asyc->dither.mode != val) {
			asyc->dither.mode = val;
			asyc->set.dither = true;
		}
	} else
	if (property == disp->dithering_depth) {
		if (asyc->dither.mode != val) {
			asyc->dither.depth = val;
			asyc->set.dither = true;
		}
	} else
	if (property == disp->vibrant_hue_property) {
		if (asyc->procamp.vibrant_hue != val) {
			asyc->procamp.vibrant_hue = val;
			asyc->set.procamp = true;
		}
	} else
	if (property == disp->color_vibrance_property) {
		if (asyc->procamp.color_vibrance != val) {
			asyc->procamp.color_vibrance = val;
			asyc->set.procamp = true;
		}
	} else {
		return -EINVAL;
	}

	return 0;
}

void
nouveau_conn_atomic_destroy_state(struct drm_connector *connector,
				  struct drm_connector_state *state)
{
	struct nouveau_conn_atom *asyc = nouveau_conn_atom(state);
	__drm_atomic_helper_connector_destroy_state(&asyc->state);
	kfree(asyc);
}

struct drm_connector_state *
nouveau_conn_atomic_duplicate_state(struct drm_connector *connector)
{
	struct nouveau_conn_atom *armc = nouveau_conn_atom(connector->state);
	struct nouveau_conn_atom *asyc;
	if (!(asyc = kmalloc(sizeof(*asyc), GFP_KERNEL)))
		return NULL;
	__drm_atomic_helper_connector_duplicate_state(connector, &asyc->state);
	asyc->dither = armc->dither;
	asyc->scaler = armc->scaler;
	asyc->procamp = armc->procamp;
	asyc->set.mask = 0;
	return &asyc->state;
}

void
nouveau_conn_reset(struct drm_connector *connector)
{
	struct nouveau_conn_atom *asyc;

	if (WARN_ON(!(asyc = kzalloc(sizeof(*asyc), GFP_KERNEL))))
		return;

	if (connector->state)
		__drm_atomic_helper_connector_destroy_state(connector->state);
	__drm_atomic_helper_connector_reset(connector, &asyc->state);
	asyc->dither.mode = DITHERING_MODE_AUTO;
	asyc->dither.depth = DITHERING_DEPTH_AUTO;
	asyc->scaler.mode = DRM_MODE_SCALE_NONE;
	asyc->scaler.underscan.mode = UNDERSCAN_OFF;
	asyc->procamp.color_vibrance = 150;
	asyc->procamp.vibrant_hue = 90;

	if (nouveau_display(connector->dev)->disp.oclass < NV50_DISP) {
		switch (connector->connector_type) {
		case DRM_MODE_CONNECTOR_LVDS:
			/* See note in nouveau_conn_atomic_set_property(). */
			asyc->scaler.mode = DRM_MODE_SCALE_FULLSCREEN;
			break;
		default:
			break;
		}
	}
}

274
MODULE_PARM_DESC(tv_disable, "Disable TV-out detection");
275
int nouveau_tv_disable = 0;
276
277
278
module_param_named(tv_disable, nouveau_tv_disable, int, 0400);

MODULE_PARM_DESC(ignorelid, "Ignore ACPI lid status");
279
int nouveau_ignorelid = 0;
280
281
282
module_param_named(ignorelid, nouveau_ignorelid, int, 0400);

MODULE_PARM_DESC(duallink, "Allow dual-link TMDS (default: enabled)");
283
int nouveau_duallink = 1;
284
module_param_named(duallink, nouveau_duallink, int, 0400);
285

286
287
288
289
MODULE_PARM_DESC(hdmimhz, "Force a maximum HDMI pixel clock (in MHz)");
int nouveau_hdmimhz = 0;
module_param_named(hdmimhz, nouveau_hdmimhz, int, 0400);

290
struct nouveau_encoder *
291
find_encoder(struct drm_connector *connector, int type)
292
293
294
{
	struct drm_device *dev = connector->dev;
	struct nouveau_encoder *nv_encoder;
Rob Clark's avatar
Rob Clark committed
295
	struct drm_encoder *enc;
296
297
298
299
300
301
302
	int i, id;

	for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
		id = connector->encoder_ids[i];
		if (!id)
			break;

Rob Clark's avatar
Rob Clark committed
303
304
		enc = drm_encoder_find(dev, id);
		if (!enc)
305
			continue;
Rob Clark's avatar
Rob Clark committed
306
		nv_encoder = nouveau_encoder(enc);
307

308
309
		if (type == DCB_OUTPUT_ANY ||
		    (nv_encoder->dcb && nv_encoder->dcb->type == type))
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
			return nv_encoder;
	}

	return NULL;
}

struct nouveau_connector *
nouveau_encoder_connector_get(struct nouveau_encoder *encoder)
{
	struct drm_device *dev = to_drm_encoder(encoder)->dev;
	struct drm_connector *drm_connector;

	list_for_each_entry(drm_connector, &dev->mode_config.connector_list, head) {
		if (drm_connector->encoder == to_drm_encoder(encoder))
			return nouveau_connector(drm_connector);
	}

	return NULL;
}

static void
331
nouveau_connector_destroy(struct drm_connector *connector)
332
{
333
	struct nouveau_connector *nv_connector = nouveau_connector(connector);
334
	nvif_notify_fini(&nv_connector->hpd);
335
	kfree(nv_connector->edid);
336
	drm_connector_unregister(connector);
337
	drm_connector_cleanup(connector);
338
339
	if (nv_connector->aux.transfer)
		drm_dp_aux_unregister(&nv_connector->aux);
340
	kfree(connector);
341
342
}

343
344
static struct nouveau_encoder *
nouveau_connector_ddc_detect(struct drm_connector *connector)
345
346
{
	struct drm_device *dev = connector->dev;
347
	struct nouveau_connector *nv_connector = nouveau_connector(connector);
348
	struct nouveau_drm *drm = nouveau_drm(dev);
349
	struct nvkm_gpio *gpio = nvxx_gpio(&drm->device);
350
	struct nouveau_encoder *nv_encoder;
Rob Clark's avatar
Rob Clark committed
351
	struct drm_encoder *encoder;
352
353
354
355
356
357
358
	int i, panel = -ENODEV;

	/* eDP panels need powering on by us (if the VBIOS doesn't default it
	 * to on) before doing any AUX channel transactions.  LVDS panel power
	 * is handled by the SOR itself, and not required for LVDS DDC.
	 */
	if (nv_connector->type == DCB_CONNECTOR_eDP) {
359
		panel = nvkm_gpio_get(gpio, 0, DCB_GPIO_PANEL_POWER, 0xff);
360
		if (panel == 0) {
361
			nvkm_gpio_set(gpio, 0, DCB_GPIO_PANEL_POWER, 0xff, 1);
362
363
364
			msleep(300);
		}
	}
365

366
367
368
	for (i = 0; nv_encoder = NULL, i < DRM_CONNECTOR_MAX_ENCODER; i++) {
		int id = connector->encoder_ids[i];
		if (id == 0)
369
370
			break;

Rob Clark's avatar
Rob Clark committed
371
372
		encoder = drm_encoder_find(dev, id);
		if (!encoder)
373
			continue;
Rob Clark's avatar
Rob Clark committed
374
		nv_encoder = nouveau_encoder(encoder);
375

376
377
378
379
380
		if (nv_encoder->dcb->type == DCB_OUTPUT_DP) {
			int ret = nouveau_dp_detect(nv_encoder);
			if (ret == 0)
				break;
		} else
381
382
383
384
385
386
387
388
389
390
391
		if ((vga_switcheroo_handler_flags() &
		     VGA_SWITCHEROO_CAN_SWITCH_DDC) &&
		    nv_encoder->dcb->type == DCB_OUTPUT_LVDS &&
		    nv_encoder->i2c) {
			int ret;
			vga_switcheroo_lock_ddc(dev->pdev);
			ret = nvkm_probe_i2c(nv_encoder->i2c, 0x50);
			vga_switcheroo_unlock_ddc(dev->pdev);
			if (ret)
				break;
		} else
392
		if (nv_encoder->i2c) {
393
			if (nvkm_probe_i2c(nv_encoder->i2c, 0x50))
394
				break;
395
396
397
		}
	}

398
399
400
	/* eDP panel not detected, restore panel power GPIO to previous
	 * state to avoid confusing the SOR for other output types.
	 */
401
	if (!nv_encoder && panel == 0)
402
		nvkm_gpio_set(gpio, 0, DCB_GPIO_PANEL_POWER, 0xff, panel);
403

404
	return nv_encoder;
405
406
}

407
408
409
410
411
412
413
414
415
416
static struct nouveau_encoder *
nouveau_connector_of_detect(struct drm_connector *connector)
{
#ifdef __powerpc__
	struct drm_device *dev = connector->dev;
	struct nouveau_connector *nv_connector = nouveau_connector(connector);
	struct nouveau_encoder *nv_encoder;
	struct device_node *cn, *dn = pci_device_to_OF_node(dev->pdev);

	if (!dn ||
417
418
	    !((nv_encoder = find_encoder(connector, DCB_OUTPUT_TMDS)) ||
	      (nv_encoder = find_encoder(connector, DCB_OUTPUT_ANALOG))))
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
		return NULL;

	for_each_child_of_node(dn, cn) {
		const char *name = of_get_property(cn, "name", NULL);
		const void *edid = of_get_property(cn, "EDID", NULL);
		int idx = name ? name[strlen(name) - 1] - 'A' : 0;

		if (nv_encoder->dcb->i2c_index == idx && edid) {
			nv_connector->edid =
				kmemdup(edid, EDID_LENGTH, GFP_KERNEL);
			of_node_put(cn);
			return nv_encoder;
		}
	}
#endif
	return NULL;
}

437
438
439
440
441
static void
nouveau_connector_set_encoder(struct drm_connector *connector,
			      struct nouveau_encoder *nv_encoder)
{
	struct nouveau_connector *nv_connector = nouveau_connector(connector);
442
	struct nouveau_drm *drm = nouveau_drm(connector->dev);
443
444
445
446
447
448
	struct drm_device *dev = connector->dev;

	if (nv_connector->detected_encoder == nv_encoder)
		return;
	nv_connector->detected_encoder = nv_encoder;

449
	if (drm->device.info.family >= NV_DEVICE_INFO_V0_TESLA) {
450
451
452
		connector->interlace_allowed = true;
		connector->doublescan_allowed = true;
	} else
453
454
	if (nv_encoder->dcb->type == DCB_OUTPUT_LVDS ||
	    nv_encoder->dcb->type == DCB_OUTPUT_TMDS) {
455
456
457
458
		connector->doublescan_allowed = false;
		connector->interlace_allowed = false;
	} else {
		connector->doublescan_allowed = true;
459
460
		if (drm->device.info.family == NV_DEVICE_INFO_V0_KELVIN ||
		    (drm->device.info.family == NV_DEVICE_INFO_V0_CELSIUS &&
461
462
		     (dev->pdev->device & 0x0ff0) != 0x0100 &&
		     (dev->pdev->device & 0x0ff0) != 0x0150))
463
464
465
466
467
468
			/* HW is broken */
			connector->interlace_allowed = false;
		else
			connector->interlace_allowed = true;
	}

469
	if (nv_connector->type == DCB_CONNECTOR_DVI_I) {
470
		drm_object_property_set_value(&connector->base,
471
			dev->mode_config.dvi_i_subconnector_property,
472
			nv_encoder->dcb->type == DCB_OUTPUT_TMDS ?
473
474
475
476
477
478
			DRM_MODE_SUBCONNECTOR_DVID :
			DRM_MODE_SUBCONNECTOR_DVIA);
	}
}

static enum drm_connector_status
479
nouveau_connector_detect(struct drm_connector *connector, bool force)
480
481
{
	struct drm_device *dev = connector->dev;
482
	struct nouveau_drm *drm = nouveau_drm(dev);
483
484
	struct nouveau_connector *nv_connector = nouveau_connector(connector);
	struct nouveau_encoder *nv_encoder = NULL;
485
	struct nouveau_encoder *nv_partner;
486
	struct i2c_adapter *i2c;
487
	int type;
488
489
	int ret;
	enum drm_connector_status conn_status = connector_status_disconnected;
490

491
492
493
494
495
496
	/* Cleanup the previous EDID block. */
	if (nv_connector->edid) {
		drm_mode_connector_update_edid_property(connector, NULL);
		kfree(nv_connector->edid);
		nv_connector->edid = NULL;
	}
497

498
	ret = pm_runtime_get_sync(connector->dev->dev);
499
	if (ret < 0 && ret != -EACCES)
500
501
		return conn_status;

502
503
	nv_encoder = nouveau_connector_ddc_detect(connector);
	if (nv_encoder && (i2c = nv_encoder->i2c) != NULL) {
504
505
506
507
508
509
510
511
		if ((vga_switcheroo_handler_flags() &
		     VGA_SWITCHEROO_CAN_SWITCH_DDC) &&
		    nv_connector->type == DCB_CONNECTOR_LVDS)
			nv_connector->edid = drm_get_edid_switcheroo(connector,
								     i2c);
		else
			nv_connector->edid = drm_get_edid(connector, i2c);

512
513
514
		drm_mode_connector_update_edid_property(connector,
							nv_connector->edid);
		if (!nv_connector->edid) {
515
			NV_ERROR(drm, "DDC responded, but no EDID for %s\n",
516
				 connector->name);
517
			goto detect_analog;
518
519
520
521
522
523
524
		}

		/* Override encoder type for DVI-I based on whether EDID
		 * says the display is digital or analog, both use the
		 * same i2c channel so the value returned from ddc_detect
		 * isn't necessarily correct.
		 */
525
		nv_partner = NULL;
526
527
528
529
530
531
532
533
534
		if (nv_encoder->dcb->type == DCB_OUTPUT_TMDS)
			nv_partner = find_encoder(connector, DCB_OUTPUT_ANALOG);
		if (nv_encoder->dcb->type == DCB_OUTPUT_ANALOG)
			nv_partner = find_encoder(connector, DCB_OUTPUT_TMDS);

		if (nv_partner && ((nv_encoder->dcb->type == DCB_OUTPUT_ANALOG &&
				    nv_partner->dcb->type == DCB_OUTPUT_TMDS) ||
				   (nv_encoder->dcb->type == DCB_OUTPUT_TMDS &&
				    nv_partner->dcb->type == DCB_OUTPUT_ANALOG))) {
535
			if (nv_connector->edid->input & DRM_EDID_INPUT_DIGITAL)
536
				type = DCB_OUTPUT_TMDS;
537
			else
538
				type = DCB_OUTPUT_ANALOG;
539

540
			nv_encoder = find_encoder(connector, type);
541
542
543
		}

		nouveau_connector_set_encoder(connector, nv_encoder);
544
545
		conn_status = connector_status_connected;
		goto out;
546
547
	}

548
549
550
	nv_encoder = nouveau_connector_of_detect(connector);
	if (nv_encoder) {
		nouveau_connector_set_encoder(connector, nv_encoder);
551
552
		conn_status = connector_status_connected;
		goto out;
553
554
	}

555
detect_analog:
556
	nv_encoder = find_encoder(connector, DCB_OUTPUT_ANALOG);
557
	if (!nv_encoder && !nouveau_tv_disable)
558
		nv_encoder = find_encoder(connector, DCB_OUTPUT_TV);
559
	if (nv_encoder && force) {
560
		struct drm_encoder *encoder = to_drm_encoder(nv_encoder);
561
		const struct drm_encoder_helper_funcs *helper =
562
563
564
565
566
						encoder->helper_private;

		if (helper->detect(encoder, connector) ==
						connector_status_connected) {
			nouveau_connector_set_encoder(connector, nv_encoder);
567
568
			conn_status = connector_status_connected;
			goto out;
569
570
571
572
		}

	}

573
574
575
576
577
578
 out:

	pm_runtime_mark_last_busy(connector->dev->dev);
	pm_runtime_put_autosuspend(connector->dev->dev);

	return conn_status;
579
580
}

581
static enum drm_connector_status
582
nouveau_connector_detect_lvds(struct drm_connector *connector, bool force)
583
584
{
	struct drm_device *dev = connector->dev;
585
	struct nouveau_drm *drm = nouveau_drm(dev);
586
587
588
589
590
591
592
593
594
595
596
	struct nouveau_connector *nv_connector = nouveau_connector(connector);
	struct nouveau_encoder *nv_encoder = NULL;
	enum drm_connector_status status = connector_status_disconnected;

	/* Cleanup the previous EDID block. */
	if (nv_connector->edid) {
		drm_mode_connector_update_edid_property(connector, NULL);
		kfree(nv_connector->edid);
		nv_connector->edid = NULL;
	}

597
	nv_encoder = find_encoder(connector, DCB_OUTPUT_LVDS);
598
599
600
	if (!nv_encoder)
		return connector_status_disconnected;

601
	/* Try retrieving EDID via DDC */
602
	if (!drm->vbios.fp_no_ddc) {
603
		status = nouveau_connector_detect(connector, force);
604
605
606
607
		if (status == connector_status_connected)
			goto out;
	}

608
609
610
611
612
613
614
615
616
617
	/* On some laptops (Sony, i'm looking at you) there appears to
	 * be no direct way of accessing the panel's EDID.  The only
	 * option available to us appears to be to ask ACPI for help..
	 *
	 * It's important this check's before trying straps, one of the
	 * said manufacturer's laptops are configured in such a way
	 * the nouveau decides an entry in the VBIOS FP mode table is
	 * valid - it's not (rh#613284)
	 */
	if (nv_encoder->dcb->lvdsconf.use_acpi_for_edid) {
618
		if ((nv_connector->edid = nouveau_acpi_edid(dev, connector))) {
619
620
621
622
623
			status = connector_status_connected;
			goto out;
		}
	}

624
625
626
627
	/* If no EDID found above, and the VBIOS indicates a hardcoded
	 * modeline is avalilable for the panel, set it as the panel's
	 * native mode and exit.
	 */
628
	if (nouveau_bios_fp_mode(dev, NULL) && (drm->vbios.fp_no_ddc ||
629
630
631
632
633
634
635
636
	    nv_encoder->dcb->lvdsconf.use_straps_for_mode)) {
		status = connector_status_connected;
		goto out;
	}

	/* Still nothing, some VBIOS images have a hardcoded EDID block
	 * stored for the panel stored in them.
	 */
637
	if (!drm->vbios.fp_no_ddc) {
638
639
640
		struct edid *edid =
			(struct edid *)nouveau_bios_embedded_edid(dev);
		if (edid) {
641
642
643
644
			nv_connector->edid =
					kmemdup(edid, EDID_LENGTH, GFP_KERNEL);
			if (nv_connector->edid)
				status = connector_status_connected;
645
646
647
648
649
650
651
652
653
654
655
656
		}
	}

out:
#if defined(CONFIG_ACPI_BUTTON) || \
	(defined(CONFIG_ACPI_BUTTON_MODULE) && defined(MODULE))
	if (status == connector_status_connected &&
	    !nouveau_ignorelid && !acpi_lid_open())
		status = connector_status_unknown;
#endif

	drm_mode_connector_update_edid_property(connector, nv_connector->edid);
657
	nouveau_connector_set_encoder(connector, nv_encoder);
658
659
660
	return status;
}

661
662
663
static void
nouveau_connector_force(struct drm_connector *connector)
{
664
	struct nouveau_drm *drm = nouveau_drm(connector->dev);
665
	struct nouveau_connector *nv_connector = nouveau_connector(connector);
666
667
668
	struct nouveau_encoder *nv_encoder;
	int type;

669
	if (nv_connector->type == DCB_CONNECTOR_DVI_I) {
670
		if (connector->force == DRM_FORCE_ON_DIGITAL)
671
			type = DCB_OUTPUT_TMDS;
672
		else
673
			type = DCB_OUTPUT_ANALOG;
674
	} else
675
		type = DCB_OUTPUT_ANY;
676

677
	nv_encoder = find_encoder(connector, type);
678
	if (!nv_encoder) {
679
		NV_ERROR(drm, "can't find encoder to force %s on!\n",
680
			 connector->name);
681
682
683
684
685
686
687
688
689
690
691
		connector->status = connector_status_disconnected;
		return;
	}

	nouveau_connector_set_encoder(connector, nv_encoder);
}

static int
nouveau_connector_set_property(struct drm_connector *connector,
			       struct drm_property *property, uint64_t value)
{
692
	struct nouveau_conn_atom *asyc = nouveau_conn_atom(connector->state);
693
694
	struct nouveau_connector *nv_connector = nouveau_connector(connector);
	struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder;
695
	struct drm_encoder *encoder = to_drm_encoder(nv_encoder);
696
	struct nouveau_crtc *nv_crtc = NULL;
697
698
	int ret;

699
700
701
702
703
704
705
706
	ret = connector->funcs->atomic_set_property(&nv_connector->base,
						    &asyc->state,
						    property, value);
	if (ret) {
		if (nv_encoder && nv_encoder->dcb->type == DCB_OUTPUT_TV)
			return get_slave_funcs(encoder)->set_property(
				encoder, connector, property, value);
		return ret;
707
708
	}

709
710
711
712
713
714
	nv_connector->scaling_mode = asyc->scaler.mode;
	nv_connector->underscan = asyc->scaler.underscan.mode;
	nv_connector->underscan_hborder = asyc->scaler.underscan.hborder;
	nv_connector->underscan_vborder = asyc->scaler.underscan.vborder;
	nv_connector->dithering_mode = asyc->dither.mode;
	nv_connector->dithering_depth = asyc->dither.depth;
715

716
717
718
	if (connector->encoder && connector->encoder->crtc)
		nv_crtc = nouveau_crtc(connector->encoder->crtc);
	if (!nv_crtc)
719
720
		return 0;

721
722
	nv_crtc->vibrant_hue = asyc->procamp.vibrant_hue - 90;
	nv_crtc->color_vibrance = asyc->procamp.color_vibrance - 100;
723

724
725
726
727
	ret = drm_crtc_helper_set_mode(&nv_crtc->base, &nv_crtc->base.mode,
				       nv_crtc->base.x, nv_crtc->base.y, NULL);
	if (!ret)
		return -EINVAL;
728

729
	return 0;
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
}

struct moderec {
	int hdisplay;
	int vdisplay;
};

static struct moderec scaler_modes[] = {
	{ 1920, 1200 },
	{ 1920, 1080 },
	{ 1680, 1050 },
	{ 1600, 1200 },
	{ 1400, 1050 },
	{ 1280, 1024 },
	{ 1280, 960 },
	{ 1152, 864 },
	{ 1024, 768 },
	{ 800, 600 },
	{ 720, 400 },
	{ 640, 480 },
	{ 640, 400 },
	{ 640, 350 },
	{}
};

static int
nouveau_connector_scaler_modes_add(struct drm_connector *connector)
{
	struct nouveau_connector *nv_connector = nouveau_connector(connector);
	struct drm_display_mode *native = nv_connector->native_mode, *m;
	struct drm_device *dev = connector->dev;
	struct moderec *mode = &scaler_modes[0];
	int modes = 0;

	if (!native)
		return 0;

	while (mode->hdisplay) {
		if (mode->hdisplay <= native->hdisplay &&
769
770
771
		    mode->vdisplay <= native->vdisplay &&
		    (mode->hdisplay != native->hdisplay ||
		     mode->vdisplay != native->vdisplay)) {
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
			m = drm_cvt_mode(dev, mode->hdisplay, mode->vdisplay,
					 drm_mode_vrefresh(native), false,
					 false, false);
			if (!m)
				continue;

			drm_mode_probed_add(connector, m);
			modes++;
		}

		mode++;
	}

	return modes;
}

788
789
790
static void
nouveau_connector_detect_depth(struct drm_connector *connector)
{
791
	struct nouveau_drm *drm = nouveau_drm(connector->dev);
792
793
	struct nouveau_connector *nv_connector = nouveau_connector(connector);
	struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder;
794
	struct nvbios *bios = &drm->vbios;
795
796
797
798
799
800
801
	struct drm_display_mode *mode = nv_connector->native_mode;
	bool duallink;

	/* if the edid is feeling nice enough to provide this info, use it */
	if (nv_connector->edid && connector->display_info.bpc)
		return;

802
803
804
805
806
807
808
	/* EDID 1.4 is *supposed* to be supported on eDP, but, Apple... */
	if (nv_connector->type == DCB_CONNECTOR_eDP) {
		connector->display_info.bpc = 6;
		return;
	}

	/* we're out of options unless we're LVDS, default to 8bpc */
809
	if (nv_encoder->dcb->type != DCB_OUTPUT_LVDS) {
810
		connector->display_info.bpc = 8;
811
		return;
812
813
814
	}

	connector->display_info.bpc = 6;
815
816
817
818
819
820
821
822
823
824
825
826

	/* LVDS: panel straps */
	if (bios->fp_no_ddc) {
		if (bios->fp.if_is_24bit)
			connector->display_info.bpc = 8;
		return;
	}

	/* LVDS: DDC panel, need to first determine the number of links to
	 * know which if_is_24bit flag to check...
	 */
	if (nv_connector->edid &&
827
	    nv_connector->type == DCB_CONNECTOR_LVDS_SPWG)
828
829
830
831
832
833
834
835
836
		duallink = ((u8 *)nv_connector->edid)[121] == 2;
	else
		duallink = mode->clock >= bios->fp.duallink_transition_clk;

	if ((!duallink && (bios->fp.strapless_is_24bit & 1)) ||
	    ( duallink && (bios->fp.strapless_is_24bit & 2)))
		connector->display_info.bpc = 8;
}

837
838
839
840
static int
nouveau_connector_get_modes(struct drm_connector *connector)
{
	struct drm_device *dev = connector->dev;
841
	struct nouveau_drm *drm = nouveau_drm(dev);
842
843
	struct nouveau_connector *nv_connector = nouveau_connector(connector);
	struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder;
844
	struct drm_encoder *encoder = to_drm_encoder(nv_encoder);
845
846
	int ret = 0;

847
	/* destroy the native mode, the attached monitor could have changed.
848
	 */
849
	if (nv_connector->native_mode) {
850
851
852
853
854
855
		drm_mode_destroy(dev, nv_connector->native_mode);
		nv_connector->native_mode = NULL;
	}

	if (nv_connector->edid)
		ret = drm_add_edid_modes(connector, nv_connector->edid);
856
	else
857
	if (nv_encoder->dcb->type == DCB_OUTPUT_LVDS &&
858
	    (nv_encoder->dcb->lvdsconf.use_straps_for_mode ||
859
	     drm->vbios.fp_no_ddc) && nouveau_bios_fp_mode(dev, NULL)) {
860
861
862
863
		struct drm_display_mode mode;

		nouveau_bios_fp_mode(dev, &mode);
		nv_connector->native_mode = drm_mode_duplicate(dev, &mode);
864
	}
865

866
867
868
869
870
871
	/* Determine display colour depth for everything except LVDS now,
	 * DP requires this before mode_valid() is called.
	 */
	if (connector->connector_type != DRM_MODE_CONNECTOR_LVDS)
		nouveau_connector_detect_depth(connector);

872
873
874
875
876
	/* Find the native mode if this is a digital panel, if we didn't
	 * find any modes through DDC previously add the native mode to
	 * the list of modes.
	 */
	if (!nv_connector->native_mode)
877
		nv_connector->native_mode = nouveau_conn_native_mode(connector);
878
879
880
881
882
883
884
885
	if (ret == 0 && nv_connector->native_mode) {
		struct drm_display_mode *mode;

		mode = drm_mode_duplicate(dev, nv_connector->native_mode);
		drm_mode_probed_add(connector, mode);
		ret = 1;
	}

886
887
888
	/* Determine LVDS colour depth, must happen after determining
	 * "native" mode as some VBIOS tables require us to use the
	 * pixel clock as part of the lookup...
889
	 */
890
891
	if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)
		nouveau_connector_detect_depth(connector);
892

893
	if (nv_encoder->dcb->type == DCB_OUTPUT_TV)
894
		ret = get_slave_funcs(encoder)->get_modes(encoder, connector);
895

896
897
898
	if (nv_connector->type == DCB_CONNECTOR_LVDS ||
	    nv_connector->type == DCB_CONNECTOR_LVDS_SPWG ||
	    nv_connector->type == DCB_CONNECTOR_eDP)
899
900
901
902
903
		ret += nouveau_connector_scaler_modes_add(connector);

	return ret;
}

904
static unsigned
905
get_tmds_link_bandwidth(struct drm_connector *connector, bool hdmi)
906
907
{
	struct nouveau_connector *nv_connector = nouveau_connector(connector);
908
	struct nouveau_drm *drm = nouveau_drm(connector->dev);
909
	struct dcb_output *dcb = nv_connector->detected_encoder->dcb;
910

911
912
913
914
915
916
917
918
919
920
921
	if (hdmi) {
		if (nouveau_hdmimhz > 0)
			return nouveau_hdmimhz * 1000;
		/* Note: these limits are conservative, some Fermi's
		 * can do 297 MHz. Unclear how this can be determined.
		 */
		if (drm->device.info.family >= NV_DEVICE_INFO_V0_KEPLER)
			return 297000;
		if (drm->device.info.family >= NV_DEVICE_INFO_V0_FERMI)
			return 225000;
	}
922
	if (dcb->location != DCB_LOC_ON_CHIP ||
923
	    drm->device.info.chipset >= 0x46)
924
		return 165000;
925
	else if (drm->device.info.chipset >= 0x40)
926
		return 155000;
927
	else if (drm->device.info.chipset >= 0x18)
928
929
930
931
932
		return 135000;
	else
		return 112000;
}

933
934
935
936
937
938
static int
nouveau_connector_mode_valid(struct drm_connector *connector,
			     struct drm_display_mode *mode)
{
	struct nouveau_connector *nv_connector = nouveau_connector(connector);
	struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder;
939
	struct drm_encoder *encoder = to_drm_encoder(nv_encoder);
940
941
	unsigned min_clock = 25000, max_clock = min_clock;
	unsigned clock = mode->clock;
942
	bool hdmi;
943
944

	switch (nv_encoder->dcb->type) {
945
	case DCB_OUTPUT_LVDS:
946
947
948
		if (nv_connector->native_mode &&
		    (mode->hdisplay > nv_connector->native_mode->hdisplay ||
		     mode->vdisplay > nv_connector->native_mode->vdisplay))
949
950
951
952
953
			return MODE_PANEL;

		min_clock = 0;
		max_clock = 400000;
		break;
954
	case DCB_OUTPUT_TMDS:
955
956
957
958
		hdmi = drm_detect_hdmi_monitor(nv_connector->edid);
		max_clock = get_tmds_link_bandwidth(connector, hdmi);
		if (!hdmi && nouveau_duallink &&
		    nv_encoder->dcb->duallink_possible)
959
			max_clock *= 2;
960
		break;
961
	case DCB_OUTPUT_ANALOG:
962
963
964
965
		max_clock = nv_encoder->dcb->crtconf.maxfreq;
		if (!max_clock)
			max_clock = 350000;
		break;
966
	case DCB_OUTPUT_TV:
967
		return get_slave_funcs(encoder)->mode_valid(encoder, mode);
968
	case DCB_OUTPUT_DP:
969
970
		max_clock  = nv_encoder->dp.link_nr;
		max_clock *= nv_encoder->dp.link_bw;
971
		clock = clock * (connector->display_info.bpc * 3) / 10;
972
		break;
973
974
975
	default:
		BUG_ON(1);
		return MODE_BAD;
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
	}

	if (clock < min_clock)
		return MODE_CLOCK_LOW;

	if (clock > max_clock)
		return MODE_CLOCK_HIGH;

	return MODE_OK;
}

static struct drm_encoder *
nouveau_connector_best_encoder(struct drm_connector *connector)
{
	struct nouveau_connector *nv_connector = nouveau_connector(connector);

	if (nv_connector->detected_encoder)
		return to_drm_encoder(nv_connector->detected_encoder);

	return NULL;
}

static const struct drm_connector_helper_funcs
nouveau_connector_helper_funcs = {
	.get_modes = nouveau_connector_get_modes,
	.mode_valid = nouveau_connector_mode_valid,
	.best_encoder = nouveau_connector_best_encoder,
};

static const struct drm_connector_funcs
nouveau_connector_funcs = {
	.dpms = drm_helper_connector_dpms,
1008
	.reset = nouveau_conn_reset,
1009
	.detect = nouveau_connector_detect,
1010
	.force = nouveau_connector_force,
1011
1012
	.fill_modes = drm_helper_probe_single_connector_modes,
	.set_property = nouveau_connector_set_property,
1013
1014
1015
1016
1017
	.destroy = nouveau_connector_destroy,
	.atomic_duplicate_state = nouveau_conn_atomic_duplicate_state,
	.atomic_destroy_state = nouveau_conn_atomic_destroy_state,
	.atomic_set_property = nouveau_conn_atomic_set_property,
	.atomic_get_property = nouveau_conn_atomic_get_property,
1018
1019
};

1020
1021
1022
static const struct drm_connector_funcs
nouveau_connector_funcs_lvds = {
	.dpms = drm_helper_connector_dpms,
1023
	.reset = nouveau_conn_reset,
1024
	.detect = nouveau_connector_detect_lvds,
1025
	.force = nouveau_connector_force,
1026
1027
	.fill_modes = drm_helper_probe_single_connector_modes,
	.set_property = nouveau_connector_set_property,
1028
1029
1030
1031
1032
	.destroy = nouveau_connector_destroy,
	.atomic_duplicate_state = nouveau_conn_atomic_duplicate_state,
	.atomic_destroy_state = nouveau_conn_atomic_destroy_state,
	.atomic_set_property = nouveau_conn_atomic_set_property,
	.atomic_get_property = nouveau_conn_atomic_get_property,
1033
};
1034

1035
static int
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
nouveau_connector_dp_dpms(struct drm_connector *connector, int mode)
{
	struct nouveau_encoder *nv_encoder = NULL;

	if (connector->encoder)
		nv_encoder = nouveau_encoder(connector->encoder);
	if (nv_encoder && nv_encoder->dcb &&
	    nv_encoder->dcb->type == DCB_OUTPUT_DP) {
		if (mode == DRM_MODE_DPMS_ON) {
			u8 data = DP_SET_POWER_D0;
1046
			nvkm_wraux(nv_encoder->aux, DP_SET_POWER, &data, 1);
1047
1048
1049
			usleep_range(1000, 2000);
		} else {
			u8 data = DP_SET_POWER_D3;
1050
			nvkm_wraux(nv_encoder->aux, DP_SET_POWER, &data, 1);
1051
1052
1053
		}
	}

1054
	return drm_helper_connector_dpms(connector, mode);
1055
1056
1057
1058
1059
}

static const struct drm_connector_funcs
nouveau_connector_funcs_dp = {
	.dpms = nouveau_connector_dp_dpms,
1060
	.reset = nouveau_conn_reset,
1061
	.detect = nouveau_connector_detect,
1062
	.force = nouveau_connector_force,
1063
1064
	.fill_modes = drm_helper_probe_single_connector_modes,
	.set_property = nouveau_connector_set_property,
1065
1066
1067
1068
1069
	.destroy = nouveau_connector_destroy,
	.atomic_duplicate_state = nouveau_conn_atomic_duplicate_state,
	.atomic_destroy_state = nouveau_conn_atomic_destroy_state,
	.atomic_set_property = nouveau_conn_atomic_set_property,
	.atomic_get_property = nouveau_conn_atomic_get_property,
1070
1071
};

1072
static int
1073
nouveau_connector_hotplug(struct nvif_notify *notify)
1074
1075
{
	struct nouveau_connector *nv_connector =
1076
		container_of(notify, typeof(*nv_connector), hpd);
1077
	struct drm_connector *connector = &nv_connector->base;
1078
	struct nouveau_drm *drm = nouveau_drm(connector->dev);
1079
	const struct nvif_notify_conn_rep_v0 *rep = notify->data;
1080
	const char *name = connector->name;
1081

1082
	if (rep->mask & NVIF_NOTIFY_CONN_V0_IRQ) {
1083
	} else {
1084
		bool plugged = (rep->mask != NVIF_NOTIFY_CONN_V0_UNPLUG);
1085

1086
1087
1088
1089
		NV_DEBUG(drm, "%splugged %s\n", plugged ? "" : "un", name);
		drm_helper_hpd_irq_event(connector->dev);
	}

1090
	return NVIF_NOTIFY_KEEP;
1091
1092
}

1093
static ssize_t
1094
nouveau_connector_aux_xfer(struct drm_dp_aux *obj, struct drm_dp_aux_msg *msg)
1095
1096
{
	struct nouveau_connector *nv_connector =
1097
		container_of(obj, typeof(*nv_connector), aux);
1098
	struct nouveau_encoder *nv_encoder;
1099
	struct nvkm_i2c_aux *aux;
1100
1101
1102
	int ret;

	nv_encoder = find_encoder(&nv_connector->base, DCB_OUTPUT_DP);
1103
	if (!nv_encoder || !(aux = nv_encoder->aux))
1104
1105
1106
1107
1108
1109
		return -ENODEV;
	if (WARN_ON(msg->size > 16))
		return -E2BIG;
	if (msg->size == 0)
		return msg->size;

1110
	ret = nvkm_i2c_aux_acquire(aux);
1111
1112
1113
	if (ret)
		return ret;

1114
1115
1116
	ret = nvkm_i2c_aux_xfer(aux, false, msg->request, msg->address,
				msg->buffer, msg->size);
	nvkm_i2c_aux_release(aux);
1117
1118
1119
1120
1121
1122
1123
1124
	if (ret >= 0) {
		msg->reply = ret;
		return msg->size;
	}

	return ret;
}

1125
1126
1127
1128
1129
1130
1131
1132
static int
drm_conntype_from_dcb(enum dcb_connector_type dcb)
{
	switch (dcb) {
	case DCB_CONNECTOR_VGA      : return DRM_MODE_CONNECTOR_VGA;
	case DCB_CONNECTOR_TV_0     :
	case DCB_CONNECTOR_TV_1     :
	case DCB_CONNECTOR_TV_3     : return DRM_MODE_CONNECTOR_TV;
1133
1134
	case DCB_CONNECTOR_DMS59_0  :
	case DCB_CONNECTOR_DMS59_1  :
1135
1136
1137
1138
	case DCB_CONNECTOR_DVI_I    : return DRM_MODE_CONNECTOR_DVII;
	case DCB_CONNECTOR_DVI_D    : return DRM_MODE_CONNECTOR_DVID;
	case DCB_CONNECTOR_LVDS     :
	case DCB_CONNECTOR_LVDS_SPWG: return DRM_MODE_CONNECTOR_LVDS;
1139
1140
	case DCB_CONNECTOR_DMS59_DP0:
	case DCB_CONNECTOR_DMS59_DP1:
1141
1142
1143
	case DCB_CONNECTOR_DP       : return DRM_MODE_CONNECTOR_DisplayPort;
	case DCB_CONNECTOR_eDP      : return DRM_MODE_CONNECTOR_eDP;
	case DCB_CONNECTOR_HDMI_0   :
1144
1145
	case DCB_CONNECTOR_HDMI_1   :
	case DCB_CONNECTOR_HDMI_C   : return DRM_MODE_CONNECTOR_HDMIA;
1146
1147
1148
1149
1150
1151
1152
	default:
		break;
	}

	return DRM_MODE_CONNECTOR_Unknown;
}

1153
1154
struct drm_connector *
nouveau_connector_create(struct drm_device *dev, int index)
1155
{
1156
	const struct drm_connector_funcs *funcs = &nouveau_connector_funcs;
1157
1158
	struct nouveau_drm *drm = nouveau_drm(dev);
	struct nouveau_display *disp = nouveau_display(dev);
1159
1160
	struct nouveau_connector *nv_connector = NULL;
	struct drm_connector *connector;
1161
	int type, ret = 0;
1162
	bool dummy;
1163

1164
1165
1166
1167
	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
		nv_connector = nouveau_connector(connector);
		if (nv_connector->index == index)
			return connector;
1168
1169
	}

1170
1171
	nv_connector = kzalloc(sizeof(*nv_connector), GFP_KERNEL);
	if (!nv_connector)
1172
		return ERR_PTR(-ENOMEM);
1173

1174
	connector = &nv_connector->base;
1175
1176
1177
	nv_connector->index = index;

	/* attempt to parse vbios connector type and hotplug gpio */
1178
	nv_connector->dcb = olddcb_conn(dev, index);
1179
1180
	if (nv_connector->dcb) {
		u32 entry = ROM16(nv_connector->dcb[0]);
1181
		if (olddcb_conntab(dev)[3] >= 4)
1182
1183
1184
1185
1186
			entry |= (u32)ROM16(nv_connector->dcb[2]) << 16;

		nv_connector->type = nv_connector->dcb[0];
		if (drm_conntype_from_dcb(nv_connector->type) ==
					  DRM_MODE_CONNECTOR_Unknown) {
1187
			NV_WARN(drm, "unknown connector type %02x\n",
1188
1189
1190
				nv_connector->type);
			nv_connector->type = DCB_CONNECTOR_NONE;
		}
1191

1192
1193
1194
1195
1196
		/* Gigabyte NX85T */
		if (nv_match_device(dev, 0x0421, 0x1458, 0x344c)) {
			if (nv_connector->type == DCB_CONNECTOR_HDMI_1)
				nv_connector->type = DCB_CONNECTOR_DVI_I;
		}
1197

1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
		/* Gigabyte GV-NX86T512H */
		if (nv_match_device(dev, 0x0402, 0x1458, 0x3455)) {
			if (nv_connector->type == DCB_CONNECTOR_HDMI_1)
				nv_connector->type = DCB_CONNECTOR_DVI_I;
		}
	} else {
		nv_connector->type = DCB_CONNECTOR_NONE;
	}

	/* no vbios data, or an unknown dcb connector type - attempt to
	 * figure out something suitable ourselves
	 */
	if (nv_connector->type == DCB_CONNECTOR_NONE) {
1211
1212
		struct nouveau_drm *drm = nouveau_drm(dev);
		struct dcb_table *dcbt = &drm->vbios.dcb;
1213
1214
1215
1216
1217
1218
1219
		u32 encoders = 0;
		int i;

		for (i = 0; i < dcbt->entries; i++) {
			if (dcbt->entry[i].connector == nv_connector->index)
				encoders |= (1 << dcbt->entry[i].type);
		}
1220

1221
1222
		if (encoders & (1 << DCB_OUTPUT_DP)) {
			if (encoders & (1 << DCB_OUTPUT_TMDS))
1223
1224
1225
1226
				nv_connector->type = DCB_CONNECTOR_DP;
			else
				nv_connector->type = DCB_CONNECTOR_eDP;
		} else
1227
1228
		if (encoders & (1 << DCB_OUTPUT_TMDS)) {
			if (encoders & (1 << DCB_OUTPUT_ANALOG))
1229
1230
1231
1232
				nv_connector->type = DCB_CONNECTOR_DVI_I;
			else
				nv_connector->type = DCB_CONNECTOR_DVI_D;
		} else
1233
		if (encoders & (1 << DCB_OUTPUT_ANALOG)) {