radeon_connectors.c 43.9 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
27
28
/*
 * Copyright 2007-8 Advanced Micro Devices, Inc.
 * Copyright 2008 Red Hat Inc.
 *
 * 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 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 HOLDER(S) OR AUTHOR(S) 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.
 *
 * Authors: Dave Airlie
 *          Alex Deucher
 */
#include "drmP.h"
#include "drm_edid.h"
#include "drm_crtc_helper.h"
29
#include "drm_fb_helper.h"
30
31
#include "radeon_drm.h"
#include "radeon.h"
32
#include "atom.h"
33
34
35
36
37
38
39
40
41
42

extern void
radeon_combios_connected_scratch_regs(struct drm_connector *connector,
				      struct drm_encoder *encoder,
				      bool connected);
extern void
radeon_atombios_connected_scratch_regs(struct drm_connector *connector,
				       struct drm_encoder *encoder,
				       bool connected);

43
44
45
46
47
48
49
50
51
void radeon_connector_hotplug(struct drm_connector *connector)
{
	struct drm_device *dev = connector->dev;
	struct radeon_device *rdev = dev->dev_private;
	struct radeon_connector *radeon_connector = to_radeon_connector(connector);

	if (radeon_connector->hpd.hpd != RADEON_HPD_NONE)
		radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd);

52
53
54
55
	if ((connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) ||
	    (connector->connector_type == DRM_MODE_CONNECTOR_eDP)) {
		if ((radeon_dp_getsinktype(radeon_connector) == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
		    (radeon_dp_getsinktype(radeon_connector) == CONNECTOR_OBJECT_ID_eDP)) {
56
57
58
59
60
61
62
63
64
			if (radeon_dp_needs_link_train(radeon_connector)) {
				if (connector->encoder)
					dp_link_train(connector->encoder, connector);
			}
		}
	}

}

65
66
67
68
69
70
71
72
73
static void radeon_property_change_mode(struct drm_encoder *encoder)
{
	struct drm_crtc *crtc = encoder->crtc;

	if (crtc && crtc->enabled) {
		drm_crtc_helper_set_mode(crtc, &crtc->mode,
					 crtc->x, crtc->y, crtc->fb);
	}
}
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
static void
radeon_connector_update_scratch_regs(struct drm_connector *connector, enum drm_connector_status status)
{
	struct drm_device *dev = connector->dev;
	struct radeon_device *rdev = dev->dev_private;
	struct drm_encoder *best_encoder = NULL;
	struct drm_encoder *encoder = NULL;
	struct drm_connector_helper_funcs *connector_funcs = connector->helper_private;
	struct drm_mode_object *obj;
	bool connected;
	int i;

	best_encoder = connector_funcs->best_encoder(connector);

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

		obj = drm_mode_object_find(connector->dev,
					   connector->encoder_ids[i],
					   DRM_MODE_OBJECT_ENCODER);
		if (!obj)
			continue;

		encoder = obj_to_encoder(obj);

		if ((encoder == best_encoder) && (status == connector_status_connected))
			connected = true;
		else
			connected = false;

		if (rdev->is_atom_bios)
			radeon_atombios_connected_scratch_regs(connector, encoder, connected);
		else
			radeon_combios_connected_scratch_regs(connector, encoder, connected);

	}
}

113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
struct drm_encoder *radeon_find_encoder(struct drm_connector *connector, int encoder_type)
{
	struct drm_mode_object *obj;
	struct drm_encoder *encoder;
	int i;

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

		obj = drm_mode_object_find(connector->dev, connector->encoder_ids[i], DRM_MODE_OBJECT_ENCODER);
		if (!obj)
			continue;

		encoder = obj_to_encoder(obj);
		if (encoder->encoder_type == encoder_type)
			return encoder;
	}
	return NULL;
}

134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
struct drm_encoder *radeon_best_single_encoder(struct drm_connector *connector)
{
	int enc_id = connector->encoder_ids[0];
	struct drm_mode_object *obj;
	struct drm_encoder *encoder;

	/* pick the encoder ids */
	if (enc_id) {
		obj = drm_mode_object_find(connector->dev, enc_id, DRM_MODE_OBJECT_ENCODER);
		if (!obj)
			return NULL;
		encoder = obj_to_encoder(obj);
		return encoder;
	}
	return NULL;
}

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
/*
 * radeon_connector_analog_encoder_conflict_solve
 * - search for other connectors sharing this encoder
 *   if priority is true, then set them disconnected if this is connected
 *   if priority is false, set us disconnected if they are connected
 */
static enum drm_connector_status
radeon_connector_analog_encoder_conflict_solve(struct drm_connector *connector,
					       struct drm_encoder *encoder,
					       enum drm_connector_status current_status,
					       bool priority)
{
	struct drm_device *dev = connector->dev;
	struct drm_connector *conflict;
	int i;

	list_for_each_entry(conflict, &dev->mode_config.connector_list, head) {
		if (conflict == connector)
			continue;

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

			/* if the IDs match */
			if (conflict->encoder_ids[i] == encoder->base.id) {
				if (conflict->status != connector_status_connected)
					continue;

				if (priority == true) {
					DRM_INFO("1: conflicting encoders switching off %s\n", drm_get_connector_name(conflict));
					DRM_INFO("in favor of %s\n", drm_get_connector_name(connector));
					conflict->status = connector_status_disconnected;
					radeon_connector_update_scratch_regs(conflict, connector_status_disconnected);
				} else {
					DRM_INFO("2: conflicting encoders switching off %s\n", drm_get_connector_name(connector));
					DRM_INFO("in favor of %s\n", drm_get_connector_name(conflict));
					current_status = connector_status_disconnected;
				}
				break;
			}
		}
	}
	return current_status;

}

198
199
200
201
202
static struct drm_display_mode *radeon_fp_native_mode(struct drm_encoder *encoder)
{
	struct drm_device *dev = encoder->dev;
	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
	struct drm_display_mode *mode = NULL;
203
	struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
204

205
206
207
	if (native_mode->hdisplay != 0 &&
	    native_mode->vdisplay != 0 &&
	    native_mode->clock != 0) {
208
		mode = drm_mode_duplicate(dev, native_mode);
209
210
211
212
		mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER;
		drm_mode_set_name(mode);

		DRM_DEBUG("Adding native panel mode %s\n", mode->name);
213
214
215
216
217
218
219
220
221
222
223
224
	} else if (native_mode->hdisplay != 0 &&
		   native_mode->vdisplay != 0) {
		/* mac laptops without an edid */
		/* Note that this is not necessarily the exact panel mode,
		 * but an approximation based on the cvt formula.  For these
		 * systems we should ideally read the mode info out of the
		 * registers or add a mode table, but this works and is much
		 * simpler.
		 */
		mode = drm_cvt_mode(dev, native_mode->hdisplay, native_mode->vdisplay, 60, true, false, false);
		mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER;
		DRM_DEBUG("Adding cvt approximation of native panel mode %s\n", mode->name);
225
226
227
228
	}
	return mode;
}

229
230
231
232
233
static void radeon_add_common_modes(struct drm_encoder *encoder, struct drm_connector *connector)
{
	struct drm_device *dev = encoder->dev;
	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
	struct drm_display_mode *mode = NULL;
234
	struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
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
	int i;
	struct mode_size {
		int w;
		int h;
	} common_modes[17] = {
		{ 640,  480},
		{ 720,  480},
		{ 800,  600},
		{ 848,  480},
		{1024,  768},
		{1152,  768},
		{1280,  720},
		{1280,  800},
		{1280,  854},
		{1280,  960},
		{1280, 1024},
		{1440,  900},
		{1400, 1050},
		{1680, 1050},
		{1600, 1200},
		{1920, 1080},
		{1920, 1200}
	};

	for (i = 0; i < 17; i++) {
260
261
262
263
264
		if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) {
			if (common_modes[i].w > 1024 ||
			    common_modes[i].h > 768)
				continue;
		}
265
		if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
266
267
268
269
			if (common_modes[i].w > native_mode->hdisplay ||
			    common_modes[i].h > native_mode->vdisplay ||
			    (common_modes[i].w == native_mode->hdisplay &&
			     common_modes[i].h == native_mode->vdisplay))
270
271
272
273
274
				continue;
		}
		if (common_modes[i].w < 320 || common_modes[i].h < 200)
			continue;

275
		mode = drm_cvt_mode(dev, common_modes[i].w, common_modes[i].h, 60, false, false, false);
276
277
278
279
		drm_mode_probed_add(connector, mode);
	}
}

280
281
282
int radeon_connector_set_property(struct drm_connector *connector, struct drm_property *property,
				  uint64_t val)
{
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
	struct drm_device *dev = connector->dev;
	struct radeon_device *rdev = dev->dev_private;
	struct drm_encoder *encoder;
	struct radeon_encoder *radeon_encoder;

	if (property == rdev->mode_info.coherent_mode_property) {
		struct radeon_encoder_atom_dig *dig;

		/* need to find digital encoder on connector */
		encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS);
		if (!encoder)
			return 0;

		radeon_encoder = to_radeon_encoder(encoder);

		if (!radeon_encoder->enc_priv)
			return 0;

		dig = radeon_encoder->enc_priv;
		dig->coherent_mode = val ? true : false;
		radeon_property_change_mode(&radeon_encoder->base);
	}

	if (property == rdev->mode_info.tv_std_property) {
		encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TVDAC);
		if (!encoder) {
			encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_DAC);
		}

		if (!encoder)
			return 0;

		radeon_encoder = to_radeon_encoder(encoder);
		if (!radeon_encoder->enc_priv)
			return 0;
		if (rdev->is_atom_bios) {
			struct radeon_encoder_atom_dac *dac_int;
			dac_int = radeon_encoder->enc_priv;
			dac_int->tv_std = val;
		} else {
			struct radeon_encoder_tv_dac *dac_int;
			dac_int = radeon_encoder->enc_priv;
			dac_int->tv_std = val;
		}
		radeon_property_change_mode(&radeon_encoder->base);
	}

	if (property == rdev->mode_info.load_detect_property) {
		struct radeon_connector *radeon_connector =
			to_radeon_connector(connector);

		if (val == 0)
			radeon_connector->dac_load_detect = false;
		else
			radeon_connector->dac_load_detect = true;
	}

	if (property == rdev->mode_info.tmds_pll_property) {
		struct radeon_encoder_int_tmds *tmds = NULL;
		bool ret = false;
		/* need to find digital encoder on connector */
		encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS);
		if (!encoder)
			return 0;

		radeon_encoder = to_radeon_encoder(encoder);

		tmds = radeon_encoder->enc_priv;
		if (!tmds)
			return 0;

		if (val == 0) {
			if (rdev->is_atom_bios)
				ret = radeon_atombios_get_tmds_info(radeon_encoder, tmds);
			else
				ret = radeon_legacy_get_tmds_info_from_combios(radeon_encoder, tmds);
		}
		if (val == 1 || ret == false) {
			radeon_legacy_get_tmds_info_from_table(radeon_encoder, tmds);
		}
		radeon_property_change_mode(&radeon_encoder->base);
	}

366
367
368
	return 0;
}

369
370
371
372
static void radeon_fixup_lvds_native_mode(struct drm_encoder *encoder,
					  struct drm_connector *connector)
{
	struct radeon_encoder *radeon_encoder =	to_radeon_encoder(encoder);
373
	struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
374
375

	/* Try to get native mode details from EDID if necessary */
376
	if (!native_mode->clock) {
377
378
379
		struct drm_display_mode *t, *mode;

		list_for_each_entry_safe(mode, t, &connector->probed_modes, head) {
380
381
382
383
			if (mode->hdisplay == native_mode->hdisplay &&
			    mode->vdisplay == native_mode->vdisplay) {
				*native_mode = *mode;
				drm_mode_set_crtcinfo(native_mode, CRTC_INTERLACE_HALVE_V);
384
385
386
387
388
				DRM_INFO("Determined LVDS native mode details from EDID\n");
				break;
			}
		}
	}
389
	if (!native_mode->clock) {
390
391
392
393
		DRM_INFO("No LVDS native mode details, disabling RMX\n");
		radeon_encoder->rmx_type = RMX_OFF;
	}
}
394
395
396
397
398
399
400
401
402
403
404

static int radeon_lvds_get_modes(struct drm_connector *connector)
{
	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
	struct drm_encoder *encoder;
	int ret = 0;
	struct drm_display_mode *mode;

	if (radeon_connector->ddc_bus) {
		ret = radeon_ddc_get_modes(radeon_connector);
		if (ret > 0) {
405
			encoder = radeon_best_single_encoder(connector);
406
407
			if (encoder) {
				radeon_fixup_lvds_native_mode(encoder, connector);
408
409
				/* add scaled modes */
				radeon_add_common_modes(encoder, connector);
410
			}
411
412
413
414
415
416
417
418
419
420
421
422
423
			return ret;
		}
	}

	encoder = radeon_best_single_encoder(connector);
	if (!encoder)
		return 0;

	/* we have no EDID modes */
	mode = radeon_fp_native_mode(encoder);
	if (mode) {
		ret = 1;
		drm_mode_probed_add(connector, mode);
424
425
		/* add scaled modes */
		radeon_add_common_modes(encoder, connector);
426
	}
427

428
429
430
431
432
433
	return ret;
}

static int radeon_lvds_mode_valid(struct drm_connector *connector,
				  struct drm_display_mode *mode)
{
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
	struct drm_encoder *encoder = radeon_best_single_encoder(connector);

	if ((mode->hdisplay < 320) || (mode->vdisplay < 240))
		return MODE_PANEL;

	if (encoder) {
		struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
		struct drm_display_mode *native_mode = &radeon_encoder->native_mode;

		/* AVIVO hardware supports downscaling modes larger than the panel
		 * to the panel size, but I'm not sure this is desirable.
		 */
		if ((mode->hdisplay > native_mode->hdisplay) ||
		    (mode->vdisplay > native_mode->vdisplay))
			return MODE_PANEL;

		/* if scaling is disabled, block non-native modes */
		if (radeon_encoder->rmx_type == RMX_OFF) {
			if ((mode->hdisplay != native_mode->hdisplay) ||
			    (mode->vdisplay != native_mode->vdisplay))
				return MODE_PANEL;
		}
	}

458
459
460
461
462
	return MODE_OK;
}

static enum drm_connector_status radeon_lvds_detect(struct drm_connector *connector)
{
463
	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
464
	struct drm_encoder *encoder = radeon_best_single_encoder(connector);
465
	enum drm_connector_status ret = connector_status_disconnected;
466
467
468

	if (encoder) {
		struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
469
		struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
470
471

		/* check if panel is valid */
472
		if (native_mode->hdisplay >= 320 && native_mode->vdisplay >= 240)
473
474
475
			ret = connector_status_connected;

	}
476
477

	/* check for edid as well */
478
479
480
481
	if (radeon_connector->edid)
		ret = connector_status_connected;
	else {
		if (radeon_connector->ddc_bus) {
482
			radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
483
484
			radeon_connector->edid = drm_get_edid(&radeon_connector->base,
							      &radeon_connector->ddc_bus->adapter);
485
			radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
486
487
488
			if (radeon_connector->edid)
				ret = connector_status_connected;
		}
489
	}
490
	/* check acpi lid status ??? */
491

492
493
494
495
496
497
498
499
500
501
	radeon_connector_update_scratch_regs(connector, ret);
	return ret;
}

static void radeon_connector_destroy(struct drm_connector *connector)
{
	struct radeon_connector *radeon_connector = to_radeon_connector(connector);

	if (radeon_connector->ddc_bus)
		radeon_i2c_destroy(radeon_connector->ddc_bus);
502
503
	if (radeon_connector->edid)
		kfree(radeon_connector->edid);
504
505
506
507
508
509
	kfree(radeon_connector->con_priv);
	drm_sysfs_connector_remove(connector);
	drm_connector_cleanup(connector);
	kfree(connector);
}

510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
static int radeon_lvds_set_property(struct drm_connector *connector,
				    struct drm_property *property,
				    uint64_t value)
{
	struct drm_device *dev = connector->dev;
	struct radeon_encoder *radeon_encoder;
	enum radeon_rmx_type rmx_type;

	DRM_DEBUG("\n");
	if (property != dev->mode_config.scaling_mode_property)
		return 0;

	if (connector->encoder)
		radeon_encoder = to_radeon_encoder(connector->encoder);
	else {
		struct drm_connector_helper_funcs *connector_funcs = connector->helper_private;
		radeon_encoder = to_radeon_encoder(connector_funcs->best_encoder(connector));
	}

	switch (value) {
	case DRM_MODE_SCALE_NONE: rmx_type = RMX_OFF; break;
	case DRM_MODE_SCALE_CENTER: rmx_type = RMX_CENTER; break;
	case DRM_MODE_SCALE_ASPECT: rmx_type = RMX_ASPECT; break;
	default:
	case DRM_MODE_SCALE_FULLSCREEN: rmx_type = RMX_FULL; break;
	}
	if (radeon_encoder->rmx_type == rmx_type)
		return 0;

	radeon_encoder->rmx_type = rmx_type;

	radeon_property_change_mode(&radeon_encoder->base);
	return 0;
}


546
547
548
549
550
551
552
553
554
555
556
struct drm_connector_helper_funcs radeon_lvds_connector_helper_funcs = {
	.get_modes = radeon_lvds_get_modes,
	.mode_valid = radeon_lvds_mode_valid,
	.best_encoder = radeon_best_single_encoder,
};

struct drm_connector_funcs radeon_lvds_connector_funcs = {
	.dpms = drm_helper_connector_dpms,
	.detect = radeon_lvds_detect,
	.fill_modes = drm_helper_probe_single_connector_modes,
	.destroy = radeon_connector_destroy,
557
	.set_property = radeon_lvds_set_property,
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
};

static int radeon_vga_get_modes(struct drm_connector *connector)
{
	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
	int ret;

	ret = radeon_ddc_get_modes(radeon_connector);

	return ret;
}

static int radeon_vga_mode_valid(struct drm_connector *connector,
				  struct drm_display_mode *mode)
{
573
574
	/* XXX check mode bandwidth */
	/* XXX verify against max DAC output frequency */
575
576
577
578
579
580
581
582
583
584
585
	return MODE_OK;
}

static enum drm_connector_status radeon_vga_detect(struct drm_connector *connector)
{
	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
	struct drm_encoder *encoder;
	struct drm_encoder_helper_funcs *encoder_funcs;
	bool dret;
	enum drm_connector_status ret = connector_status_disconnected;

586
587
588
589
	encoder = radeon_best_single_encoder(connector);
	if (!encoder)
		ret = connector_status_disconnected;

590
	radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
591
	dret = radeon_ddc_probe(radeon_connector);
592
	radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
593
594
595
596
597
	if (dret) {
		if (radeon_connector->edid) {
			kfree(radeon_connector->edid);
			radeon_connector->edid = NULL;
		}
598
		radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
599
		radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter);
600
		radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
601
602

		if (!radeon_connector->edid) {
603
604
605
			DRM_ERROR("%s: probed a monitor but no|invalid EDID\n",
					drm_get_connector_name(connector));
			ret = connector_status_connected;
606
607
608
609
610
611
612
613
614
615
616
617
618
619
		} else {
			radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL);

			/* some oems have boards with separate digital and analog connectors
			 * with a shared ddc line (often vga + hdmi)
			 */
			if (radeon_connector->use_digital && radeon_connector->shared_ddc) {
				kfree(radeon_connector->edid);
				radeon_connector->edid = NULL;
				ret = connector_status_disconnected;
			} else
				ret = connector_status_connected;
		}
	} else {
620
		if (radeon_connector->dac_load_detect && encoder) {
621
622
623
			encoder_funcs = encoder->helper_private;
			ret = encoder_funcs->detect(encoder, connector);
		}
624
625
	}

626
627
	if (ret == connector_status_connected)
		ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, true);
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
	radeon_connector_update_scratch_regs(connector, ret);
	return ret;
}

struct drm_connector_helper_funcs radeon_vga_connector_helper_funcs = {
	.get_modes = radeon_vga_get_modes,
	.mode_valid = radeon_vga_mode_valid,
	.best_encoder = radeon_best_single_encoder,
};

struct drm_connector_funcs radeon_vga_connector_funcs = {
	.dpms = drm_helper_connector_dpms,
	.detect = radeon_vga_detect,
	.fill_modes = drm_helper_probe_single_connector_modes,
	.destroy = radeon_connector_destroy,
	.set_property = radeon_connector_set_property,
};

646
647
648
static int radeon_tv_get_modes(struct drm_connector *connector)
{
	struct drm_device *dev = connector->dev;
649
	struct radeon_device *rdev = dev->dev_private;
650
	struct drm_display_mode *tv_mode;
651
	struct drm_encoder *encoder;
652

653
654
655
	encoder = radeon_best_single_encoder(connector);
	if (!encoder)
		return 0;
656

657
658
659
660
661
662
	/* avivo chips can scale any mode */
	if (rdev->family >= CHIP_RS600)
		/* add scaled modes */
		radeon_add_common_modes(encoder, connector);
	else {
		/* only 800x600 is supported right now on pre-avivo chips */
663
		tv_mode = drm_cvt_mode(dev, 800, 600, 60, false, false, false);
664
665
666
		tv_mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
		drm_mode_probed_add(connector, tv_mode);
	}
667
668
669
670
671
672
	return 1;
}

static int radeon_tv_mode_valid(struct drm_connector *connector,
				struct drm_display_mode *mode)
{
673
674
	if ((mode->hdisplay > 1024) || (mode->vdisplay > 768))
		return MODE_CLOCK_RANGE;
675
676
677
678
679
680
681
	return MODE_OK;
}

static enum drm_connector_status radeon_tv_detect(struct drm_connector *connector)
{
	struct drm_encoder *encoder;
	struct drm_encoder_helper_funcs *encoder_funcs;
682
683
684
685
686
	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
	enum drm_connector_status ret = connector_status_disconnected;

	if (!radeon_connector->dac_load_detect)
		return ret;
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714

	encoder = radeon_best_single_encoder(connector);
	if (!encoder)
		ret = connector_status_disconnected;
	else {
		encoder_funcs = encoder->helper_private;
		ret = encoder_funcs->detect(encoder, connector);
	}
	if (ret == connector_status_connected)
		ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, false);
	radeon_connector_update_scratch_regs(connector, ret);
	return ret;
}

struct drm_connector_helper_funcs radeon_tv_connector_helper_funcs = {
	.get_modes = radeon_tv_get_modes,
	.mode_valid = radeon_tv_mode_valid,
	.best_encoder = radeon_best_single_encoder,
};

struct drm_connector_funcs radeon_tv_connector_funcs = {
	.dpms = drm_helper_connector_dpms,
	.detect = radeon_tv_detect,
	.fill_modes = drm_helper_probe_single_connector_modes,
	.destroy = radeon_connector_destroy,
	.set_property = radeon_connector_set_property,
};

715
716
717
718
719
720
721
722
723
static int radeon_dvi_get_modes(struct drm_connector *connector)
{
	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
	int ret;

	ret = radeon_ddc_get_modes(radeon_connector);
	return ret;
}

724
725
726
727
728
729
730
731
732
733
734
/*
 * DVI is complicated
 * Do a DDC probe, if DDC probe passes, get the full EDID so
 * we can do analog/digital monitor detection at this point.
 * If the monitor is an analog monitor or we got no DDC,
 * we need to find the DAC encoder object for this connector.
 * If we got no DDC, we do load detection on the DAC encoder object.
 * If we got analog DDC or load detection passes on the DAC encoder
 * we have to check if this analog encoder is shared with anyone else (TV)
 * if its shared we have to set the other connector to disconnected.
 */
735
736
737
static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connector)
{
	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
738
	struct drm_encoder *encoder = NULL;
739
740
741
742
743
744
	struct drm_encoder_helper_funcs *encoder_funcs;
	struct drm_mode_object *obj;
	int i;
	enum drm_connector_status ret = connector_status_disconnected;
	bool dret;

745
	radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
746
	dret = radeon_ddc_probe(radeon_connector);
747
	radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
748
	if (dret) {
749
750
751
752
		if (radeon_connector->edid) {
			kfree(radeon_connector->edid);
			radeon_connector->edid = NULL;
		}
753
		radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
754
		radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter);
755
		radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
756
757

		if (!radeon_connector->edid) {
758
759
			DRM_ERROR("%s: probed a monitor but no|invalid EDID\n",
					drm_get_connector_name(connector));
760
761
762
		} else {
			radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL);

763
764
765
766
767
768
769
770
771
			/* some oems have boards with separate digital and analog connectors
			 * with a shared ddc line (often vga + hdmi)
			 */
			if ((!radeon_connector->use_digital) && radeon_connector->shared_ddc) {
				kfree(radeon_connector->edid);
				radeon_connector->edid = NULL;
				ret = connector_status_disconnected;
			} else
				ret = connector_status_connected;
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804

			/* multiple connectors on the same encoder with the same ddc line
			 * This tends to be HDMI and DVI on the same encoder with the
			 * same ddc line.  If the edid says HDMI, consider the HDMI port
			 * connected and the DVI port disconnected.  If the edid doesn't
			 * say HDMI, vice versa.
			 */
			if (radeon_connector->shared_ddc && connector_status_connected) {
				struct drm_device *dev = connector->dev;
				struct drm_connector *list_connector;
				struct radeon_connector *list_radeon_connector;
				list_for_each_entry(list_connector, &dev->mode_config.connector_list, head) {
					if (connector == list_connector)
						continue;
					list_radeon_connector = to_radeon_connector(list_connector);
					if (radeon_connector->devices == list_radeon_connector->devices) {
						if (drm_detect_hdmi_monitor(radeon_connector->edid)) {
							if (connector->connector_type == DRM_MODE_CONNECTOR_DVID) {
								kfree(radeon_connector->edid);
								radeon_connector->edid = NULL;
								ret = connector_status_disconnected;
							}
						} else {
							if ((connector->connector_type == DRM_MODE_CONNECTOR_HDMIA) ||
							    (connector->connector_type == DRM_MODE_CONNECTOR_HDMIB)) {
								kfree(radeon_connector->edid);
								radeon_connector->edid = NULL;
								ret = connector_status_disconnected;
							}
						}
					}
				}
			}
805
806
807
808
809
810
811
		}
	}

	if ((ret == connector_status_connected) && (radeon_connector->use_digital == true))
		goto out;

	/* find analog encoder */
812
813
814
815
	if (radeon_connector->dac_load_detect) {
		for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
			if (connector->encoder_ids[i] == 0)
				break;
816

817
818
819
820
821
			obj = drm_mode_object_find(connector->dev,
						   connector->encoder_ids[i],
						   DRM_MODE_OBJECT_ENCODER);
			if (!obj)
				continue;
822

823
			encoder = obj_to_encoder(obj);
824

825
826
827
828
829
830
831
			encoder_funcs = encoder->helper_private;
			if (encoder_funcs->detect) {
				if (ret != connector_status_connected) {
					ret = encoder_funcs->detect(encoder, connector);
					if (ret == connector_status_connected) {
						radeon_connector->use_digital = false;
					}
832
				}
833
				break;
834
835
836
837
			}
		}
	}

838
839
840
841
842
843
	if ((ret == connector_status_connected) && (radeon_connector->use_digital == false) &&
	    encoder) {
		ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, true);
	}

out:
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
	/* updated in get modes as well since we need to know if it's analog or digital */
	radeon_connector_update_scratch_regs(connector, ret);
	return ret;
}

/* okay need to be smart in here about which encoder to pick */
struct drm_encoder *radeon_dvi_encoder(struct drm_connector *connector)
{
	int enc_id = connector->encoder_ids[0];
	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
	struct drm_mode_object *obj;
	struct drm_encoder *encoder;
	int i;
	for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
		if (connector->encoder_ids[i] == 0)
			break;

		obj = drm_mode_object_find(connector->dev, connector->encoder_ids[i], DRM_MODE_OBJECT_ENCODER);
		if (!obj)
			continue;

		encoder = obj_to_encoder(obj);

867
		if (radeon_connector->use_digital == true) {
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
			if (encoder->encoder_type == DRM_MODE_ENCODER_TMDS)
				return encoder;
		} else {
			if (encoder->encoder_type == DRM_MODE_ENCODER_DAC ||
			    encoder->encoder_type == DRM_MODE_ENCODER_TVDAC)
				return encoder;
		}
	}

	/* see if we have a default encoder  TODO */

	/* then check use digitial */
	/* pick the first one */
	if (enc_id) {
		obj = drm_mode_object_find(connector->dev, enc_id, DRM_MODE_OBJECT_ENCODER);
		if (!obj)
			return NULL;
		encoder = obj_to_encoder(obj);
		return encoder;
	}
	return NULL;
}

891
892
893
894
895
896
897
898
899
static void radeon_dvi_force(struct drm_connector *connector)
{
	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
	if (connector->force == DRM_FORCE_ON)
		radeon_connector->use_digital = false;
	if (connector->force == DRM_FORCE_ON_DIGITAL)
		radeon_connector->use_digital = true;
}

900
901
902
static int radeon_dvi_mode_valid(struct drm_connector *connector,
				  struct drm_display_mode *mode)
{
903
904
	struct drm_device *dev = connector->dev;
	struct radeon_device *rdev = dev->dev_private;
905
906
907
908
	struct radeon_connector *radeon_connector = to_radeon_connector(connector);

	/* XXX check mode bandwidth */

909
910
911
912
913
914
	/* clocks over 135 MHz have heat issues with DVI on RV100 */
	if (radeon_connector->use_digital &&
	    (rdev->family == CHIP_RV100) &&
	    (mode->clock > 135000))
		return MODE_CLOCK_HIGH;

915
916
917
918
919
920
921
922
923
924
925
	if (radeon_connector->use_digital && (mode->clock > 165000)) {
		if ((radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I) ||
		    (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D) ||
		    (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_HDMI_TYPE_B))
			return MODE_OK;
		else
			return MODE_CLOCK_HIGH;
	}
	return MODE_OK;
}

926
927
struct drm_connector_helper_funcs radeon_dvi_connector_helper_funcs = {
	.get_modes = radeon_dvi_get_modes,
928
	.mode_valid = radeon_dvi_mode_valid,
929
930
931
932
933
934
935
936
937
	.best_encoder = radeon_dvi_encoder,
};

struct drm_connector_funcs radeon_dvi_connector_funcs = {
	.dpms = drm_helper_connector_dpms,
	.detect = radeon_dvi_detect,
	.fill_modes = drm_helper_probe_single_connector_modes,
	.set_property = radeon_connector_set_property,
	.destroy = radeon_connector_destroy,
938
	.force = radeon_dvi_force,
939
940
};

941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
static void radeon_dp_connector_destroy(struct drm_connector *connector)
{
	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
	struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv;

	if (radeon_connector->ddc_bus)
		radeon_i2c_destroy(radeon_connector->ddc_bus);
	if (radeon_connector->edid)
		kfree(radeon_connector->edid);
	if (radeon_dig_connector->dp_i2c_bus)
		radeon_i2c_destroy(radeon_dig_connector->dp_i2c_bus);
	kfree(radeon_connector->con_priv);
	drm_sysfs_connector_remove(connector);
	drm_connector_cleanup(connector);
	kfree(connector);
}

958
959
960
961
962
963
964
965
966
967
968
969
970
static int radeon_dp_get_modes(struct drm_connector *connector)
{
	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
	int ret;

	ret = radeon_ddc_get_modes(radeon_connector);
	return ret;
}

static enum drm_connector_status radeon_dp_detect(struct drm_connector *connector)
{
	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
	enum drm_connector_status ret = connector_status_disconnected;
971
972
	struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv;
	u8 sink_type;
973
974
975
976
977
978
979

	if (radeon_connector->edid) {
		kfree(radeon_connector->edid);
		radeon_connector->edid = NULL;
	}

	sink_type = radeon_dp_getsinktype(radeon_connector);
980
981
	if ((sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
	    (sink_type == CONNECTOR_OBJECT_ID_eDP)) {
Alex Deucher's avatar
Alex Deucher committed
982
983
984
985
		if (radeon_dp_getdpcd(radeon_connector)) {
			radeon_dig_connector->dp_sink_type = sink_type;
			ret = connector_status_connected;
		}
986
987
988
989
990
991
992
	} else {
		radeon_i2c_do_lock(radeon_connector->ddc_bus, 1);
		if (radeon_ddc_probe(radeon_connector)) {
			radeon_dig_connector->dp_sink_type = sink_type;
			ret = connector_status_connected;
		}
		radeon_i2c_do_lock(radeon_connector->ddc_bus, 0);
993
	}
994

995
996
997
	return ret;
}

998
999
1000
1001
1002
1003
1004
1005
static int radeon_dp_mode_valid(struct drm_connector *connector,
				  struct drm_display_mode *mode)
{
	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
	struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv;

	/* XXX check mode bandwidth */

1006
1007
	if ((radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
	    (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP))
1008
1009
1010
1011
1012
		return radeon_dp_mode_valid_helper(radeon_connector, mode);
	else
		return MODE_OK;
}

1013
1014
struct drm_connector_helper_funcs radeon_dp_connector_helper_funcs = {
	.get_modes = radeon_dp_get_modes,
1015
	.mode_valid = radeon_dp_mode_valid,
1016
1017
1018
1019
1020
1021
1022
1023
	.best_encoder = radeon_dvi_encoder,
};

struct drm_connector_funcs radeon_dp_connector_funcs = {
	.dpms = drm_helper_connector_dpms,
	.detect = radeon_dp_detect,
	.fill_modes = drm_helper_probe_single_connector_modes,
	.set_property = radeon_connector_set_property,
1024
	.destroy = radeon_dp_connector_destroy,
1025
1026
1027
	.force = radeon_dvi_force,
};

1028
1029
1030
1031
1032
1033
1034
void
radeon_add_atom_connector(struct drm_device *dev,
			  uint32_t connector_id,
			  uint32_t supported_device,
			  int connector_type,
			  struct radeon_i2c_bus_rec *i2c_bus,
			  bool linkb,
1035
			  uint32_t igp_lane_info,
1036
1037
			  uint16_t connector_object_id,
			  struct radeon_hpd *hpd)
1038
{
1039
	struct radeon_device *rdev = dev->dev_private;
1040
1041
1042
1043
	struct drm_connector *connector;
	struct radeon_connector *radeon_connector;
	struct radeon_connector_atom_dig *radeon_dig_connector;
	uint32_t subpixel_order = SubPixelNone;
1044
	bool shared_ddc = false;
1045
	int ret;
1046
1047

	/* fixme - tv/cv/din */
1048
	if (connector_type == DRM_MODE_CONNECTOR_Unknown)
1049
1050
1051
1052
1053
1054
1055
1056
1057
		return;

	/* see if we already added it */
	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
		radeon_connector = to_radeon_connector(connector);
		if (radeon_connector->connector_id == connector_id) {
			radeon_connector->devices |= supported_device;
			return;
		}
1058
1059
1060
1061
1062
1063
1064
		if (radeon_connector->ddc_bus && i2c_bus->valid) {
			if (memcmp(&radeon_connector->ddc_bus->rec, i2c_bus,
				    sizeof(struct radeon_i2c_bus_rec)) == 0) {
				radeon_connector->shared_ddc = true;
				shared_ddc = true;
			}
		}
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
	}

	radeon_connector = kzalloc(sizeof(struct radeon_connector), GFP_KERNEL);
	if (!radeon_connector)
		return;

	connector = &radeon_connector->base;

	radeon_connector->connector_id = connector_id;
	radeon_connector->devices = supported_device;
1075
	radeon_connector->shared_ddc = shared_ddc;
1076
	radeon_connector->connector_object_id = connector_object_id;
1077
	radeon_connector->hpd = *hpd;
1078
1079
1080
	switch (connector_type) {
	case DRM_MODE_CONNECTOR_VGA:
		drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
1081
1082
1083
		ret = drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs);
		if (ret)
			goto failed;
1084
1085
1086
1087
1088
		if (i2c_bus->valid) {
			radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "VGA");
			if (!radeon_connector->ddc_bus)
				goto failed;
		}
1089
		radeon_connector->dac_load_detect = true;
1090
1091
1092
		drm_connector_attach_property(&radeon_connector->base,
					      rdev->mode_info.load_detect_property,
					      1);
1093
1094
1095
		break;
	case DRM_MODE_CONNECTOR_DVIA:
		drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
1096
1097
1098
		ret = drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs);
		if (ret)
			goto failed;
1099
1100
1101
1102
1103
		if (i2c_bus->valid) {
			radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI");
			if (!radeon_connector->ddc_bus)
				goto failed;
		}
1104
		radeon_connector->dac_load_detect = true;
1105
1106
1107
		drm_connector_attach_property(&radeon_connector->base,
					      rdev->mode_info.load_detect_property,
					      1);
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
		break;
	case DRM_MODE_CONNECTOR_DVII:
	case DRM_MODE_CONNECTOR_DVID:
		radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL);
		if (!radeon_dig_connector)
			goto failed;
		radeon_dig_connector->linkb = linkb;
		radeon_dig_connector->igp_lane_info = igp_lane_info;
		radeon_connector->con_priv = radeon_dig_connector;
		drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type);
1118
1119
1120
		ret = drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs);
		if (ret)
			goto failed;
1121
1122
1123
1124
1125
1126
		if (i2c_bus->valid) {
			radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI");
			if (!radeon_connector->ddc_bus)
				goto failed;
		}
		subpixel_order = SubPixelHorizontalRGB;
1127
1128
1129
		drm_connector_attach_property(&radeon_connector->base,
					      rdev->mode_info.coherent_mode_property,
					      1);
Alex Deucher's avatar
Alex Deucher committed
1130
1131
1132
1133
1134
1135
		if (connector_type == DRM_MODE_CONNECTOR_DVII) {
			radeon_connector->dac_load_detect = true;
			drm_connector_attach_property(&radeon_connector->base,
						      rdev->mode_info.load_detect_property,
						      1);
		}
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
		break;
	case DRM_MODE_CONNECTOR_HDMIA:
	case DRM_MODE_CONNECTOR_HDMIB:
		radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL);
		if (!radeon_dig_connector)
			goto failed;
		radeon_dig_connector->linkb = linkb;
		radeon_dig_connector->igp_lane_info = igp_lane_info;
		radeon_connector->con_priv = radeon_dig_connector;
		drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type);
1146
1147
1148
		ret = drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs);
		if (ret)
			goto failed;
1149
1150
1151
1152
1153
		if (i2c_bus->valid) {
			radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "HDMI");
			if (!radeon_connector->ddc_bus)
				goto failed;
		}
1154
1155
1156
		drm_connector_attach_property(&radeon_connector->base,
					      rdev->mode_info.coherent_mode_property,
					      1);
1157
1158
1159
		subpixel_order = SubPixelHorizontalRGB;
		break;
	case DRM_MODE_CONNECTOR_DisplayPort:
1160
	case DRM_MODE_CONNECTOR_eDP:
1161
1162
1163
1164
1165
1166
		radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL);
		if (!radeon_dig_connector)
			goto failed;
		radeon_dig_connector->linkb = linkb;
		radeon_dig_connector->igp_lane_info = igp_lane_info;
		radeon_connector->con_priv = radeon_dig_connector;
1167
1168
		drm_connector_init(dev, &radeon_connector->base, &radeon_dp_connector_funcs, connector_type);
		ret = drm_connector_helper_add(&radeon_connector->base, &radeon_dp_connector_helper_funcs);
1169
1170
		if (ret)
			goto failed;
1171
		if (i2c_bus->valid) {
Alex Deucher's avatar
Alex Deucher committed
1172
			/* add DP i2c bus */
1173
1174
1175
1176
			if (connector_type == DRM_MODE_CONNECTOR_eDP)
				radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "eDP-auxch");
			else
				radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "DP-auxch");
Alex Deucher's avatar
Alex Deucher committed
1177
1178
			if (!radeon_dig_connector->dp_i2c_bus)
				goto failed;
1179
1180
1181
1182
			if (connector_type == DRM_MODE_CONNECTOR_eDP)
				radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "eDP");
			else
				radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DP");
1183
1184
1185
1186
			if (!radeon_connector->ddc_bus)
				goto failed;
		}
		subpixel_order = SubPixelHorizontalRGB;
Alex Deucher's avatar
Alex Deucher committed
1187
1188
1189
		drm_connector_attach_property(&radeon_connector->base,
					      rdev->mode_info.coherent_mode_property,
					      1);
1190
1191
1192
1193
		break;
	case DRM_MODE_CONNECTOR_SVIDEO:
	case DRM_MODE_CONNECTOR_Composite:
	case DRM_MODE_CONNECTOR_9PinDIN:
1194
1195
		if (radeon_tv == 1) {
			drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type);
1196
1197
1198
1199
1200
1201
1202
			ret = drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs);
			if (ret)
				goto failed;
			radeon_connector->dac_load_detect = true;
			drm_connector_attach_property(&radeon_connector->base,
						      rdev->mode_info.load_detect_property,
						      1);
1203
1204
			drm_connector_attach_property(&radeon_connector->base,
						      rdev->mode_info.tv_std_property,
1205
						      radeon_atombios_get_tv_info(rdev));
1206
		}
1207
1208
1209
1210
1211
1212
1213
1214
1215
		break;
	case DRM_MODE_CONNECTOR_LVDS:
		radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL);
		if (!radeon_dig_connector)
			goto failed;
		radeon_dig_connector->linkb = linkb;
		radeon_dig_connector->igp_lane_info = igp_lane_info;
		radeon_connector->con_priv = radeon_dig_connector;
		drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type);
1216
1217
1218
		ret = drm_connector_helper_add(&radeon_connector->base, &radeon_lvds_connector_helper_funcs);
		if (ret)
			goto failed;
1219
1220
1221
1222
1223
		if (i2c_bus->valid) {
			radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "LVDS");
			if (!radeon_connector->ddc_bus)
				goto failed;
		}
1224
1225
1226
		drm_connector_attach_property(&radeon_connector->base,
					      dev->mode_config.scaling_mode_property,
					      DRM_MODE_SCALE_FULLSCREEN);
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
		subpixel_order = SubPixelHorizontalRGB;
		break;
	}

	connector->display_info.subpixel_order = subpixel_order;
	drm_sysfs_connector_add(connector);
	return;

failed:
	if (radeon_connector->ddc_bus)
		radeon_i2c_destroy(radeon_connector->ddc_bus);
	drm_connector_cleanup(connector);
	kfree(connector);
}

void
radeon_add_legacy_connector(struct drm_device *dev,
			    uint32_t connector_id,
			    uint32_t supported_device,
			    int connector_type,
1247
			    struct radeon_i2c_bus_rec *i2c_bus,
1248
1249
			    uint16_t connector_object_id,
			    struct radeon_hpd *hpd)
1250
{
1251
	struct radeon_device *rdev = dev->dev_private;
1252
1253
1254
	struct drm_connector *connector;
	struct radeon_connector *radeon_connector;
	uint32_t subpixel_order = SubPixelNone;
1255
	int ret;
1256
1257

	/* fixme - tv/cv/din */
1258
	if (connector_type == DRM_MODE_CONNECTOR_Unknown)
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
		return;

	/* see if we already added it */
	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
		radeon_connector = to_radeon_connector(connector);
		if (radeon_connector->connector_id == connector_id) {
			radeon_connector->devices |= supported_device;
			return;
		}
	}

	radeon_connector = kzalloc(sizeof(struct radeon_connector), GFP_KERNEL);
	if (!radeon_connector)
		return;

	connector = &radeon_connector->base;

	radeon_connector->connector_id = connector_id;
	radeon_connector->devices = supported_device;
1278
	radeon_connector->connector_object_id = connector_object_id;
1279
	radeon_connector->hpd = *hpd;
1280
1281
1282
	switch (connector_type) {
	case DRM_MODE_CONNECTOR_VGA:
		drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
1283
1284
1285
		ret = drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs);
		if (ret)
			goto failed;
1286
1287
1288
1289
1290
		if (i2c_bus->valid) {
			radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "VGA");
			if (!radeon_connector->ddc_bus)
				goto failed;
		}
1291
		radeon_connector->dac_load_detect = true;
1292
1293
1294
		drm_connector_attach_property(&radeon_connector->base,
					      rdev->mode_info.load_detect_property,
					      1);
1295
1296
1297
		break;
	case DRM_MODE_CONNECTOR_DVIA:
		drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
1298
1299
1300
		ret = drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs);
		if (ret)
			goto failed;
1301
1302
1303
1304
1305
		if (i2c_bus->valid) {
			radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI");
			if (!radeon_connector->ddc_bus)
				goto failed;
		}
1306
		radeon_connector->dac_load_detect = true;
1307
1308
1309
		drm_connector_attach_property(&radeon_connector->base,
					      rdev->mode_info.load_detect_property,
					      1);
1310
1311
1312
1313
		break;
	case DRM_MODE_CONNECTOR_DVII:
	case DRM_MODE_CONNECTOR_DVID:
		drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type);
1314
1315
1316
		ret = drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs);
		if (ret)
			goto failed;
1317
1318
1319
1320
		if (i2c_bus->valid) {
			radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI");
			if (!radeon_connector->ddc_bus)
				goto failed;
1321
			radeon_connector->dac_load_detect = true;
1322
1323
1324
			drm_connector_attach_property(&radeon_connector->base,
						      rdev->mode_info.load_detect_property,
						      1);
1325
1326
1327
1328
1329
1330
		}
		subpixel_order = SubPixelHorizontalRGB;
		break;
	case DRM_MODE_CONNECTOR_SVIDEO:
	case DRM_MODE_CONNECTOR_Composite:
	case DRM_MODE_CONNECTOR_9PinDIN:
1331
1332
		if (radeon_tv == 1) {
			drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type);
1333
1334
1335
			ret = drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs);
			if (ret)
				goto failed;
1336
			radeon_connector->dac_load_detect = true;
1337
1338
1339
1340
1341
1342
1343
			/* RS400,RC410,RS480 chipset seems to report a lot
			 * of false positive on load detect, we haven't yet
			 * found a way to make load detect reliable on those
			 * chipset, thus just disable it for TV.
			 */
			if (rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480)
				radeon_connector->dac_load_detect = false;
1344
1345
			drm_connector_attach_property(&radeon_connector->base,
						      rdev->mode_info.load_detect_property,
1346
						      radeon_connector->dac_load_detect);
1347
1348
			drm_connector_attach_property(&radeon_connector->base,
						      rdev->mode_info.tv_std_property,
1349
						      radeon_combios_get_tv_info(rdev));
1350
		}
1351
1352
1353
		break;
	case DRM_MODE_CONNECTOR_LVDS:
		drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type);
1354
1355
1356
		ret = drm_connector_helper_add(&radeon_connector->base, &radeon_lvds_connector_helper_funcs);
		if (ret)
			goto failed;
1357
1358
1359
1360
1361
		if (i2c_bus->valid) {
			radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "LVDS");
			if (!radeon_connector->ddc_bus)
				goto failed;
		}
1362
1363
1364
		drm_connector_attach_property(&radeon_connector->base,
					      dev->mode_config.scaling_mode_property,
					      DRM_MODE_SCALE_FULLSCREEN);
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
		subpixel_order = SubPixelHorizontalRGB;
		break;
	}

	connector->display_info.subpixel_order = subpixel_order;
	drm_sysfs_connector_add(connector);
	return;

failed:
	if (radeon_connector->ddc_bus)
		radeon_i2c_destroy(radeon_connector->ddc_bus);
	drm_connector_cleanup(connector);
	kfree(connector);
}