1254885Sdumbbell/*
2254885Sdumbbell * Copyright 2007-8 Advanced Micro Devices, Inc.
3254885Sdumbbell * Copyright 2008 Red Hat Inc.
4254885Sdumbbell *
5254885Sdumbbell * Permission is hereby granted, free of charge, to any person obtaining a
6254885Sdumbbell * copy of this software and associated documentation files (the "Software"),
7254885Sdumbbell * to deal in the Software without restriction, including without limitation
8254885Sdumbbell * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9254885Sdumbbell * and/or sell copies of the Software, and to permit persons to whom the
10254885Sdumbbell * Software is furnished to do so, subject to the following conditions:
11254885Sdumbbell *
12254885Sdumbbell * The above copyright notice and this permission notice shall be included in
13254885Sdumbbell * all copies or substantial portions of the Software.
14254885Sdumbbell *
15254885Sdumbbell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16254885Sdumbbell * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17254885Sdumbbell * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18254885Sdumbbell * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
19254885Sdumbbell * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20254885Sdumbbell * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21254885Sdumbbell * OTHER DEALINGS IN THE SOFTWARE.
22254885Sdumbbell *
23254885Sdumbbell * Authors: Dave Airlie
24254885Sdumbbell *          Alex Deucher
25254885Sdumbbell */
26254885Sdumbbell
27254885Sdumbbell#include <sys/cdefs.h>
28254885Sdumbbell__FBSDID("$FreeBSD: releng/10.3/sys/dev/drm2/radeon/radeon_connectors.c 282199 2015-04-28 19:35:05Z dumbbell $");
29254885Sdumbbell
30254885Sdumbbell#include <dev/drm2/drmP.h>
31254885Sdumbbell#include <dev/drm2/drm_edid.h>
32254885Sdumbbell#include <dev/drm2/drm_crtc_helper.h>
33254885Sdumbbell#include <dev/drm2/drm_fb_helper.h>
34254885Sdumbbell#include <dev/drm2/radeon/radeon_drm.h>
35254885Sdumbbell#include "radeon.h"
36254885Sdumbbell#include "atom.h"
37254885Sdumbbell
38282199Sdumbbell#ifdef FREEBSD_WIP /* FreeBSD: to please GCC 4.2. */
39282199Sdumbbellextern void
40282199Sdumbbellradeon_combios_connected_scratch_regs(struct drm_connector *connector,
41282199Sdumbbell				      struct drm_encoder *encoder,
42282199Sdumbbell				      bool connected);
43282199Sdumbbellextern void
44282199Sdumbbellradeon_atombios_connected_scratch_regs(struct drm_connector *connector,
45282199Sdumbbell				       struct drm_encoder *encoder,
46282199Sdumbbell				       bool connected);
47282199Sdumbbell#endif
48282199Sdumbbell
49254885Sdumbbellvoid radeon_connector_hotplug(struct drm_connector *connector)
50254885Sdumbbell{
51254885Sdumbbell	struct drm_device *dev = connector->dev;
52254885Sdumbbell	struct radeon_device *rdev = dev->dev_private;
53254885Sdumbbell	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
54254885Sdumbbell
55254885Sdumbbell	/* bail if the connector does not have hpd pin, e.g.,
56254885Sdumbbell	 * VGA, TV, etc.
57254885Sdumbbell	 */
58254885Sdumbbell	if (radeon_connector->hpd.hpd == RADEON_HPD_NONE)
59254885Sdumbbell		return;
60254885Sdumbbell
61254885Sdumbbell	radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd);
62254885Sdumbbell
63254885Sdumbbell	/* if the connector is already off, don't turn it back on */
64254885Sdumbbell	if (connector->dpms != DRM_MODE_DPMS_ON)
65254885Sdumbbell		return;
66254885Sdumbbell
67254885Sdumbbell	/* just deal with DP (not eDP) here. */
68254885Sdumbbell	if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) {
69254885Sdumbbell		struct radeon_connector_atom_dig *dig_connector =
70254885Sdumbbell			radeon_connector->con_priv;
71254885Sdumbbell
72254885Sdumbbell		/* if existing sink type was not DP no need to retrain */
73254885Sdumbbell		if (dig_connector->dp_sink_type != CONNECTOR_OBJECT_ID_DISPLAYPORT)
74254885Sdumbbell			return;
75254885Sdumbbell
76254885Sdumbbell		/* first get sink type as it may be reset after (un)plug */
77254885Sdumbbell		dig_connector->dp_sink_type = radeon_dp_getsinktype(radeon_connector);
78254885Sdumbbell		/* don't do anything if sink is not display port, i.e.,
79254885Sdumbbell		 * passive dp->(dvi|hdmi) adaptor
80254885Sdumbbell		 */
81254885Sdumbbell		if (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) {
82254885Sdumbbell			int saved_dpms = connector->dpms;
83254885Sdumbbell			/* Only turn off the display if it's physically disconnected */
84254885Sdumbbell			if (!radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) {
85254885Sdumbbell				drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
86254885Sdumbbell			} else if (radeon_dp_needs_link_train(radeon_connector)) {
87254885Sdumbbell				/* set it to OFF so that drm_helper_connector_dpms()
88254885Sdumbbell				 * won't return immediately since the current state
89254885Sdumbbell				 * is ON at this point.
90254885Sdumbbell				 */
91254885Sdumbbell				connector->dpms = DRM_MODE_DPMS_OFF;
92254885Sdumbbell				drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);
93254885Sdumbbell			}
94254885Sdumbbell			connector->dpms = saved_dpms;
95254885Sdumbbell		}
96254885Sdumbbell	}
97254885Sdumbbell}
98254885Sdumbbell
99254885Sdumbbellstatic void radeon_property_change_mode(struct drm_encoder *encoder)
100254885Sdumbbell{
101254885Sdumbbell	struct drm_crtc *crtc = encoder->crtc;
102254885Sdumbbell
103254885Sdumbbell	if (crtc && crtc->enabled) {
104254885Sdumbbell		drm_crtc_helper_set_mode(crtc, &crtc->mode,
105254885Sdumbbell					 crtc->x, crtc->y, crtc->fb);
106254885Sdumbbell	}
107254885Sdumbbell}
108254885Sdumbbell
109254885Sdumbbellint radeon_get_monitor_bpc(struct drm_connector *connector)
110254885Sdumbbell{
111254885Sdumbbell	struct drm_device *dev = connector->dev;
112254885Sdumbbell	struct radeon_device *rdev = dev->dev_private;
113254885Sdumbbell	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
114254885Sdumbbell	struct radeon_connector_atom_dig *dig_connector;
115254885Sdumbbell	int bpc = 8;
116254885Sdumbbell
117254885Sdumbbell	switch (connector->connector_type) {
118254885Sdumbbell	case DRM_MODE_CONNECTOR_DVII:
119254885Sdumbbell	case DRM_MODE_CONNECTOR_HDMIB:
120254885Sdumbbell		if (radeon_connector->use_digital) {
121254885Sdumbbell			if (drm_detect_hdmi_monitor(radeon_connector->edid)) {
122254885Sdumbbell				if (connector->display_info.bpc)
123254885Sdumbbell					bpc = connector->display_info.bpc;
124254885Sdumbbell			}
125254885Sdumbbell		}
126254885Sdumbbell		break;
127254885Sdumbbell	case DRM_MODE_CONNECTOR_DVID:
128254885Sdumbbell	case DRM_MODE_CONNECTOR_HDMIA:
129254885Sdumbbell		if (drm_detect_hdmi_monitor(radeon_connector->edid)) {
130254885Sdumbbell			if (connector->display_info.bpc)
131254885Sdumbbell				bpc = connector->display_info.bpc;
132254885Sdumbbell		}
133254885Sdumbbell		break;
134254885Sdumbbell	case DRM_MODE_CONNECTOR_DisplayPort:
135254885Sdumbbell		dig_connector = radeon_connector->con_priv;
136254885Sdumbbell		if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
137254885Sdumbbell		    (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP) ||
138254885Sdumbbell		    drm_detect_hdmi_monitor(radeon_connector->edid)) {
139254885Sdumbbell			if (connector->display_info.bpc)
140254885Sdumbbell				bpc = connector->display_info.bpc;
141254885Sdumbbell		}
142254885Sdumbbell		break;
143254885Sdumbbell	case DRM_MODE_CONNECTOR_eDP:
144254885Sdumbbell	case DRM_MODE_CONNECTOR_LVDS:
145254885Sdumbbell		if (connector->display_info.bpc)
146254885Sdumbbell			bpc = connector->display_info.bpc;
147254885Sdumbbell		else if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) {
148254885Sdumbbell			struct drm_connector_helper_funcs *connector_funcs =
149254885Sdumbbell				connector->helper_private;
150254885Sdumbbell			struct drm_encoder *encoder = connector_funcs->best_encoder(connector);
151254885Sdumbbell			struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
152254885Sdumbbell			struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
153254885Sdumbbell
154254885Sdumbbell			if (dig->lcd_misc & ATOM_PANEL_MISC_V13_6BIT_PER_COLOR)
155254885Sdumbbell				bpc = 6;
156254885Sdumbbell			else if (dig->lcd_misc & ATOM_PANEL_MISC_V13_8BIT_PER_COLOR)
157254885Sdumbbell				bpc = 8;
158254885Sdumbbell		}
159254885Sdumbbell		break;
160254885Sdumbbell	}
161254885Sdumbbell	return bpc;
162254885Sdumbbell}
163254885Sdumbbell
164254885Sdumbbellstatic void
165254885Sdumbbellradeon_connector_update_scratch_regs(struct drm_connector *connector, enum drm_connector_status status)
166254885Sdumbbell{
167254885Sdumbbell	struct drm_device *dev = connector->dev;
168254885Sdumbbell	struct radeon_device *rdev = dev->dev_private;
169254885Sdumbbell	struct drm_encoder *best_encoder = NULL;
170254885Sdumbbell	struct drm_encoder *encoder = NULL;
171254885Sdumbbell	struct drm_connector_helper_funcs *connector_funcs = connector->helper_private;
172254885Sdumbbell	struct drm_mode_object *obj;
173254885Sdumbbell	bool connected;
174254885Sdumbbell	int i;
175254885Sdumbbell
176254885Sdumbbell	best_encoder = connector_funcs->best_encoder(connector);
177254885Sdumbbell
178254885Sdumbbell	for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
179254885Sdumbbell		if (connector->encoder_ids[i] == 0)
180254885Sdumbbell			break;
181254885Sdumbbell
182254885Sdumbbell		obj = drm_mode_object_find(connector->dev,
183254885Sdumbbell					   connector->encoder_ids[i],
184254885Sdumbbell					   DRM_MODE_OBJECT_ENCODER);
185254885Sdumbbell		if (!obj)
186254885Sdumbbell			continue;
187254885Sdumbbell
188254885Sdumbbell		encoder = obj_to_encoder(obj);
189254885Sdumbbell
190254885Sdumbbell		if ((encoder == best_encoder) && (status == connector_status_connected))
191254885Sdumbbell			connected = true;
192254885Sdumbbell		else
193254885Sdumbbell			connected = false;
194254885Sdumbbell
195254885Sdumbbell		if (rdev->is_atom_bios)
196254885Sdumbbell			radeon_atombios_connected_scratch_regs(connector, encoder, connected);
197254885Sdumbbell		else
198254885Sdumbbell			radeon_combios_connected_scratch_regs(connector, encoder, connected);
199254885Sdumbbell
200254885Sdumbbell	}
201254885Sdumbbell}
202254885Sdumbbell
203254885Sdumbbellstatic struct drm_encoder *radeon_find_encoder(struct drm_connector *connector, int encoder_type)
204254885Sdumbbell{
205254885Sdumbbell	struct drm_mode_object *obj;
206254885Sdumbbell	struct drm_encoder *encoder;
207254885Sdumbbell	int i;
208254885Sdumbbell
209254885Sdumbbell	for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
210254885Sdumbbell		if (connector->encoder_ids[i] == 0)
211254885Sdumbbell			break;
212254885Sdumbbell
213254885Sdumbbell		obj = drm_mode_object_find(connector->dev, connector->encoder_ids[i], DRM_MODE_OBJECT_ENCODER);
214254885Sdumbbell		if (!obj)
215254885Sdumbbell			continue;
216254885Sdumbbell
217254885Sdumbbell		encoder = obj_to_encoder(obj);
218254885Sdumbbell		if (encoder->encoder_type == encoder_type)
219254885Sdumbbell			return encoder;
220254885Sdumbbell	}
221254885Sdumbbell	return NULL;
222254885Sdumbbell}
223254885Sdumbbell
224254885Sdumbbellstatic struct drm_encoder *radeon_best_single_encoder(struct drm_connector *connector)
225254885Sdumbbell{
226254885Sdumbbell	int enc_id = connector->encoder_ids[0];
227254885Sdumbbell	struct drm_mode_object *obj;
228254885Sdumbbell	struct drm_encoder *encoder;
229254885Sdumbbell
230254885Sdumbbell	/* pick the encoder ids */
231254885Sdumbbell	if (enc_id) {
232254885Sdumbbell		obj = drm_mode_object_find(connector->dev, enc_id, DRM_MODE_OBJECT_ENCODER);
233254885Sdumbbell		if (!obj)
234254885Sdumbbell			return NULL;
235254885Sdumbbell		encoder = obj_to_encoder(obj);
236254885Sdumbbell		return encoder;
237254885Sdumbbell	}
238254885Sdumbbell	return NULL;
239254885Sdumbbell}
240254885Sdumbbell
241254885Sdumbbell/*
242254885Sdumbbell * radeon_connector_analog_encoder_conflict_solve
243254885Sdumbbell * - search for other connectors sharing this encoder
244254885Sdumbbell *   if priority is true, then set them disconnected if this is connected
245254885Sdumbbell *   if priority is false, set us disconnected if they are connected
246254885Sdumbbell */
247254885Sdumbbellstatic enum drm_connector_status
248254885Sdumbbellradeon_connector_analog_encoder_conflict_solve(struct drm_connector *connector,
249254885Sdumbbell					       struct drm_encoder *encoder,
250254885Sdumbbell					       enum drm_connector_status current_status,
251254885Sdumbbell					       bool priority)
252254885Sdumbbell{
253254885Sdumbbell	struct drm_device *dev = connector->dev;
254254885Sdumbbell	struct drm_connector *conflict;
255254885Sdumbbell	struct radeon_connector *radeon_conflict;
256254885Sdumbbell	int i;
257254885Sdumbbell
258254885Sdumbbell	list_for_each_entry(conflict, &dev->mode_config.connector_list, head) {
259254885Sdumbbell		if (conflict == connector)
260254885Sdumbbell			continue;
261254885Sdumbbell
262254885Sdumbbell		radeon_conflict = to_radeon_connector(conflict);
263254885Sdumbbell		for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
264254885Sdumbbell			if (conflict->encoder_ids[i] == 0)
265254885Sdumbbell				break;
266254885Sdumbbell
267254885Sdumbbell			/* if the IDs match */
268254885Sdumbbell			if (conflict->encoder_ids[i] == encoder->base.id) {
269254885Sdumbbell				if (conflict->status != connector_status_connected)
270254885Sdumbbell					continue;
271254885Sdumbbell
272254885Sdumbbell				if (radeon_conflict->use_digital)
273254885Sdumbbell					continue;
274254885Sdumbbell
275254885Sdumbbell				if (priority == true) {
276254885Sdumbbell					DRM_DEBUG_KMS("1: conflicting encoders switching off %s\n", drm_get_connector_name(conflict));
277254885Sdumbbell					DRM_DEBUG_KMS("in favor of %s\n", drm_get_connector_name(connector));
278254885Sdumbbell					conflict->status = connector_status_disconnected;
279254885Sdumbbell					radeon_connector_update_scratch_regs(conflict, connector_status_disconnected);
280254885Sdumbbell				} else {
281254885Sdumbbell					DRM_DEBUG_KMS("2: conflicting encoders switching off %s\n", drm_get_connector_name(connector));
282254885Sdumbbell					DRM_DEBUG_KMS("in favor of %s\n", drm_get_connector_name(conflict));
283254885Sdumbbell					current_status = connector_status_disconnected;
284254885Sdumbbell				}
285254885Sdumbbell				break;
286254885Sdumbbell			}
287254885Sdumbbell		}
288254885Sdumbbell	}
289254885Sdumbbell	return current_status;
290254885Sdumbbell
291254885Sdumbbell}
292254885Sdumbbell
293254885Sdumbbellstatic struct drm_display_mode *radeon_fp_native_mode(struct drm_encoder *encoder)
294254885Sdumbbell{
295254885Sdumbbell	struct drm_device *dev = encoder->dev;
296254885Sdumbbell	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
297254885Sdumbbell	struct drm_display_mode *mode = NULL;
298254885Sdumbbell	struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
299254885Sdumbbell
300254885Sdumbbell	if (native_mode->hdisplay != 0 &&
301254885Sdumbbell	    native_mode->vdisplay != 0 &&
302254885Sdumbbell	    native_mode->clock != 0) {
303254885Sdumbbell		mode = drm_mode_duplicate(dev, native_mode);
304254885Sdumbbell		mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER;
305254885Sdumbbell		drm_mode_set_name(mode);
306254885Sdumbbell
307254885Sdumbbell		DRM_DEBUG_KMS("Adding native panel mode %s\n", mode->name);
308254885Sdumbbell	} else if (native_mode->hdisplay != 0 &&
309254885Sdumbbell		   native_mode->vdisplay != 0) {
310254885Sdumbbell		/* mac laptops without an edid */
311254885Sdumbbell		/* Note that this is not necessarily the exact panel mode,
312254885Sdumbbell		 * but an approximation based on the cvt formula.  For these
313254885Sdumbbell		 * systems we should ideally read the mode info out of the
314254885Sdumbbell		 * registers or add a mode table, but this works and is much
315254885Sdumbbell		 * simpler.
316254885Sdumbbell		 */
317254885Sdumbbell		mode = drm_cvt_mode(dev, native_mode->hdisplay, native_mode->vdisplay, 60, true, false, false);
318254885Sdumbbell		mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER;
319254885Sdumbbell		DRM_DEBUG_KMS("Adding cvt approximation of native panel mode %s\n", mode->name);
320254885Sdumbbell	}
321254885Sdumbbell	return mode;
322254885Sdumbbell}
323254885Sdumbbell
324254885Sdumbbellstatic void radeon_add_common_modes(struct drm_encoder *encoder, struct drm_connector *connector)
325254885Sdumbbell{
326254885Sdumbbell	struct drm_device *dev = encoder->dev;
327254885Sdumbbell	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
328254885Sdumbbell	struct drm_display_mode *mode = NULL;
329254885Sdumbbell	struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
330254885Sdumbbell	int i;
331254885Sdumbbell	struct mode_size {
332254885Sdumbbell		int w;
333254885Sdumbbell		int h;
334254885Sdumbbell	} common_modes[17] = {
335254885Sdumbbell		{ 640,  480},
336254885Sdumbbell		{ 720,  480},
337254885Sdumbbell		{ 800,  600},
338254885Sdumbbell		{ 848,  480},
339254885Sdumbbell		{1024,  768},
340254885Sdumbbell		{1152,  768},
341254885Sdumbbell		{1280,  720},
342254885Sdumbbell		{1280,  800},
343254885Sdumbbell		{1280,  854},
344254885Sdumbbell		{1280,  960},
345254885Sdumbbell		{1280, 1024},
346254885Sdumbbell		{1440,  900},
347254885Sdumbbell		{1400, 1050},
348254885Sdumbbell		{1680, 1050},
349254885Sdumbbell		{1600, 1200},
350254885Sdumbbell		{1920, 1080},
351254885Sdumbbell		{1920, 1200}
352254885Sdumbbell	};
353254885Sdumbbell
354254885Sdumbbell	for (i = 0; i < 17; i++) {
355254885Sdumbbell		if (radeon_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) {
356254885Sdumbbell			if (common_modes[i].w > 1024 ||
357254885Sdumbbell			    common_modes[i].h > 768)
358254885Sdumbbell				continue;
359254885Sdumbbell		}
360254885Sdumbbell		if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
361254885Sdumbbell			if (common_modes[i].w > native_mode->hdisplay ||
362254885Sdumbbell			    common_modes[i].h > native_mode->vdisplay ||
363254885Sdumbbell			    (common_modes[i].w == native_mode->hdisplay &&
364254885Sdumbbell			     common_modes[i].h == native_mode->vdisplay))
365254885Sdumbbell				continue;
366254885Sdumbbell		}
367254885Sdumbbell		if (common_modes[i].w < 320 || common_modes[i].h < 200)
368254885Sdumbbell			continue;
369254885Sdumbbell
370254885Sdumbbell		mode = drm_cvt_mode(dev, common_modes[i].w, common_modes[i].h, 60, false, false, false);
371254885Sdumbbell		drm_mode_probed_add(connector, mode);
372254885Sdumbbell	}
373254885Sdumbbell}
374254885Sdumbbell
375254885Sdumbbellstatic int radeon_connector_set_property(struct drm_connector *connector, struct drm_property *property,
376254885Sdumbbell				  uint64_t val)
377254885Sdumbbell{
378254885Sdumbbell	struct drm_device *dev = connector->dev;
379254885Sdumbbell	struct radeon_device *rdev = dev->dev_private;
380254885Sdumbbell	struct drm_encoder *encoder;
381254885Sdumbbell	struct radeon_encoder *radeon_encoder;
382254885Sdumbbell
383254885Sdumbbell	if (property == rdev->mode_info.coherent_mode_property) {
384254885Sdumbbell		struct radeon_encoder_atom_dig *dig;
385254885Sdumbbell		bool new_coherent_mode;
386254885Sdumbbell
387254885Sdumbbell		/* need to find digital encoder on connector */
388254885Sdumbbell		encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS);
389254885Sdumbbell		if (!encoder)
390254885Sdumbbell			return 0;
391254885Sdumbbell
392254885Sdumbbell		radeon_encoder = to_radeon_encoder(encoder);
393254885Sdumbbell
394254885Sdumbbell		if (!radeon_encoder->enc_priv)
395254885Sdumbbell			return 0;
396254885Sdumbbell
397254885Sdumbbell		dig = radeon_encoder->enc_priv;
398254885Sdumbbell		new_coherent_mode = val ? true : false;
399254885Sdumbbell		if (dig->coherent_mode != new_coherent_mode) {
400254885Sdumbbell			dig->coherent_mode = new_coherent_mode;
401254885Sdumbbell			radeon_property_change_mode(&radeon_encoder->base);
402254885Sdumbbell		}
403254885Sdumbbell	}
404254885Sdumbbell
405254885Sdumbbell	if (property == rdev->mode_info.underscan_property) {
406254885Sdumbbell		/* need to find digital encoder on connector */
407254885Sdumbbell		encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS);
408254885Sdumbbell		if (!encoder)
409254885Sdumbbell			return 0;
410254885Sdumbbell
411254885Sdumbbell		radeon_encoder = to_radeon_encoder(encoder);
412254885Sdumbbell
413254885Sdumbbell		if (radeon_encoder->underscan_type != val) {
414254885Sdumbbell			radeon_encoder->underscan_type = val;
415254885Sdumbbell			radeon_property_change_mode(&radeon_encoder->base);
416254885Sdumbbell		}
417254885Sdumbbell	}
418254885Sdumbbell
419254885Sdumbbell	if (property == rdev->mode_info.underscan_hborder_property) {
420254885Sdumbbell		/* need to find digital encoder on connector */
421254885Sdumbbell		encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS);
422254885Sdumbbell		if (!encoder)
423254885Sdumbbell			return 0;
424254885Sdumbbell
425254885Sdumbbell		radeon_encoder = to_radeon_encoder(encoder);
426254885Sdumbbell
427254885Sdumbbell		if (radeon_encoder->underscan_hborder != val) {
428254885Sdumbbell			radeon_encoder->underscan_hborder = val;
429254885Sdumbbell			radeon_property_change_mode(&radeon_encoder->base);
430254885Sdumbbell		}
431254885Sdumbbell	}
432254885Sdumbbell
433254885Sdumbbell	if (property == rdev->mode_info.underscan_vborder_property) {
434254885Sdumbbell		/* need to find digital encoder on connector */
435254885Sdumbbell		encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS);
436254885Sdumbbell		if (!encoder)
437254885Sdumbbell			return 0;
438254885Sdumbbell
439254885Sdumbbell		radeon_encoder = to_radeon_encoder(encoder);
440254885Sdumbbell
441254885Sdumbbell		if (radeon_encoder->underscan_vborder != val) {
442254885Sdumbbell			radeon_encoder->underscan_vborder = val;
443254885Sdumbbell			radeon_property_change_mode(&radeon_encoder->base);
444254885Sdumbbell		}
445254885Sdumbbell	}
446254885Sdumbbell
447254885Sdumbbell	if (property == rdev->mode_info.tv_std_property) {
448254885Sdumbbell		encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TVDAC);
449254885Sdumbbell		if (!encoder) {
450254885Sdumbbell			encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_DAC);
451254885Sdumbbell		}
452254885Sdumbbell
453254885Sdumbbell		if (!encoder)
454254885Sdumbbell			return 0;
455254885Sdumbbell
456254885Sdumbbell		radeon_encoder = to_radeon_encoder(encoder);
457254885Sdumbbell		if (!radeon_encoder->enc_priv)
458254885Sdumbbell			return 0;
459254885Sdumbbell		if (ASIC_IS_AVIVO(rdev) || radeon_r4xx_atom) {
460254885Sdumbbell			struct radeon_encoder_atom_dac *dac_int;
461254885Sdumbbell			dac_int = radeon_encoder->enc_priv;
462254885Sdumbbell			dac_int->tv_std = val;
463254885Sdumbbell		} else {
464254885Sdumbbell			struct radeon_encoder_tv_dac *dac_int;
465254885Sdumbbell			dac_int = radeon_encoder->enc_priv;
466254885Sdumbbell			dac_int->tv_std = val;
467254885Sdumbbell		}
468254885Sdumbbell		radeon_property_change_mode(&radeon_encoder->base);
469254885Sdumbbell	}
470254885Sdumbbell
471254885Sdumbbell	if (property == rdev->mode_info.load_detect_property) {
472254885Sdumbbell		struct radeon_connector *radeon_connector =
473254885Sdumbbell			to_radeon_connector(connector);
474254885Sdumbbell
475254885Sdumbbell		if (val == 0)
476254885Sdumbbell			radeon_connector->dac_load_detect = false;
477254885Sdumbbell		else
478254885Sdumbbell			radeon_connector->dac_load_detect = true;
479254885Sdumbbell	}
480254885Sdumbbell
481254885Sdumbbell	if (property == rdev->mode_info.tmds_pll_property) {
482254885Sdumbbell		struct radeon_encoder_int_tmds *tmds = NULL;
483254885Sdumbbell		bool ret = false;
484254885Sdumbbell		/* need to find digital encoder on connector */
485254885Sdumbbell		encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS);
486254885Sdumbbell		if (!encoder)
487254885Sdumbbell			return 0;
488254885Sdumbbell
489254885Sdumbbell		radeon_encoder = to_radeon_encoder(encoder);
490254885Sdumbbell
491254885Sdumbbell		tmds = radeon_encoder->enc_priv;
492254885Sdumbbell		if (!tmds)
493254885Sdumbbell			return 0;
494254885Sdumbbell
495254885Sdumbbell		if (val == 0) {
496254885Sdumbbell			if (rdev->is_atom_bios)
497254885Sdumbbell				ret = radeon_atombios_get_tmds_info(radeon_encoder, tmds);
498254885Sdumbbell			else
499254885Sdumbbell				ret = radeon_legacy_get_tmds_info_from_combios(radeon_encoder, tmds);
500254885Sdumbbell		}
501254885Sdumbbell		if (val == 1 || ret == false) {
502254885Sdumbbell			radeon_legacy_get_tmds_info_from_table(radeon_encoder, tmds);
503254885Sdumbbell		}
504254885Sdumbbell		radeon_property_change_mode(&radeon_encoder->base);
505254885Sdumbbell	}
506254885Sdumbbell
507254885Sdumbbell	return 0;
508254885Sdumbbell}
509254885Sdumbbell
510254885Sdumbbellstatic void radeon_fixup_lvds_native_mode(struct drm_encoder *encoder,
511254885Sdumbbell					  struct drm_connector *connector)
512254885Sdumbbell{
513254885Sdumbbell	struct radeon_encoder *radeon_encoder =	to_radeon_encoder(encoder);
514254885Sdumbbell	struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
515254885Sdumbbell	struct drm_display_mode *t, *mode;
516254885Sdumbbell
517254885Sdumbbell	/* If the EDID preferred mode doesn't match the native mode, use it */
518254885Sdumbbell	list_for_each_entry_safe(mode, t, &connector->probed_modes, head) {
519254885Sdumbbell		if (mode->type & DRM_MODE_TYPE_PREFERRED) {
520254885Sdumbbell			if (mode->hdisplay != native_mode->hdisplay ||
521254885Sdumbbell			    mode->vdisplay != native_mode->vdisplay)
522254885Sdumbbell				memcpy(native_mode, mode, sizeof(*mode));
523254885Sdumbbell		}
524254885Sdumbbell	}
525254885Sdumbbell
526254885Sdumbbell	/* Try to get native mode details from EDID if necessary */
527254885Sdumbbell	if (!native_mode->clock) {
528254885Sdumbbell		list_for_each_entry_safe(mode, t, &connector->probed_modes, head) {
529254885Sdumbbell			if (mode->hdisplay == native_mode->hdisplay &&
530254885Sdumbbell			    mode->vdisplay == native_mode->vdisplay) {
531254885Sdumbbell				*native_mode = *mode;
532254885Sdumbbell				drm_mode_set_crtcinfo(native_mode, CRTC_INTERLACE_HALVE_V);
533254885Sdumbbell				DRM_DEBUG_KMS("Determined LVDS native mode details from EDID\n");
534254885Sdumbbell				break;
535254885Sdumbbell			}
536254885Sdumbbell		}
537254885Sdumbbell	}
538254885Sdumbbell
539254885Sdumbbell	if (!native_mode->clock) {
540254885Sdumbbell		DRM_DEBUG_KMS("No LVDS native mode details, disabling RMX\n");
541254885Sdumbbell		radeon_encoder->rmx_type = RMX_OFF;
542254885Sdumbbell	}
543254885Sdumbbell}
544254885Sdumbbell
545254885Sdumbbellstatic int radeon_lvds_get_modes(struct drm_connector *connector)
546254885Sdumbbell{
547254885Sdumbbell	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
548254885Sdumbbell	struct drm_encoder *encoder;
549254885Sdumbbell	int ret = 0;
550254885Sdumbbell	struct drm_display_mode *mode;
551254885Sdumbbell
552254885Sdumbbell	if (radeon_connector->ddc_bus) {
553254885Sdumbbell		ret = radeon_ddc_get_modes(radeon_connector);
554254885Sdumbbell		if (ret > 0) {
555254885Sdumbbell			encoder = radeon_best_single_encoder(connector);
556254885Sdumbbell			if (encoder) {
557254885Sdumbbell				radeon_fixup_lvds_native_mode(encoder, connector);
558254885Sdumbbell				/* add scaled modes */
559254885Sdumbbell				radeon_add_common_modes(encoder, connector);
560254885Sdumbbell			}
561254885Sdumbbell			return ret;
562254885Sdumbbell		}
563254885Sdumbbell	}
564254885Sdumbbell
565254885Sdumbbell	encoder = radeon_best_single_encoder(connector);
566254885Sdumbbell	if (!encoder)
567254885Sdumbbell		return 0;
568254885Sdumbbell
569254885Sdumbbell	/* we have no EDID modes */
570254885Sdumbbell	mode = radeon_fp_native_mode(encoder);
571254885Sdumbbell	if (mode) {
572254885Sdumbbell		ret = 1;
573254885Sdumbbell		drm_mode_probed_add(connector, mode);
574254885Sdumbbell		/* add the width/height from vbios tables if available */
575254885Sdumbbell		connector->display_info.width_mm = mode->width_mm;
576254885Sdumbbell		connector->display_info.height_mm = mode->height_mm;
577254885Sdumbbell		/* add scaled modes */
578254885Sdumbbell		radeon_add_common_modes(encoder, connector);
579254885Sdumbbell	}
580254885Sdumbbell
581254885Sdumbbell	return ret;
582254885Sdumbbell}
583254885Sdumbbell
584254885Sdumbbellstatic int radeon_lvds_mode_valid(struct drm_connector *connector,
585254885Sdumbbell				  struct drm_display_mode *mode)
586254885Sdumbbell{
587254885Sdumbbell	struct drm_encoder *encoder = radeon_best_single_encoder(connector);
588254885Sdumbbell
589254885Sdumbbell	if ((mode->hdisplay < 320) || (mode->vdisplay < 240))
590254885Sdumbbell		return MODE_PANEL;
591254885Sdumbbell
592254885Sdumbbell	if (encoder) {
593254885Sdumbbell		struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
594254885Sdumbbell		struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
595254885Sdumbbell
596254885Sdumbbell		/* AVIVO hardware supports downscaling modes larger than the panel
597254885Sdumbbell		 * to the panel size, but I'm not sure this is desirable.
598254885Sdumbbell		 */
599254885Sdumbbell		if ((mode->hdisplay > native_mode->hdisplay) ||
600254885Sdumbbell		    (mode->vdisplay > native_mode->vdisplay))
601254885Sdumbbell			return MODE_PANEL;
602254885Sdumbbell
603254885Sdumbbell		/* if scaling is disabled, block non-native modes */
604254885Sdumbbell		if (radeon_encoder->rmx_type == RMX_OFF) {
605254885Sdumbbell			if ((mode->hdisplay != native_mode->hdisplay) ||
606254885Sdumbbell			    (mode->vdisplay != native_mode->vdisplay))
607254885Sdumbbell				return MODE_PANEL;
608254885Sdumbbell		}
609254885Sdumbbell	}
610254885Sdumbbell
611254885Sdumbbell	return MODE_OK;
612254885Sdumbbell}
613254885Sdumbbell
614254885Sdumbbellstatic enum drm_connector_status
615254885Sdumbbellradeon_lvds_detect(struct drm_connector *connector, bool force)
616254885Sdumbbell{
617254885Sdumbbell	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
618254885Sdumbbell	struct drm_encoder *encoder = radeon_best_single_encoder(connector);
619254885Sdumbbell	enum drm_connector_status ret = connector_status_disconnected;
620254885Sdumbbell
621254885Sdumbbell	if (encoder) {
622254885Sdumbbell		struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
623254885Sdumbbell		struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
624254885Sdumbbell
625254885Sdumbbell		/* check if panel is valid */
626254885Sdumbbell		if (native_mode->hdisplay >= 320 && native_mode->vdisplay >= 240)
627254885Sdumbbell			ret = connector_status_connected;
628254885Sdumbbell
629254885Sdumbbell	}
630254885Sdumbbell
631254885Sdumbbell	/* check for edid as well */
632254885Sdumbbell	if (radeon_connector->edid)
633254885Sdumbbell		ret = connector_status_connected;
634254885Sdumbbell	else {
635254885Sdumbbell		if (radeon_connector->ddc_bus) {
636254885Sdumbbell			radeon_connector->edid = drm_get_edid(&radeon_connector->base,
637254885Sdumbbell							      radeon_connector->ddc_bus->adapter);
638254885Sdumbbell			if (radeon_connector->edid)
639254885Sdumbbell				ret = connector_status_connected;
640254885Sdumbbell		}
641254885Sdumbbell	}
642254885Sdumbbell	/* check acpi lid status ??? */
643254885Sdumbbell
644254885Sdumbbell	radeon_connector_update_scratch_regs(connector, ret);
645254885Sdumbbell	return ret;
646254885Sdumbbell}
647254885Sdumbbell
648254885Sdumbbellstatic void radeon_connector_destroy(struct drm_connector *connector)
649254885Sdumbbell{
650254885Sdumbbell	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
651254885Sdumbbell
652254885Sdumbbell	if (radeon_connector->edid)
653254885Sdumbbell		free(radeon_connector->edid, DRM_MEM_KMS);
654254885Sdumbbell	free(radeon_connector->con_priv, DRM_MEM_DRIVER);
655282199Sdumbbell#ifdef FREEBSD_WIP
656254885Sdumbbell	drm_sysfs_connector_remove(connector);
657282199Sdumbbell#endif /* FREEBSD_WIP */
658254885Sdumbbell	drm_connector_cleanup(connector);
659254885Sdumbbell	free(connector, DRM_MEM_DRIVER);
660254885Sdumbbell}
661254885Sdumbbell
662254885Sdumbbellstatic int radeon_lvds_set_property(struct drm_connector *connector,
663254885Sdumbbell				    struct drm_property *property,
664254885Sdumbbell				    uint64_t value)
665254885Sdumbbell{
666254885Sdumbbell	struct drm_device *dev = connector->dev;
667254885Sdumbbell	struct radeon_encoder *radeon_encoder;
668254885Sdumbbell	enum radeon_rmx_type rmx_type;
669254885Sdumbbell
670254885Sdumbbell	DRM_DEBUG_KMS("\n");
671254885Sdumbbell	if (property != dev->mode_config.scaling_mode_property)
672254885Sdumbbell		return 0;
673254885Sdumbbell
674254885Sdumbbell	if (connector->encoder)
675254885Sdumbbell		radeon_encoder = to_radeon_encoder(connector->encoder);
676254885Sdumbbell	else {
677254885Sdumbbell		struct drm_connector_helper_funcs *connector_funcs = connector->helper_private;
678254885Sdumbbell		radeon_encoder = to_radeon_encoder(connector_funcs->best_encoder(connector));
679254885Sdumbbell	}
680254885Sdumbbell
681254885Sdumbbell	switch (value) {
682254885Sdumbbell	case DRM_MODE_SCALE_NONE: rmx_type = RMX_OFF; break;
683254885Sdumbbell	case DRM_MODE_SCALE_CENTER: rmx_type = RMX_CENTER; break;
684254885Sdumbbell	case DRM_MODE_SCALE_ASPECT: rmx_type = RMX_ASPECT; break;
685254885Sdumbbell	default:
686254885Sdumbbell	case DRM_MODE_SCALE_FULLSCREEN: rmx_type = RMX_FULL; break;
687254885Sdumbbell	}
688254885Sdumbbell	if (radeon_encoder->rmx_type == rmx_type)
689254885Sdumbbell		return 0;
690254885Sdumbbell
691254885Sdumbbell	radeon_encoder->rmx_type = rmx_type;
692254885Sdumbbell
693254885Sdumbbell	radeon_property_change_mode(&radeon_encoder->base);
694254885Sdumbbell	return 0;
695254885Sdumbbell}
696254885Sdumbbell
697254885Sdumbbell
698254885Sdumbbellstatic const struct drm_connector_helper_funcs radeon_lvds_connector_helper_funcs = {
699254885Sdumbbell	.get_modes = radeon_lvds_get_modes,
700254885Sdumbbell	.mode_valid = radeon_lvds_mode_valid,
701254885Sdumbbell	.best_encoder = radeon_best_single_encoder,
702254885Sdumbbell};
703254885Sdumbbell
704254885Sdumbbellstatic const struct drm_connector_funcs radeon_lvds_connector_funcs = {
705254885Sdumbbell	.dpms = drm_helper_connector_dpms,
706254885Sdumbbell	.detect = radeon_lvds_detect,
707254885Sdumbbell	.fill_modes = drm_helper_probe_single_connector_modes,
708254885Sdumbbell	.destroy = radeon_connector_destroy,
709254885Sdumbbell	.set_property = radeon_lvds_set_property,
710254885Sdumbbell};
711254885Sdumbbell
712254885Sdumbbellstatic int radeon_vga_get_modes(struct drm_connector *connector)
713254885Sdumbbell{
714254885Sdumbbell	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
715254885Sdumbbell	int ret;
716254885Sdumbbell
717254885Sdumbbell	ret = radeon_ddc_get_modes(radeon_connector);
718254885Sdumbbell
719254885Sdumbbell	return ret;
720254885Sdumbbell}
721254885Sdumbbell
722254885Sdumbbellstatic int radeon_vga_mode_valid(struct drm_connector *connector,
723254885Sdumbbell				  struct drm_display_mode *mode)
724254885Sdumbbell{
725254885Sdumbbell	struct drm_device *dev = connector->dev;
726254885Sdumbbell	struct radeon_device *rdev = dev->dev_private;
727254885Sdumbbell
728254885Sdumbbell	/* XXX check mode bandwidth */
729254885Sdumbbell
730254885Sdumbbell	if ((mode->clock / 10) > rdev->clock.max_pixel_clock)
731254885Sdumbbell		return MODE_CLOCK_HIGH;
732254885Sdumbbell
733254885Sdumbbell	return MODE_OK;
734254885Sdumbbell}
735254885Sdumbbell
736254885Sdumbbellstatic enum drm_connector_status
737254885Sdumbbellradeon_vga_detect(struct drm_connector *connector, bool force)
738254885Sdumbbell{
739254885Sdumbbell	struct drm_device *dev = connector->dev;
740254885Sdumbbell	struct radeon_device *rdev = dev->dev_private;
741254885Sdumbbell	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
742254885Sdumbbell	struct drm_encoder *encoder;
743254885Sdumbbell	struct drm_encoder_helper_funcs *encoder_funcs;
744254885Sdumbbell	bool dret = false;
745254885Sdumbbell	enum drm_connector_status ret = connector_status_disconnected;
746254885Sdumbbell
747254885Sdumbbell	encoder = radeon_best_single_encoder(connector);
748254885Sdumbbell	if (!encoder)
749254885Sdumbbell		ret = connector_status_disconnected;
750254885Sdumbbell
751254885Sdumbbell	if (radeon_connector->ddc_bus)
752254885Sdumbbell		dret = radeon_ddc_probe(radeon_connector, false);
753254885Sdumbbell	if (dret) {
754254885Sdumbbell		radeon_connector->detected_by_load = false;
755254885Sdumbbell		if (radeon_connector->edid) {
756254885Sdumbbell			free(radeon_connector->edid, DRM_MEM_KMS);
757254885Sdumbbell			radeon_connector->edid = NULL;
758254885Sdumbbell		}
759254885Sdumbbell		radeon_connector->edid = drm_get_edid(&radeon_connector->base, radeon_connector->ddc_bus->adapter);
760254885Sdumbbell
761254885Sdumbbell		if (!radeon_connector->edid) {
762274862Sdumbbell			DRM_DEBUG_KMS("%s: probed a monitor but no|invalid EDID\n",
763254885Sdumbbell					drm_get_connector_name(connector));
764254885Sdumbbell			ret = connector_status_connected;
765254885Sdumbbell		} else {
766254885Sdumbbell			radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL);
767254885Sdumbbell
768254885Sdumbbell			/* some oems have boards with separate digital and analog connectors
769254885Sdumbbell			 * with a shared ddc line (often vga + hdmi)
770254885Sdumbbell			 */
771254885Sdumbbell			if (radeon_connector->use_digital && radeon_connector->shared_ddc) {
772254885Sdumbbell				free(radeon_connector->edid, DRM_MEM_KMS);
773254885Sdumbbell				radeon_connector->edid = NULL;
774254885Sdumbbell				ret = connector_status_disconnected;
775254885Sdumbbell			} else
776254885Sdumbbell				ret = connector_status_connected;
777254885Sdumbbell		}
778254885Sdumbbell	} else {
779254885Sdumbbell
780254885Sdumbbell		/* if we aren't forcing don't do destructive polling */
781254885Sdumbbell		if (!force) {
782254885Sdumbbell			/* only return the previous status if we last
783254885Sdumbbell			 * detected a monitor via load.
784254885Sdumbbell			 */
785254885Sdumbbell			if (radeon_connector->detected_by_load)
786254885Sdumbbell				return connector->status;
787254885Sdumbbell			else
788254885Sdumbbell				return ret;
789254885Sdumbbell		}
790254885Sdumbbell
791254885Sdumbbell		if (radeon_connector->dac_load_detect && encoder) {
792254885Sdumbbell			encoder_funcs = encoder->helper_private;
793254885Sdumbbell			ret = encoder_funcs->detect(encoder, connector);
794254885Sdumbbell			if (ret != connector_status_disconnected)
795254885Sdumbbell				radeon_connector->detected_by_load = true;
796254885Sdumbbell		}
797254885Sdumbbell	}
798254885Sdumbbell
799254885Sdumbbell	if (ret == connector_status_connected)
800254885Sdumbbell		ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, true);
801254885Sdumbbell
802254885Sdumbbell	/* RN50 and some RV100 asics in servers often have a hardcoded EDID in the
803254885Sdumbbell	 * vbios to deal with KVMs. If we have one and are not able to detect a monitor
804254885Sdumbbell	 * by other means, assume the CRT is connected and use that EDID.
805254885Sdumbbell	 */
806254885Sdumbbell	if ((!rdev->is_atom_bios) &&
807254885Sdumbbell	    (ret == connector_status_disconnected) &&
808254885Sdumbbell	    rdev->mode_info.bios_hardcoded_edid_size) {
809254885Sdumbbell		ret = connector_status_connected;
810254885Sdumbbell	}
811254885Sdumbbell
812254885Sdumbbell	radeon_connector_update_scratch_regs(connector, ret);
813254885Sdumbbell	return ret;
814254885Sdumbbell}
815254885Sdumbbell
816254885Sdumbbellstatic const struct drm_connector_helper_funcs radeon_vga_connector_helper_funcs = {
817254885Sdumbbell	.get_modes = radeon_vga_get_modes,
818254885Sdumbbell	.mode_valid = radeon_vga_mode_valid,
819254885Sdumbbell	.best_encoder = radeon_best_single_encoder,
820254885Sdumbbell};
821254885Sdumbbell
822254885Sdumbbellstatic const struct drm_connector_funcs radeon_vga_connector_funcs = {
823254885Sdumbbell	.dpms = drm_helper_connector_dpms,
824254885Sdumbbell	.detect = radeon_vga_detect,
825254885Sdumbbell	.fill_modes = drm_helper_probe_single_connector_modes,
826254885Sdumbbell	.destroy = radeon_connector_destroy,
827254885Sdumbbell	.set_property = radeon_connector_set_property,
828254885Sdumbbell};
829254885Sdumbbell
830254885Sdumbbellstatic int radeon_tv_get_modes(struct drm_connector *connector)
831254885Sdumbbell{
832254885Sdumbbell	struct drm_device *dev = connector->dev;
833254885Sdumbbell	struct radeon_device *rdev = dev->dev_private;
834254885Sdumbbell	struct drm_display_mode *tv_mode;
835254885Sdumbbell	struct drm_encoder *encoder;
836254885Sdumbbell
837254885Sdumbbell	encoder = radeon_best_single_encoder(connector);
838254885Sdumbbell	if (!encoder)
839254885Sdumbbell		return 0;
840254885Sdumbbell
841254885Sdumbbell	/* avivo chips can scale any mode */
842254885Sdumbbell	if (rdev->family >= CHIP_RS600)
843254885Sdumbbell		/* add scaled modes */
844254885Sdumbbell		radeon_add_common_modes(encoder, connector);
845254885Sdumbbell	else {
846254885Sdumbbell		/* only 800x600 is supported right now on pre-avivo chips */
847254885Sdumbbell		tv_mode = drm_cvt_mode(dev, 800, 600, 60, false, false, false);
848254885Sdumbbell		tv_mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
849254885Sdumbbell		drm_mode_probed_add(connector, tv_mode);
850254885Sdumbbell	}
851254885Sdumbbell	return 1;
852254885Sdumbbell}
853254885Sdumbbell
854254885Sdumbbellstatic int radeon_tv_mode_valid(struct drm_connector *connector,
855254885Sdumbbell				struct drm_display_mode *mode)
856254885Sdumbbell{
857254885Sdumbbell	if ((mode->hdisplay > 1024) || (mode->vdisplay > 768))
858254885Sdumbbell		return MODE_CLOCK_RANGE;
859254885Sdumbbell	return MODE_OK;
860254885Sdumbbell}
861254885Sdumbbell
862254885Sdumbbellstatic enum drm_connector_status
863254885Sdumbbellradeon_tv_detect(struct drm_connector *connector, bool force)
864254885Sdumbbell{
865254885Sdumbbell	struct drm_encoder *encoder;
866254885Sdumbbell	struct drm_encoder_helper_funcs *encoder_funcs;
867254885Sdumbbell	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
868254885Sdumbbell	enum drm_connector_status ret = connector_status_disconnected;
869254885Sdumbbell
870254885Sdumbbell	if (!radeon_connector->dac_load_detect)
871254885Sdumbbell		return ret;
872254885Sdumbbell
873254885Sdumbbell	encoder = radeon_best_single_encoder(connector);
874254885Sdumbbell	if (!encoder)
875254885Sdumbbell		ret = connector_status_disconnected;
876254885Sdumbbell	else {
877254885Sdumbbell		encoder_funcs = encoder->helper_private;
878254885Sdumbbell		ret = encoder_funcs->detect(encoder, connector);
879254885Sdumbbell	}
880254885Sdumbbell	if (ret == connector_status_connected)
881254885Sdumbbell		ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, false);
882254885Sdumbbell	radeon_connector_update_scratch_regs(connector, ret);
883254885Sdumbbell	return ret;
884254885Sdumbbell}
885254885Sdumbbell
886254885Sdumbbellstatic const struct drm_connector_helper_funcs radeon_tv_connector_helper_funcs = {
887254885Sdumbbell	.get_modes = radeon_tv_get_modes,
888254885Sdumbbell	.mode_valid = radeon_tv_mode_valid,
889254885Sdumbbell	.best_encoder = radeon_best_single_encoder,
890254885Sdumbbell};
891254885Sdumbbell
892254885Sdumbbellstatic const struct drm_connector_funcs radeon_tv_connector_funcs = {
893254885Sdumbbell	.dpms = drm_helper_connector_dpms,
894254885Sdumbbell	.detect = radeon_tv_detect,
895254885Sdumbbell	.fill_modes = drm_helper_probe_single_connector_modes,
896254885Sdumbbell	.destroy = radeon_connector_destroy,
897254885Sdumbbell	.set_property = radeon_connector_set_property,
898254885Sdumbbell};
899254885Sdumbbell
900254885Sdumbbellstatic int radeon_dvi_get_modes(struct drm_connector *connector)
901254885Sdumbbell{
902254885Sdumbbell	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
903254885Sdumbbell	int ret;
904254885Sdumbbell
905254885Sdumbbell	ret = radeon_ddc_get_modes(radeon_connector);
906254885Sdumbbell	return ret;
907254885Sdumbbell}
908254885Sdumbbell
909254885Sdumbbellstatic bool radeon_check_hpd_status_unchanged(struct drm_connector *connector)
910254885Sdumbbell{
911254885Sdumbbell	struct drm_device *dev = connector->dev;
912254885Sdumbbell	struct radeon_device *rdev = dev->dev_private;
913254885Sdumbbell	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
914254885Sdumbbell	enum drm_connector_status status;
915254885Sdumbbell
916254885Sdumbbell	/* We only trust HPD on R600 and newer ASICS. */
917254885Sdumbbell	if (rdev->family >= CHIP_R600
918254885Sdumbbell	  && radeon_connector->hpd.hpd != RADEON_HPD_NONE) {
919254885Sdumbbell		if (radeon_hpd_sense(rdev, radeon_connector->hpd.hpd))
920254885Sdumbbell			status = connector_status_connected;
921254885Sdumbbell		else
922254885Sdumbbell			status = connector_status_disconnected;
923254885Sdumbbell		if (connector->status == status)
924254885Sdumbbell			return true;
925254885Sdumbbell	}
926254885Sdumbbell
927254885Sdumbbell	return false;
928254885Sdumbbell}
929254885Sdumbbell
930254885Sdumbbell/*
931254885Sdumbbell * DVI is complicated
932254885Sdumbbell * Do a DDC probe, if DDC probe passes, get the full EDID so
933254885Sdumbbell * we can do analog/digital monitor detection at this point.
934254885Sdumbbell * If the monitor is an analog monitor or we got no DDC,
935254885Sdumbbell * we need to find the DAC encoder object for this connector.
936254885Sdumbbell * If we got no DDC, we do load detection on the DAC encoder object.
937254885Sdumbbell * If we got analog DDC or load detection passes on the DAC encoder
938254885Sdumbbell * we have to check if this analog encoder is shared with anyone else (TV)
939254885Sdumbbell * if its shared we have to set the other connector to disconnected.
940254885Sdumbbell */
941254885Sdumbbellstatic enum drm_connector_status
942254885Sdumbbellradeon_dvi_detect(struct drm_connector *connector, bool force)
943254885Sdumbbell{
944254885Sdumbbell	struct drm_device *dev = connector->dev;
945254885Sdumbbell	struct radeon_device *rdev = dev->dev_private;
946254885Sdumbbell	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
947254885Sdumbbell	struct drm_encoder *encoder = NULL;
948254885Sdumbbell	struct drm_encoder_helper_funcs *encoder_funcs;
949254885Sdumbbell	struct drm_mode_object *obj;
950254885Sdumbbell	int i;
951254885Sdumbbell	enum drm_connector_status ret = connector_status_disconnected;
952254885Sdumbbell	bool dret = false, broken_edid = false;
953254885Sdumbbell
954254885Sdumbbell	if (!force && radeon_check_hpd_status_unchanged(connector))
955254885Sdumbbell		return connector->status;
956254885Sdumbbell
957254885Sdumbbell	if (radeon_connector->ddc_bus)
958254885Sdumbbell		dret = radeon_ddc_probe(radeon_connector, false);
959254885Sdumbbell	if (dret) {
960254885Sdumbbell		radeon_connector->detected_by_load = false;
961254885Sdumbbell		if (radeon_connector->edid) {
962254885Sdumbbell			free(radeon_connector->edid, DRM_MEM_KMS);
963254885Sdumbbell			radeon_connector->edid = NULL;
964254885Sdumbbell		}
965254885Sdumbbell		radeon_connector->edid = drm_get_edid(&radeon_connector->base, radeon_connector->ddc_bus->adapter);
966254885Sdumbbell
967254885Sdumbbell		if (!radeon_connector->edid) {
968274862Sdumbbell			DRM_DEBUG_KMS("%s: probed a monitor but no|invalid EDID\n",
969254885Sdumbbell					drm_get_connector_name(connector));
970254885Sdumbbell			/* rs690 seems to have a problem with connectors not existing and always
971254885Sdumbbell			 * return a block of 0's. If we see this just stop polling on this output */
972254885Sdumbbell			if ((rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740) && radeon_connector->base.null_edid_counter) {
973254885Sdumbbell				ret = connector_status_disconnected;
974254885Sdumbbell				DRM_ERROR("%s: detected RS690 floating bus bug, stopping ddc detect\n", drm_get_connector_name(connector));
975254885Sdumbbell				radeon_connector->ddc_bus = NULL;
976254885Sdumbbell			} else {
977254885Sdumbbell				ret = connector_status_connected;
978254885Sdumbbell				broken_edid = true; /* defer use_digital to later */
979254885Sdumbbell			}
980254885Sdumbbell		} else {
981254885Sdumbbell			radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL);
982254885Sdumbbell
983254885Sdumbbell			/* some oems have boards with separate digital and analog connectors
984254885Sdumbbell			 * with a shared ddc line (often vga + hdmi)
985254885Sdumbbell			 */
986254885Sdumbbell			if ((!radeon_connector->use_digital) && radeon_connector->shared_ddc) {
987254885Sdumbbell				free(radeon_connector->edid, DRM_MEM_KMS);
988254885Sdumbbell				radeon_connector->edid = NULL;
989254885Sdumbbell				ret = connector_status_disconnected;
990254885Sdumbbell			} else
991254885Sdumbbell				ret = connector_status_connected;
992254885Sdumbbell
993254885Sdumbbell			/* This gets complicated.  We have boards with VGA + HDMI with a
994254885Sdumbbell			 * shared DDC line and we have boards with DVI-D + HDMI with a shared
995254885Sdumbbell			 * DDC line.  The latter is more complex because with DVI<->HDMI adapters
996254885Sdumbbell			 * you don't really know what's connected to which port as both are digital.
997254885Sdumbbell			 */
998254885Sdumbbell			if (radeon_connector->shared_ddc && (ret == connector_status_connected)) {
999254885Sdumbbell				struct drm_connector *list_connector;
1000254885Sdumbbell				struct radeon_connector *list_radeon_connector;
1001254885Sdumbbell				list_for_each_entry(list_connector, &dev->mode_config.connector_list, head) {
1002254885Sdumbbell					if (connector == list_connector)
1003254885Sdumbbell						continue;
1004254885Sdumbbell					list_radeon_connector = to_radeon_connector(list_connector);
1005254885Sdumbbell					if (list_radeon_connector->shared_ddc &&
1006254885Sdumbbell					    (list_radeon_connector->ddc_bus->rec.i2c_id ==
1007254885Sdumbbell					     radeon_connector->ddc_bus->rec.i2c_id)) {
1008254885Sdumbbell						/* cases where both connectors are digital */
1009254885Sdumbbell						if (list_connector->connector_type != DRM_MODE_CONNECTOR_VGA) {
1010254885Sdumbbell							/* hpd is our only option in this case */
1011254885Sdumbbell							if (!radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) {
1012254885Sdumbbell								free(radeon_connector->edid, DRM_MEM_KMS);
1013254885Sdumbbell								radeon_connector->edid = NULL;
1014254885Sdumbbell								ret = connector_status_disconnected;
1015254885Sdumbbell							}
1016254885Sdumbbell						}
1017254885Sdumbbell					}
1018254885Sdumbbell				}
1019254885Sdumbbell			}
1020254885Sdumbbell		}
1021254885Sdumbbell	}
1022254885Sdumbbell
1023254885Sdumbbell	if ((ret == connector_status_connected) && (radeon_connector->use_digital == true))
1024254885Sdumbbell		goto out;
1025254885Sdumbbell
1026254885Sdumbbell	/* DVI-D and HDMI-A are digital only */
1027254885Sdumbbell	if ((connector->connector_type == DRM_MODE_CONNECTOR_DVID) ||
1028254885Sdumbbell	    (connector->connector_type == DRM_MODE_CONNECTOR_HDMIA))
1029254885Sdumbbell		goto out;
1030254885Sdumbbell
1031254885Sdumbbell	/* if we aren't forcing don't do destructive polling */
1032254885Sdumbbell	if (!force) {
1033254885Sdumbbell		/* only return the previous status if we last
1034254885Sdumbbell		 * detected a monitor via load.
1035254885Sdumbbell		 */
1036254885Sdumbbell		if (radeon_connector->detected_by_load)
1037254885Sdumbbell			ret = connector->status;
1038254885Sdumbbell		goto out;
1039254885Sdumbbell	}
1040254885Sdumbbell
1041254885Sdumbbell	/* find analog encoder */
1042254885Sdumbbell	if (radeon_connector->dac_load_detect) {
1043254885Sdumbbell		for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
1044254885Sdumbbell			if (connector->encoder_ids[i] == 0)
1045254885Sdumbbell				break;
1046254885Sdumbbell
1047254885Sdumbbell			obj = drm_mode_object_find(connector->dev,
1048254885Sdumbbell						   connector->encoder_ids[i],
1049254885Sdumbbell						   DRM_MODE_OBJECT_ENCODER);
1050254885Sdumbbell			if (!obj)
1051254885Sdumbbell				continue;
1052254885Sdumbbell
1053254885Sdumbbell			encoder = obj_to_encoder(obj);
1054254885Sdumbbell
1055254885Sdumbbell			if (encoder->encoder_type != DRM_MODE_ENCODER_DAC &&
1056254885Sdumbbell			    encoder->encoder_type != DRM_MODE_ENCODER_TVDAC)
1057254885Sdumbbell				continue;
1058254885Sdumbbell
1059254885Sdumbbell			encoder_funcs = encoder->helper_private;
1060254885Sdumbbell			if (encoder_funcs->detect) {
1061254885Sdumbbell				if (!broken_edid) {
1062254885Sdumbbell					if (ret != connector_status_connected) {
1063254885Sdumbbell						/* deal with analog monitors without DDC */
1064254885Sdumbbell						ret = encoder_funcs->detect(encoder, connector);
1065254885Sdumbbell						if (ret == connector_status_connected) {
1066254885Sdumbbell							radeon_connector->use_digital = false;
1067254885Sdumbbell						}
1068254885Sdumbbell						if (ret != connector_status_disconnected)
1069254885Sdumbbell							radeon_connector->detected_by_load = true;
1070254885Sdumbbell					}
1071254885Sdumbbell				} else {
1072254885Sdumbbell					enum drm_connector_status lret;
1073254885Sdumbbell					/* assume digital unless load detected otherwise */
1074254885Sdumbbell					radeon_connector->use_digital = true;
1075254885Sdumbbell					lret = encoder_funcs->detect(encoder, connector);
1076254885Sdumbbell					DRM_DEBUG_KMS("load_detect %x returned: %x\n",encoder->encoder_type,lret);
1077254885Sdumbbell					if (lret == connector_status_connected)
1078254885Sdumbbell						radeon_connector->use_digital = false;
1079254885Sdumbbell				}
1080254885Sdumbbell				break;
1081254885Sdumbbell			}
1082254885Sdumbbell		}
1083254885Sdumbbell	}
1084254885Sdumbbell
1085254885Sdumbbell	if ((ret == connector_status_connected) && (radeon_connector->use_digital == false) &&
1086254885Sdumbbell	    encoder) {
1087254885Sdumbbell		ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, true);
1088254885Sdumbbell	}
1089254885Sdumbbell
1090254885Sdumbbell	/* RN50 and some RV100 asics in servers often have a hardcoded EDID in the
1091254885Sdumbbell	 * vbios to deal with KVMs. If we have one and are not able to detect a monitor
1092254885Sdumbbell	 * by other means, assume the DFP is connected and use that EDID.  In most
1093254885Sdumbbell	 * cases the DVI port is actually a virtual KVM port connected to the service
1094254885Sdumbbell	 * processor.
1095254885Sdumbbell	 */
1096254885Sdumbbellout:
1097254885Sdumbbell	if ((!rdev->is_atom_bios) &&
1098254885Sdumbbell	    (ret == connector_status_disconnected) &&
1099254885Sdumbbell	    rdev->mode_info.bios_hardcoded_edid_size) {
1100254885Sdumbbell		radeon_connector->use_digital = true;
1101254885Sdumbbell		ret = connector_status_connected;
1102254885Sdumbbell	}
1103254885Sdumbbell
1104254885Sdumbbell	/* updated in get modes as well since we need to know if it's analog or digital */
1105254885Sdumbbell	radeon_connector_update_scratch_regs(connector, ret);
1106254885Sdumbbell	return ret;
1107254885Sdumbbell}
1108254885Sdumbbell
1109254885Sdumbbell/* okay need to be smart in here about which encoder to pick */
1110254885Sdumbbellstatic struct drm_encoder *radeon_dvi_encoder(struct drm_connector *connector)
1111254885Sdumbbell{
1112254885Sdumbbell	int enc_id = connector->encoder_ids[0];
1113254885Sdumbbell	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
1114254885Sdumbbell	struct drm_mode_object *obj;
1115254885Sdumbbell	struct drm_encoder *encoder;
1116254885Sdumbbell	int i;
1117254885Sdumbbell	for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
1118254885Sdumbbell		if (connector->encoder_ids[i] == 0)
1119254885Sdumbbell			break;
1120254885Sdumbbell
1121254885Sdumbbell		obj = drm_mode_object_find(connector->dev, connector->encoder_ids[i], DRM_MODE_OBJECT_ENCODER);
1122254885Sdumbbell		if (!obj)
1123254885Sdumbbell			continue;
1124254885Sdumbbell
1125254885Sdumbbell		encoder = obj_to_encoder(obj);
1126254885Sdumbbell
1127254885Sdumbbell		if (radeon_connector->use_digital == true) {
1128254885Sdumbbell			if (encoder->encoder_type == DRM_MODE_ENCODER_TMDS)
1129254885Sdumbbell				return encoder;
1130254885Sdumbbell		} else {
1131254885Sdumbbell			if (encoder->encoder_type == DRM_MODE_ENCODER_DAC ||
1132254885Sdumbbell			    encoder->encoder_type == DRM_MODE_ENCODER_TVDAC)
1133254885Sdumbbell				return encoder;
1134254885Sdumbbell		}
1135254885Sdumbbell	}
1136254885Sdumbbell
1137254885Sdumbbell	/* see if we have a default encoder  TODO */
1138254885Sdumbbell
1139254885Sdumbbell	/* then check use digitial */
1140254885Sdumbbell	/* pick the first one */
1141254885Sdumbbell	if (enc_id) {
1142254885Sdumbbell		obj = drm_mode_object_find(connector->dev, enc_id, DRM_MODE_OBJECT_ENCODER);
1143254885Sdumbbell		if (!obj)
1144254885Sdumbbell			return NULL;
1145254885Sdumbbell		encoder = obj_to_encoder(obj);
1146254885Sdumbbell		return encoder;
1147254885Sdumbbell	}
1148254885Sdumbbell	return NULL;
1149254885Sdumbbell}
1150254885Sdumbbell
1151254885Sdumbbellstatic void radeon_dvi_force(struct drm_connector *connector)
1152254885Sdumbbell{
1153254885Sdumbbell	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
1154254885Sdumbbell	if (connector->force == DRM_FORCE_ON)
1155254885Sdumbbell		radeon_connector->use_digital = false;
1156254885Sdumbbell	if (connector->force == DRM_FORCE_ON_DIGITAL)
1157254885Sdumbbell		radeon_connector->use_digital = true;
1158254885Sdumbbell}
1159254885Sdumbbell
1160254885Sdumbbellstatic int radeon_dvi_mode_valid(struct drm_connector *connector,
1161254885Sdumbbell				  struct drm_display_mode *mode)
1162254885Sdumbbell{
1163254885Sdumbbell	struct drm_device *dev = connector->dev;
1164254885Sdumbbell	struct radeon_device *rdev = dev->dev_private;
1165254885Sdumbbell	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
1166254885Sdumbbell
1167254885Sdumbbell	/* XXX check mode bandwidth */
1168254885Sdumbbell
1169254885Sdumbbell	/* clocks over 135 MHz have heat issues with DVI on RV100 */
1170254885Sdumbbell	if (radeon_connector->use_digital &&
1171254885Sdumbbell	    (rdev->family == CHIP_RV100) &&
1172254885Sdumbbell	    (mode->clock > 135000))
1173254885Sdumbbell		return MODE_CLOCK_HIGH;
1174254885Sdumbbell
1175254885Sdumbbell	if (radeon_connector->use_digital && (mode->clock > 165000)) {
1176254885Sdumbbell		if ((radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I) ||
1177254885Sdumbbell		    (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D) ||
1178254885Sdumbbell		    (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_HDMI_TYPE_B))
1179254885Sdumbbell			return MODE_OK;
1180254885Sdumbbell		else if (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_HDMI_TYPE_A) {
1181254885Sdumbbell			if (ASIC_IS_DCE6(rdev)) {
1182254885Sdumbbell				/* HDMI 1.3+ supports max clock of 340 Mhz */
1183254885Sdumbbell				if (mode->clock > 340000)
1184254885Sdumbbell					return MODE_CLOCK_HIGH;
1185254885Sdumbbell				else
1186254885Sdumbbell					return MODE_OK;
1187254885Sdumbbell			} else
1188254885Sdumbbell				return MODE_CLOCK_HIGH;
1189254885Sdumbbell		} else
1190254885Sdumbbell			return MODE_CLOCK_HIGH;
1191254885Sdumbbell	}
1192254885Sdumbbell
1193254885Sdumbbell	/* check against the max pixel clock */
1194254885Sdumbbell	if ((mode->clock / 10) > rdev->clock.max_pixel_clock)
1195254885Sdumbbell		return MODE_CLOCK_HIGH;
1196254885Sdumbbell
1197254885Sdumbbell	return MODE_OK;
1198254885Sdumbbell}
1199254885Sdumbbell
1200254885Sdumbbellstatic const struct drm_connector_helper_funcs radeon_dvi_connector_helper_funcs = {
1201254885Sdumbbell	.get_modes = radeon_dvi_get_modes,
1202254885Sdumbbell	.mode_valid = radeon_dvi_mode_valid,
1203254885Sdumbbell	.best_encoder = radeon_dvi_encoder,
1204254885Sdumbbell};
1205254885Sdumbbell
1206254885Sdumbbellstatic const struct drm_connector_funcs radeon_dvi_connector_funcs = {
1207254885Sdumbbell	.dpms = drm_helper_connector_dpms,
1208254885Sdumbbell	.detect = radeon_dvi_detect,
1209254885Sdumbbell	.fill_modes = drm_helper_probe_single_connector_modes,
1210254885Sdumbbell	.set_property = radeon_connector_set_property,
1211254885Sdumbbell	.destroy = radeon_connector_destroy,
1212254885Sdumbbell	.force = radeon_dvi_force,
1213254885Sdumbbell};
1214254885Sdumbbell
1215254885Sdumbbellstatic void radeon_dp_connector_destroy(struct drm_connector *connector)
1216254885Sdumbbell{
1217254885Sdumbbell	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
1218254885Sdumbbell	struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv;
1219254885Sdumbbell
1220254885Sdumbbell	if (radeon_connector->edid)
1221254885Sdumbbell		free(radeon_connector->edid, DRM_MEM_KMS);
1222254885Sdumbbell	if (radeon_dig_connector->dp_i2c_bus)
1223254885Sdumbbell		radeon_i2c_destroy(radeon_dig_connector->dp_i2c_bus);
1224254885Sdumbbell	free(radeon_connector->con_priv, DRM_MEM_DRIVER);
1225282199Sdumbbell#ifdef FREEBSD_WIP
1226254885Sdumbbell	drm_sysfs_connector_remove(connector);
1227282199Sdumbbell#endif /* FREEBSD_WIP */
1228254885Sdumbbell	drm_connector_cleanup(connector);
1229254885Sdumbbell	free(connector, DRM_MEM_DRIVER);
1230254885Sdumbbell}
1231254885Sdumbbell
1232254885Sdumbbellstatic int radeon_dp_get_modes(struct drm_connector *connector)
1233254885Sdumbbell{
1234254885Sdumbbell	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
1235254885Sdumbbell	struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv;
1236254885Sdumbbell	struct drm_encoder *encoder = radeon_best_single_encoder(connector);
1237254885Sdumbbell	int ret;
1238254885Sdumbbell
1239254885Sdumbbell	if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) ||
1240254885Sdumbbell	    (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) {
1241254885Sdumbbell		struct drm_display_mode *mode;
1242254885Sdumbbell
1243254885Sdumbbell		if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
1244254885Sdumbbell			if (!radeon_dig_connector->edp_on)
1245254885Sdumbbell				atombios_set_edp_panel_power(connector,
1246254885Sdumbbell							     ATOM_TRANSMITTER_ACTION_POWER_ON);
1247254885Sdumbbell			ret = radeon_ddc_get_modes(radeon_connector);
1248254885Sdumbbell			if (!radeon_dig_connector->edp_on)
1249254885Sdumbbell				atombios_set_edp_panel_power(connector,
1250254885Sdumbbell							     ATOM_TRANSMITTER_ACTION_POWER_OFF);
1251254885Sdumbbell		} else {
1252254885Sdumbbell			/* need to setup ddc on the bridge */
1253254885Sdumbbell			if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) !=
1254254885Sdumbbell			    ENCODER_OBJECT_ID_NONE) {
1255254885Sdumbbell				if (encoder)
1256254885Sdumbbell					radeon_atom_ext_encoder_setup_ddc(encoder);
1257254885Sdumbbell			}
1258254885Sdumbbell			ret = radeon_ddc_get_modes(radeon_connector);
1259254885Sdumbbell		}
1260254885Sdumbbell
1261254885Sdumbbell		if (ret > 0) {
1262254885Sdumbbell			if (encoder) {
1263254885Sdumbbell				radeon_fixup_lvds_native_mode(encoder, connector);
1264254885Sdumbbell				/* add scaled modes */
1265254885Sdumbbell				radeon_add_common_modes(encoder, connector);
1266254885Sdumbbell			}
1267254885Sdumbbell			return ret;
1268254885Sdumbbell		}
1269254885Sdumbbell
1270254885Sdumbbell		if (!encoder)
1271254885Sdumbbell			return 0;
1272254885Sdumbbell
1273254885Sdumbbell		/* we have no EDID modes */
1274254885Sdumbbell		mode = radeon_fp_native_mode(encoder);
1275254885Sdumbbell		if (mode) {
1276254885Sdumbbell			ret = 1;
1277254885Sdumbbell			drm_mode_probed_add(connector, mode);
1278254885Sdumbbell			/* add the width/height from vbios tables if available */
1279254885Sdumbbell			connector->display_info.width_mm = mode->width_mm;
1280254885Sdumbbell			connector->display_info.height_mm = mode->height_mm;
1281254885Sdumbbell			/* add scaled modes */
1282254885Sdumbbell			radeon_add_common_modes(encoder, connector);
1283254885Sdumbbell		}
1284254885Sdumbbell	} else {
1285254885Sdumbbell		/* need to setup ddc on the bridge */
1286254885Sdumbbell		if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) !=
1287254885Sdumbbell			ENCODER_OBJECT_ID_NONE) {
1288254885Sdumbbell			if (encoder)
1289254885Sdumbbell				radeon_atom_ext_encoder_setup_ddc(encoder);
1290254885Sdumbbell		}
1291254885Sdumbbell		ret = radeon_ddc_get_modes(radeon_connector);
1292254885Sdumbbell	}
1293254885Sdumbbell
1294254885Sdumbbell	return ret;
1295254885Sdumbbell}
1296254885Sdumbbell
1297254885Sdumbbellu16 radeon_connector_encoder_get_dp_bridge_encoder_id(struct drm_connector *connector)
1298254885Sdumbbell{
1299254885Sdumbbell	struct drm_mode_object *obj;
1300254885Sdumbbell	struct drm_encoder *encoder;
1301254885Sdumbbell	struct radeon_encoder *radeon_encoder;
1302254885Sdumbbell	int i;
1303254885Sdumbbell
1304254885Sdumbbell	for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
1305254885Sdumbbell		if (connector->encoder_ids[i] == 0)
1306254885Sdumbbell			break;
1307254885Sdumbbell
1308254885Sdumbbell		obj = drm_mode_object_find(connector->dev, connector->encoder_ids[i], DRM_MODE_OBJECT_ENCODER);
1309254885Sdumbbell		if (!obj)
1310254885Sdumbbell			continue;
1311254885Sdumbbell
1312254885Sdumbbell		encoder = obj_to_encoder(obj);
1313254885Sdumbbell		radeon_encoder = to_radeon_encoder(encoder);
1314254885Sdumbbell
1315254885Sdumbbell		switch (radeon_encoder->encoder_id) {
1316254885Sdumbbell		case ENCODER_OBJECT_ID_TRAVIS:
1317254885Sdumbbell		case ENCODER_OBJECT_ID_NUTMEG:
1318254885Sdumbbell			return radeon_encoder->encoder_id;
1319254885Sdumbbell		default:
1320254885Sdumbbell			break;
1321254885Sdumbbell		}
1322254885Sdumbbell	}
1323254885Sdumbbell
1324254885Sdumbbell	return ENCODER_OBJECT_ID_NONE;
1325254885Sdumbbell}
1326254885Sdumbbell
1327254885Sdumbbellbool radeon_connector_encoder_is_hbr2(struct drm_connector *connector)
1328254885Sdumbbell{
1329254885Sdumbbell	struct drm_mode_object *obj;
1330254885Sdumbbell	struct drm_encoder *encoder;
1331254885Sdumbbell	struct radeon_encoder *radeon_encoder;
1332254885Sdumbbell	int i;
1333254885Sdumbbell	bool found = false;
1334254885Sdumbbell
1335254885Sdumbbell	for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
1336254885Sdumbbell		if (connector->encoder_ids[i] == 0)
1337254885Sdumbbell			break;
1338254885Sdumbbell
1339254885Sdumbbell		obj = drm_mode_object_find(connector->dev, connector->encoder_ids[i], DRM_MODE_OBJECT_ENCODER);
1340254885Sdumbbell		if (!obj)
1341254885Sdumbbell			continue;
1342254885Sdumbbell
1343254885Sdumbbell		encoder = obj_to_encoder(obj);
1344254885Sdumbbell		radeon_encoder = to_radeon_encoder(encoder);
1345254885Sdumbbell		if (radeon_encoder->caps & ATOM_ENCODER_CAP_RECORD_HBR2)
1346254885Sdumbbell			found = true;
1347254885Sdumbbell	}
1348254885Sdumbbell
1349254885Sdumbbell	return found;
1350254885Sdumbbell}
1351254885Sdumbbell
1352254885Sdumbbellbool radeon_connector_is_dp12_capable(struct drm_connector *connector)
1353254885Sdumbbell{
1354254885Sdumbbell	struct drm_device *dev = connector->dev;
1355254885Sdumbbell	struct radeon_device *rdev = dev->dev_private;
1356254885Sdumbbell
1357254885Sdumbbell	if (ASIC_IS_DCE5(rdev) &&
1358254885Sdumbbell	    (rdev->clock.dp_extclk >= 53900) &&
1359254885Sdumbbell	    radeon_connector_encoder_is_hbr2(connector)) {
1360254885Sdumbbell		return true;
1361254885Sdumbbell	}
1362254885Sdumbbell
1363254885Sdumbbell	return false;
1364254885Sdumbbell}
1365254885Sdumbbell
1366254885Sdumbbellstatic enum drm_connector_status
1367254885Sdumbbellradeon_dp_detect(struct drm_connector *connector, bool force)
1368254885Sdumbbell{
1369254885Sdumbbell	struct drm_device *dev = connector->dev;
1370254885Sdumbbell	struct radeon_device *rdev = dev->dev_private;
1371254885Sdumbbell	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
1372254885Sdumbbell	enum drm_connector_status ret = connector_status_disconnected;
1373254885Sdumbbell	struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv;
1374254885Sdumbbell	struct drm_encoder *encoder = radeon_best_single_encoder(connector);
1375254885Sdumbbell
1376254885Sdumbbell	if (!force && radeon_check_hpd_status_unchanged(connector))
1377254885Sdumbbell		return connector->status;
1378254885Sdumbbell
1379254885Sdumbbell	if (radeon_connector->edid) {
1380254885Sdumbbell		free(radeon_connector->edid, DRM_MEM_KMS);
1381254885Sdumbbell		radeon_connector->edid = NULL;
1382254885Sdumbbell	}
1383254885Sdumbbell
1384254885Sdumbbell	if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) ||
1385254885Sdumbbell	    (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) {
1386254885Sdumbbell		if (encoder) {
1387254885Sdumbbell			struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
1388254885Sdumbbell			struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
1389254885Sdumbbell
1390254885Sdumbbell			/* check if panel is valid */
1391254885Sdumbbell			if (native_mode->hdisplay >= 320 && native_mode->vdisplay >= 240)
1392254885Sdumbbell				ret = connector_status_connected;
1393254885Sdumbbell		}
1394254885Sdumbbell		/* eDP is always DP */
1395254885Sdumbbell		radeon_dig_connector->dp_sink_type = CONNECTOR_OBJECT_ID_DISPLAYPORT;
1396254885Sdumbbell		if (!radeon_dig_connector->edp_on)
1397254885Sdumbbell			atombios_set_edp_panel_power(connector,
1398254885Sdumbbell						     ATOM_TRANSMITTER_ACTION_POWER_ON);
1399254885Sdumbbell		if (radeon_dp_getdpcd(radeon_connector))
1400254885Sdumbbell			ret = connector_status_connected;
1401254885Sdumbbell		if (!radeon_dig_connector->edp_on)
1402254885Sdumbbell			atombios_set_edp_panel_power(connector,
1403254885Sdumbbell						     ATOM_TRANSMITTER_ACTION_POWER_OFF);
1404254885Sdumbbell	} else if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) !=
1405254885Sdumbbell		   ENCODER_OBJECT_ID_NONE) {
1406254885Sdumbbell		/* DP bridges are always DP */
1407254885Sdumbbell		radeon_dig_connector->dp_sink_type = CONNECTOR_OBJECT_ID_DISPLAYPORT;
1408254885Sdumbbell		/* get the DPCD from the bridge */
1409254885Sdumbbell		radeon_dp_getdpcd(radeon_connector);
1410254885Sdumbbell
1411254885Sdumbbell		if (encoder) {
1412254885Sdumbbell			/* setup ddc on the bridge */
1413254885Sdumbbell			radeon_atom_ext_encoder_setup_ddc(encoder);
1414254885Sdumbbell			/* bridge chips are always aux */
1415254885Sdumbbell			if (radeon_ddc_probe(radeon_connector, true)) /* try DDC */
1416254885Sdumbbell				ret = connector_status_connected;
1417254885Sdumbbell			else if (radeon_connector->dac_load_detect) { /* try load detection */
1418254885Sdumbbell				struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
1419254885Sdumbbell				ret = encoder_funcs->detect(encoder, connector);
1420254885Sdumbbell			}
1421254885Sdumbbell		}
1422254885Sdumbbell	} else {
1423254885Sdumbbell		radeon_dig_connector->dp_sink_type = radeon_dp_getsinktype(radeon_connector);
1424254885Sdumbbell		if (radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) {
1425254885Sdumbbell			ret = connector_status_connected;
1426254885Sdumbbell			if (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT)
1427254885Sdumbbell				radeon_dp_getdpcd(radeon_connector);
1428254885Sdumbbell		} else {
1429254885Sdumbbell			if (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) {
1430254885Sdumbbell				if (radeon_dp_getdpcd(radeon_connector))
1431254885Sdumbbell					ret = connector_status_connected;
1432254885Sdumbbell			} else {
1433254885Sdumbbell				/* try non-aux ddc (DP to DVI/HMDI/etc. adapter) */
1434254885Sdumbbell				if (radeon_ddc_probe(radeon_connector, false))
1435254885Sdumbbell					ret = connector_status_connected;
1436254885Sdumbbell			}
1437254885Sdumbbell		}
1438254885Sdumbbell	}
1439254885Sdumbbell
1440254885Sdumbbell	radeon_connector_update_scratch_regs(connector, ret);
1441254885Sdumbbell	return ret;
1442254885Sdumbbell}
1443254885Sdumbbell
1444254885Sdumbbellstatic int radeon_dp_mode_valid(struct drm_connector *connector,
1445254885Sdumbbell				  struct drm_display_mode *mode)
1446254885Sdumbbell{
1447254885Sdumbbell	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
1448254885Sdumbbell	struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv;
1449254885Sdumbbell
1450254885Sdumbbell	/* XXX check mode bandwidth */
1451254885Sdumbbell
1452254885Sdumbbell	if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) ||
1453254885Sdumbbell	    (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) {
1454254885Sdumbbell		struct drm_encoder *encoder = radeon_best_single_encoder(connector);
1455254885Sdumbbell
1456254885Sdumbbell		if ((mode->hdisplay < 320) || (mode->vdisplay < 240))
1457254885Sdumbbell			return MODE_PANEL;
1458254885Sdumbbell
1459254885Sdumbbell		if (encoder) {
1460254885Sdumbbell			struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
1461254885Sdumbbell			struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
1462254885Sdumbbell
1463254885Sdumbbell			/* AVIVO hardware supports downscaling modes larger than the panel
1464254885Sdumbbell			 * to the panel size, but I'm not sure this is desirable.
1465254885Sdumbbell			 */
1466254885Sdumbbell			if ((mode->hdisplay > native_mode->hdisplay) ||
1467254885Sdumbbell			    (mode->vdisplay > native_mode->vdisplay))
1468254885Sdumbbell				return MODE_PANEL;
1469254885Sdumbbell
1470254885Sdumbbell			/* if scaling is disabled, block non-native modes */
1471254885Sdumbbell			if (radeon_encoder->rmx_type == RMX_OFF) {
1472254885Sdumbbell				if ((mode->hdisplay != native_mode->hdisplay) ||
1473254885Sdumbbell				    (mode->vdisplay != native_mode->vdisplay))
1474254885Sdumbbell					return MODE_PANEL;
1475254885Sdumbbell			}
1476254885Sdumbbell		}
1477254885Sdumbbell		return MODE_OK;
1478254885Sdumbbell	} else {
1479254885Sdumbbell		if ((radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
1480254885Sdumbbell		    (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP))
1481254885Sdumbbell			return radeon_dp_mode_valid_helper(connector, mode);
1482254885Sdumbbell		else
1483254885Sdumbbell			return MODE_OK;
1484254885Sdumbbell	}
1485254885Sdumbbell}
1486254885Sdumbbell
1487254885Sdumbbellstatic const struct drm_connector_helper_funcs radeon_dp_connector_helper_funcs = {
1488254885Sdumbbell	.get_modes = radeon_dp_get_modes,
1489254885Sdumbbell	.mode_valid = radeon_dp_mode_valid,
1490254885Sdumbbell	.best_encoder = radeon_dvi_encoder,
1491254885Sdumbbell};
1492254885Sdumbbell
1493254885Sdumbbellstatic const struct drm_connector_funcs radeon_dp_connector_funcs = {
1494254885Sdumbbell	.dpms = drm_helper_connector_dpms,
1495254885Sdumbbell	.detect = radeon_dp_detect,
1496254885Sdumbbell	.fill_modes = drm_helper_probe_single_connector_modes,
1497254885Sdumbbell	.set_property = radeon_connector_set_property,
1498254885Sdumbbell	.destroy = radeon_dp_connector_destroy,
1499254885Sdumbbell	.force = radeon_dvi_force,
1500254885Sdumbbell};
1501254885Sdumbbell
1502254885Sdumbbellvoid
1503254885Sdumbbellradeon_add_atom_connector(struct drm_device *dev,
1504254885Sdumbbell			  uint32_t connector_id,
1505254885Sdumbbell			  uint32_t supported_device,
1506254885Sdumbbell			  int connector_type,
1507254885Sdumbbell			  struct radeon_i2c_bus_rec *i2c_bus,
1508254885Sdumbbell			  uint32_t igp_lane_info,
1509254885Sdumbbell			  uint16_t connector_object_id,
1510254885Sdumbbell			  struct radeon_hpd *hpd,
1511254885Sdumbbell			  struct radeon_router *router)
1512254885Sdumbbell{
1513254885Sdumbbell	struct radeon_device *rdev = dev->dev_private;
1514254885Sdumbbell	struct drm_connector *connector;
1515254885Sdumbbell	struct radeon_connector *radeon_connector;
1516254885Sdumbbell	struct radeon_connector_atom_dig *radeon_dig_connector;
1517254885Sdumbbell	struct drm_encoder *encoder;
1518254885Sdumbbell	struct radeon_encoder *radeon_encoder;
1519254885Sdumbbell	uint32_t subpixel_order = SubPixelNone;
1520254885Sdumbbell	bool shared_ddc = false;
1521254885Sdumbbell	bool is_dp_bridge = false;
1522254885Sdumbbell
1523254885Sdumbbell	if (connector_type == DRM_MODE_CONNECTOR_Unknown)
1524254885Sdumbbell		return;
1525254885Sdumbbell
1526254885Sdumbbell	/* if the user selected tv=0 don't try and add the connector */
1527254885Sdumbbell	if (((connector_type == DRM_MODE_CONNECTOR_SVIDEO) ||
1528254885Sdumbbell	     (connector_type == DRM_MODE_CONNECTOR_Composite) ||
1529254885Sdumbbell	     (connector_type == DRM_MODE_CONNECTOR_9PinDIN)) &&
1530254885Sdumbbell	    (radeon_tv == 0))
1531254885Sdumbbell		return;
1532254885Sdumbbell
1533254885Sdumbbell	/* see if we already added it */
1534254885Sdumbbell	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
1535254885Sdumbbell		radeon_connector = to_radeon_connector(connector);
1536254885Sdumbbell		if (radeon_connector->connector_id == connector_id) {
1537254885Sdumbbell			radeon_connector->devices |= supported_device;
1538254885Sdumbbell			return;
1539254885Sdumbbell		}
1540254885Sdumbbell		if (radeon_connector->ddc_bus && i2c_bus->valid) {
1541254885Sdumbbell			if (radeon_connector->ddc_bus->rec.i2c_id == i2c_bus->i2c_id) {
1542254885Sdumbbell				radeon_connector->shared_ddc = true;
1543254885Sdumbbell				shared_ddc = true;
1544254885Sdumbbell			}
1545254885Sdumbbell			if (radeon_connector->router_bus && router->ddc_valid &&
1546254885Sdumbbell			    (radeon_connector->router.router_id == router->router_id)) {
1547254885Sdumbbell				radeon_connector->shared_ddc = false;
1548254885Sdumbbell				shared_ddc = false;
1549254885Sdumbbell			}
1550254885Sdumbbell		}
1551254885Sdumbbell	}
1552254885Sdumbbell
1553254885Sdumbbell	/* check if it's a dp bridge */
1554254885Sdumbbell	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
1555254885Sdumbbell		radeon_encoder = to_radeon_encoder(encoder);
1556254885Sdumbbell		if (radeon_encoder->devices & supported_device) {
1557254885Sdumbbell			switch (radeon_encoder->encoder_id) {
1558254885Sdumbbell			case ENCODER_OBJECT_ID_TRAVIS:
1559254885Sdumbbell			case ENCODER_OBJECT_ID_NUTMEG:
1560254885Sdumbbell				is_dp_bridge = true;
1561254885Sdumbbell				break;
1562254885Sdumbbell			default:
1563254885Sdumbbell				break;
1564254885Sdumbbell			}
1565254885Sdumbbell		}
1566254885Sdumbbell	}
1567254885Sdumbbell
1568254885Sdumbbell	radeon_connector = malloc(sizeof(struct radeon_connector),
1569282199Sdumbbell	    DRM_MEM_DRIVER, M_NOWAIT | M_ZERO);
1570254885Sdumbbell	if (!radeon_connector)
1571254885Sdumbbell		return;
1572254885Sdumbbell
1573254885Sdumbbell	connector = &radeon_connector->base;
1574254885Sdumbbell
1575254885Sdumbbell	radeon_connector->connector_id = connector_id;
1576254885Sdumbbell	radeon_connector->devices = supported_device;
1577254885Sdumbbell	radeon_connector->shared_ddc = shared_ddc;
1578254885Sdumbbell	radeon_connector->connector_object_id = connector_object_id;
1579254885Sdumbbell	radeon_connector->hpd = *hpd;
1580254885Sdumbbell
1581254885Sdumbbell	radeon_connector->router = *router;
1582254885Sdumbbell	if (router->ddc_valid || router->cd_valid) {
1583254885Sdumbbell		radeon_connector->router_bus = radeon_i2c_lookup(rdev, &router->i2c_info);
1584254885Sdumbbell		if (!radeon_connector->router_bus)
1585254885Sdumbbell			DRM_ERROR("Failed to assign router i2c bus! Check dmesg for i2c errors.\n");
1586254885Sdumbbell	}
1587254885Sdumbbell
1588254885Sdumbbell	if (is_dp_bridge) {
1589254885Sdumbbell		radeon_dig_connector = malloc(
1590254885Sdumbbell		    sizeof(struct radeon_connector_atom_dig),
1591282199Sdumbbell		    DRM_MEM_DRIVER, M_NOWAIT | M_ZERO);
1592254885Sdumbbell		if (!radeon_dig_connector)
1593254885Sdumbbell			goto failed;
1594254885Sdumbbell		radeon_dig_connector->igp_lane_info = igp_lane_info;
1595254885Sdumbbell		radeon_connector->con_priv = radeon_dig_connector;
1596254885Sdumbbell		drm_connector_init(dev, &radeon_connector->base, &radeon_dp_connector_funcs, connector_type);
1597254885Sdumbbell		drm_connector_helper_add(&radeon_connector->base, &radeon_dp_connector_helper_funcs);
1598254885Sdumbbell		if (i2c_bus->valid) {
1599254885Sdumbbell			/* add DP i2c bus */
1600254885Sdumbbell			if (connector_type == DRM_MODE_CONNECTOR_eDP)
1601254885Sdumbbell				radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "eDP-auxch");
1602254885Sdumbbell			else
1603254885Sdumbbell				radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "DP-auxch");
1604254885Sdumbbell			if (!radeon_dig_connector->dp_i2c_bus)
1605254885Sdumbbell				DRM_ERROR("DP: Failed to assign dp ddc bus! Check dmesg for i2c errors.\n");
1606254885Sdumbbell			radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus);
1607254885Sdumbbell			if (!radeon_connector->ddc_bus)
1608254885Sdumbbell				DRM_ERROR("DP: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
1609254885Sdumbbell		}
1610254885Sdumbbell		switch (connector_type) {
1611254885Sdumbbell		case DRM_MODE_CONNECTOR_VGA:
1612254885Sdumbbell		case DRM_MODE_CONNECTOR_DVIA:
1613254885Sdumbbell		default:
1614254885Sdumbbell			connector->interlace_allowed = true;
1615254885Sdumbbell			connector->doublescan_allowed = true;
1616254885Sdumbbell			radeon_connector->dac_load_detect = true;
1617282199Sdumbbell			drm_object_attach_property(&radeon_connector->base.base,
1618254885Sdumbbell						      rdev->mode_info.load_detect_property,
1619254885Sdumbbell						      1);
1620254885Sdumbbell			break;
1621254885Sdumbbell		case DRM_MODE_CONNECTOR_DVII:
1622254885Sdumbbell		case DRM_MODE_CONNECTOR_DVID:
1623254885Sdumbbell		case DRM_MODE_CONNECTOR_HDMIA:
1624254885Sdumbbell		case DRM_MODE_CONNECTOR_HDMIB:
1625254885Sdumbbell		case DRM_MODE_CONNECTOR_DisplayPort:
1626282199Sdumbbell			drm_object_attach_property(&radeon_connector->base.base,
1627254885Sdumbbell						      rdev->mode_info.underscan_property,
1628254885Sdumbbell						      UNDERSCAN_OFF);
1629282199Sdumbbell			drm_object_attach_property(&radeon_connector->base.base,
1630254885Sdumbbell						      rdev->mode_info.underscan_hborder_property,
1631254885Sdumbbell						      0);
1632282199Sdumbbell			drm_object_attach_property(&radeon_connector->base.base,
1633254885Sdumbbell						      rdev->mode_info.underscan_vborder_property,
1634254885Sdumbbell						      0);
1635254885Sdumbbell			subpixel_order = SubPixelHorizontalRGB;
1636254885Sdumbbell			connector->interlace_allowed = true;
1637254885Sdumbbell			if (connector_type == DRM_MODE_CONNECTOR_HDMIB)
1638254885Sdumbbell				connector->doublescan_allowed = true;
1639254885Sdumbbell			else
1640254885Sdumbbell				connector->doublescan_allowed = false;
1641254885Sdumbbell			if (connector_type == DRM_MODE_CONNECTOR_DVII) {
1642254885Sdumbbell				radeon_connector->dac_load_detect = true;
1643282199Sdumbbell				drm_object_attach_property(&radeon_connector->base.base,
1644254885Sdumbbell							      rdev->mode_info.load_detect_property,
1645254885Sdumbbell							      1);
1646254885Sdumbbell			}
1647254885Sdumbbell			break;
1648254885Sdumbbell		case DRM_MODE_CONNECTOR_LVDS:
1649254885Sdumbbell		case DRM_MODE_CONNECTOR_eDP:
1650282199Sdumbbell			drm_object_attach_property(&radeon_connector->base.base,
1651254885Sdumbbell						      dev->mode_config.scaling_mode_property,
1652254885Sdumbbell						      DRM_MODE_SCALE_FULLSCREEN);
1653254885Sdumbbell			subpixel_order = SubPixelHorizontalRGB;
1654254885Sdumbbell			connector->interlace_allowed = false;
1655254885Sdumbbell			connector->doublescan_allowed = false;
1656254885Sdumbbell			break;
1657254885Sdumbbell		}
1658254885Sdumbbell	} else {
1659254885Sdumbbell		switch (connector_type) {
1660254885Sdumbbell		case DRM_MODE_CONNECTOR_VGA:
1661254885Sdumbbell			drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
1662254885Sdumbbell			drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs);
1663254885Sdumbbell			if (i2c_bus->valid) {
1664254885Sdumbbell				radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus);
1665254885Sdumbbell				if (!radeon_connector->ddc_bus)
1666254885Sdumbbell					DRM_ERROR("VGA: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
1667254885Sdumbbell			}
1668254885Sdumbbell			radeon_connector->dac_load_detect = true;
1669282199Sdumbbell			drm_object_attach_property(&radeon_connector->base.base,
1670254885Sdumbbell						      rdev->mode_info.load_detect_property,
1671254885Sdumbbell						      1);
1672254885Sdumbbell			/* no HPD on analog connectors */
1673254885Sdumbbell			radeon_connector->hpd.hpd = RADEON_HPD_NONE;
1674254885Sdumbbell			connector->polled = DRM_CONNECTOR_POLL_CONNECT;
1675254885Sdumbbell			connector->interlace_allowed = true;
1676254885Sdumbbell			connector->doublescan_allowed = true;
1677254885Sdumbbell			break;
1678254885Sdumbbell		case DRM_MODE_CONNECTOR_DVIA:
1679254885Sdumbbell			drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
1680254885Sdumbbell			drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs);
1681254885Sdumbbell			if (i2c_bus->valid) {
1682254885Sdumbbell				radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus);
1683254885Sdumbbell				if (!radeon_connector->ddc_bus)
1684254885Sdumbbell					DRM_ERROR("DVIA: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
1685254885Sdumbbell			}
1686254885Sdumbbell			radeon_connector->dac_load_detect = true;
1687282199Sdumbbell			drm_object_attach_property(&radeon_connector->base.base,
1688254885Sdumbbell						      rdev->mode_info.load_detect_property,
1689254885Sdumbbell						      1);
1690254885Sdumbbell			/* no HPD on analog connectors */
1691254885Sdumbbell			radeon_connector->hpd.hpd = RADEON_HPD_NONE;
1692254885Sdumbbell			connector->interlace_allowed = true;
1693254885Sdumbbell			connector->doublescan_allowed = true;
1694254885Sdumbbell			break;
1695254885Sdumbbell		case DRM_MODE_CONNECTOR_DVII:
1696254885Sdumbbell		case DRM_MODE_CONNECTOR_DVID:
1697254885Sdumbbell			radeon_dig_connector = malloc(
1698254885Sdumbbell			    sizeof(struct radeon_connector_atom_dig),
1699282199Sdumbbell			    DRM_MEM_DRIVER, M_NOWAIT | M_ZERO);
1700254885Sdumbbell			if (!radeon_dig_connector)
1701254885Sdumbbell				goto failed;
1702254885Sdumbbell			radeon_dig_connector->igp_lane_info = igp_lane_info;
1703254885Sdumbbell			radeon_connector->con_priv = radeon_dig_connector;
1704254885Sdumbbell			drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type);
1705254885Sdumbbell			drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs);
1706254885Sdumbbell			if (i2c_bus->valid) {
1707254885Sdumbbell				radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus);
1708254885Sdumbbell				if (!radeon_connector->ddc_bus)
1709254885Sdumbbell					DRM_ERROR("DVI: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
1710254885Sdumbbell			}
1711254885Sdumbbell			subpixel_order = SubPixelHorizontalRGB;
1712282199Sdumbbell			drm_object_attach_property(&radeon_connector->base.base,
1713254885Sdumbbell						      rdev->mode_info.coherent_mode_property,
1714254885Sdumbbell						      1);
1715254885Sdumbbell			if (ASIC_IS_AVIVO(rdev)) {
1716282199Sdumbbell				drm_object_attach_property(&radeon_connector->base.base,
1717254885Sdumbbell							      rdev->mode_info.underscan_property,
1718254885Sdumbbell							      UNDERSCAN_OFF);
1719282199Sdumbbell				drm_object_attach_property(&radeon_connector->base.base,
1720254885Sdumbbell							      rdev->mode_info.underscan_hborder_property,
1721254885Sdumbbell							      0);
1722282199Sdumbbell				drm_object_attach_property(&radeon_connector->base.base,
1723254885Sdumbbell							      rdev->mode_info.underscan_vborder_property,
1724254885Sdumbbell							      0);
1725254885Sdumbbell			}
1726254885Sdumbbell			if (connector_type == DRM_MODE_CONNECTOR_DVII) {
1727254885Sdumbbell				radeon_connector->dac_load_detect = true;
1728282199Sdumbbell				drm_object_attach_property(&radeon_connector->base.base,
1729254885Sdumbbell							      rdev->mode_info.load_detect_property,
1730254885Sdumbbell							      1);
1731254885Sdumbbell			}
1732254885Sdumbbell			connector->interlace_allowed = true;
1733254885Sdumbbell			if (connector_type == DRM_MODE_CONNECTOR_DVII)
1734254885Sdumbbell				connector->doublescan_allowed = true;
1735254885Sdumbbell			else
1736254885Sdumbbell				connector->doublescan_allowed = false;
1737254885Sdumbbell			break;
1738254885Sdumbbell		case DRM_MODE_CONNECTOR_HDMIA:
1739254885Sdumbbell		case DRM_MODE_CONNECTOR_HDMIB:
1740254885Sdumbbell			radeon_dig_connector = malloc(
1741254885Sdumbbell			    sizeof(struct radeon_connector_atom_dig),
1742282199Sdumbbell			    DRM_MEM_DRIVER, M_NOWAIT | M_ZERO);
1743254885Sdumbbell			if (!radeon_dig_connector)
1744254885Sdumbbell				goto failed;
1745254885Sdumbbell			radeon_dig_connector->igp_lane_info = igp_lane_info;
1746254885Sdumbbell			radeon_connector->con_priv = radeon_dig_connector;
1747254885Sdumbbell			drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type);
1748254885Sdumbbell			drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs);
1749254885Sdumbbell			if (i2c_bus->valid) {
1750254885Sdumbbell				radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus);
1751254885Sdumbbell				if (!radeon_connector->ddc_bus)
1752254885Sdumbbell					DRM_ERROR("HDMI: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
1753254885Sdumbbell			}
1754282199Sdumbbell			drm_object_attach_property(&radeon_connector->base.base,
1755254885Sdumbbell						      rdev->mode_info.coherent_mode_property,
1756254885Sdumbbell						      1);
1757254885Sdumbbell			if (ASIC_IS_AVIVO(rdev)) {
1758282199Sdumbbell				drm_object_attach_property(&radeon_connector->base.base,
1759254885Sdumbbell							      rdev->mode_info.underscan_property,
1760254885Sdumbbell							      UNDERSCAN_OFF);
1761282199Sdumbbell				drm_object_attach_property(&radeon_connector->base.base,
1762254885Sdumbbell							      rdev->mode_info.underscan_hborder_property,
1763254885Sdumbbell							      0);
1764282199Sdumbbell				drm_object_attach_property(&radeon_connector->base.base,
1765254885Sdumbbell							      rdev->mode_info.underscan_vborder_property,
1766254885Sdumbbell							      0);
1767254885Sdumbbell			}
1768254885Sdumbbell			subpixel_order = SubPixelHorizontalRGB;
1769254885Sdumbbell			connector->interlace_allowed = true;
1770254885Sdumbbell			if (connector_type == DRM_MODE_CONNECTOR_HDMIB)
1771254885Sdumbbell				connector->doublescan_allowed = true;
1772254885Sdumbbell			else
1773254885Sdumbbell				connector->doublescan_allowed = false;
1774254885Sdumbbell			break;
1775254885Sdumbbell		case DRM_MODE_CONNECTOR_DisplayPort:
1776254885Sdumbbell			radeon_dig_connector = malloc(
1777254885Sdumbbell			    sizeof(struct radeon_connector_atom_dig),
1778282199Sdumbbell			    DRM_MEM_DRIVER, M_NOWAIT | M_ZERO);
1779254885Sdumbbell			if (!radeon_dig_connector)
1780254885Sdumbbell				goto failed;
1781254885Sdumbbell			radeon_dig_connector->igp_lane_info = igp_lane_info;
1782254885Sdumbbell			radeon_connector->con_priv = radeon_dig_connector;
1783254885Sdumbbell			drm_connector_init(dev, &radeon_connector->base, &radeon_dp_connector_funcs, connector_type);
1784254885Sdumbbell			drm_connector_helper_add(&radeon_connector->base, &radeon_dp_connector_helper_funcs);
1785254885Sdumbbell			if (i2c_bus->valid) {
1786254885Sdumbbell				/* add DP i2c bus */
1787254885Sdumbbell				radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "DP-auxch");
1788254885Sdumbbell				if (!radeon_dig_connector->dp_i2c_bus)
1789254885Sdumbbell					DRM_ERROR("DP: Failed to assign dp ddc bus! Check dmesg for i2c errors.\n");
1790254885Sdumbbell				radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus);
1791254885Sdumbbell				if (!radeon_connector->ddc_bus)
1792254885Sdumbbell					DRM_ERROR("DP: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
1793254885Sdumbbell			}
1794254885Sdumbbell			subpixel_order = SubPixelHorizontalRGB;
1795282199Sdumbbell			drm_object_attach_property(&radeon_connector->base.base,
1796254885Sdumbbell						      rdev->mode_info.coherent_mode_property,
1797254885Sdumbbell						      1);
1798254885Sdumbbell			if (ASIC_IS_AVIVO(rdev)) {
1799282199Sdumbbell				drm_object_attach_property(&radeon_connector->base.base,
1800254885Sdumbbell							      rdev->mode_info.underscan_property,
1801254885Sdumbbell							      UNDERSCAN_OFF);
1802282199Sdumbbell				drm_object_attach_property(&radeon_connector->base.base,
1803254885Sdumbbell							      rdev->mode_info.underscan_hborder_property,
1804254885Sdumbbell							      0);
1805282199Sdumbbell				drm_object_attach_property(&radeon_connector->base.base,
1806254885Sdumbbell							      rdev->mode_info.underscan_vborder_property,
1807254885Sdumbbell							      0);
1808254885Sdumbbell			}
1809254885Sdumbbell			connector->interlace_allowed = true;
1810254885Sdumbbell			/* in theory with a DP to VGA converter... */
1811254885Sdumbbell			connector->doublescan_allowed = false;
1812254885Sdumbbell			break;
1813254885Sdumbbell		case DRM_MODE_CONNECTOR_eDP:
1814254885Sdumbbell			radeon_dig_connector = malloc(
1815254885Sdumbbell			    sizeof(struct radeon_connector_atom_dig),
1816282199Sdumbbell			    DRM_MEM_DRIVER, M_NOWAIT | M_ZERO);
1817254885Sdumbbell			if (!radeon_dig_connector)
1818254885Sdumbbell				goto failed;
1819254885Sdumbbell			radeon_dig_connector->igp_lane_info = igp_lane_info;
1820254885Sdumbbell			radeon_connector->con_priv = radeon_dig_connector;
1821254885Sdumbbell			drm_connector_init(dev, &radeon_connector->base, &radeon_dp_connector_funcs, connector_type);
1822254885Sdumbbell			drm_connector_helper_add(&radeon_connector->base, &radeon_dp_connector_helper_funcs);
1823254885Sdumbbell			if (i2c_bus->valid) {
1824254885Sdumbbell				/* add DP i2c bus */
1825254885Sdumbbell				radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "eDP-auxch");
1826254885Sdumbbell				if (!radeon_dig_connector->dp_i2c_bus)
1827254885Sdumbbell					DRM_ERROR("DP: Failed to assign dp ddc bus! Check dmesg for i2c errors.\n");
1828254885Sdumbbell				radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus);
1829254885Sdumbbell				if (!radeon_connector->ddc_bus)
1830254885Sdumbbell					DRM_ERROR("DP: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
1831254885Sdumbbell			}
1832282199Sdumbbell			drm_object_attach_property(&radeon_connector->base.base,
1833254885Sdumbbell						      dev->mode_config.scaling_mode_property,
1834254885Sdumbbell						      DRM_MODE_SCALE_FULLSCREEN);
1835254885Sdumbbell			subpixel_order = SubPixelHorizontalRGB;
1836254885Sdumbbell			connector->interlace_allowed = false;
1837254885Sdumbbell			connector->doublescan_allowed = false;
1838254885Sdumbbell			break;
1839254885Sdumbbell		case DRM_MODE_CONNECTOR_SVIDEO:
1840254885Sdumbbell		case DRM_MODE_CONNECTOR_Composite:
1841254885Sdumbbell		case DRM_MODE_CONNECTOR_9PinDIN:
1842254885Sdumbbell			drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type);
1843254885Sdumbbell			drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs);
1844254885Sdumbbell			radeon_connector->dac_load_detect = true;
1845282199Sdumbbell			drm_object_attach_property(&radeon_connector->base.base,
1846254885Sdumbbell						      rdev->mode_info.load_detect_property,
1847254885Sdumbbell						      1);
1848282199Sdumbbell			drm_object_attach_property(&radeon_connector->base.base,
1849254885Sdumbbell						      rdev->mode_info.tv_std_property,
1850254885Sdumbbell						      radeon_atombios_get_tv_info(rdev));
1851254885Sdumbbell			/* no HPD on analog connectors */
1852254885Sdumbbell			radeon_connector->hpd.hpd = RADEON_HPD_NONE;
1853254885Sdumbbell			connector->interlace_allowed = false;
1854254885Sdumbbell			connector->doublescan_allowed = false;
1855254885Sdumbbell			break;
1856254885Sdumbbell		case DRM_MODE_CONNECTOR_LVDS:
1857254885Sdumbbell			radeon_dig_connector = malloc(
1858254885Sdumbbell			    sizeof(struct radeon_connector_atom_dig),
1859282199Sdumbbell			    DRM_MEM_DRIVER, M_NOWAIT | M_ZERO);
1860254885Sdumbbell			if (!radeon_dig_connector)
1861254885Sdumbbell				goto failed;
1862254885Sdumbbell			radeon_dig_connector->igp_lane_info = igp_lane_info;
1863254885Sdumbbell			radeon_connector->con_priv = radeon_dig_connector;
1864254885Sdumbbell			drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type);
1865254885Sdumbbell			drm_connector_helper_add(&radeon_connector->base, &radeon_lvds_connector_helper_funcs);
1866254885Sdumbbell			if (i2c_bus->valid) {
1867254885Sdumbbell				radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus);
1868254885Sdumbbell				if (!radeon_connector->ddc_bus)
1869254885Sdumbbell					DRM_ERROR("LVDS: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
1870254885Sdumbbell			}
1871282199Sdumbbell			drm_object_attach_property(&radeon_connector->base.base,
1872254885Sdumbbell						      dev->mode_config.scaling_mode_property,
1873254885Sdumbbell						      DRM_MODE_SCALE_FULLSCREEN);
1874254885Sdumbbell			subpixel_order = SubPixelHorizontalRGB;
1875254885Sdumbbell			connector->interlace_allowed = false;
1876254885Sdumbbell			connector->doublescan_allowed = false;
1877254885Sdumbbell			break;
1878254885Sdumbbell		}
1879254885Sdumbbell	}
1880254885Sdumbbell
1881254885Sdumbbell	if (radeon_connector->hpd.hpd == RADEON_HPD_NONE) {
1882254885Sdumbbell		if (i2c_bus->valid)
1883254885Sdumbbell			connector->polled = DRM_CONNECTOR_POLL_CONNECT;
1884254885Sdumbbell	} else
1885254885Sdumbbell		connector->polled = DRM_CONNECTOR_POLL_HPD;
1886254885Sdumbbell
1887254885Sdumbbell	connector->display_info.subpixel_order = subpixel_order;
1888282199Sdumbbell#ifdef FREEBSD_WIP
1889254885Sdumbbell	drm_sysfs_connector_add(connector);
1890282199Sdumbbell#endif /* FREEBSD_WIP */
1891254885Sdumbbell	return;
1892254885Sdumbbell
1893254885Sdumbbellfailed:
1894254885Sdumbbell	drm_connector_cleanup(connector);
1895254885Sdumbbell	free(connector, DRM_MEM_DRIVER);
1896254885Sdumbbell}
1897254885Sdumbbell
1898254885Sdumbbellvoid
1899254885Sdumbbellradeon_add_legacy_connector(struct drm_device *dev,
1900254885Sdumbbell			    uint32_t connector_id,
1901254885Sdumbbell			    uint32_t supported_device,
1902254885Sdumbbell			    int connector_type,
1903254885Sdumbbell			    struct radeon_i2c_bus_rec *i2c_bus,
1904254885Sdumbbell			    uint16_t connector_object_id,
1905254885Sdumbbell			    struct radeon_hpd *hpd)
1906254885Sdumbbell{
1907254885Sdumbbell	struct radeon_device *rdev = dev->dev_private;
1908254885Sdumbbell	struct drm_connector *connector;
1909254885Sdumbbell	struct radeon_connector *radeon_connector;
1910254885Sdumbbell	uint32_t subpixel_order = SubPixelNone;
1911254885Sdumbbell
1912254885Sdumbbell	if (connector_type == DRM_MODE_CONNECTOR_Unknown)
1913254885Sdumbbell		return;
1914254885Sdumbbell
1915254885Sdumbbell	/* if the user selected tv=0 don't try and add the connector */
1916254885Sdumbbell	if (((connector_type == DRM_MODE_CONNECTOR_SVIDEO) ||
1917254885Sdumbbell	     (connector_type == DRM_MODE_CONNECTOR_Composite) ||
1918254885Sdumbbell	     (connector_type == DRM_MODE_CONNECTOR_9PinDIN)) &&
1919254885Sdumbbell	    (radeon_tv == 0))
1920254885Sdumbbell		return;
1921254885Sdumbbell
1922254885Sdumbbell	/* see if we already added it */
1923254885Sdumbbell	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
1924254885Sdumbbell		radeon_connector = to_radeon_connector(connector);
1925254885Sdumbbell		if (radeon_connector->connector_id == connector_id) {
1926254885Sdumbbell			radeon_connector->devices |= supported_device;
1927254885Sdumbbell			return;
1928254885Sdumbbell		}
1929254885Sdumbbell	}
1930254885Sdumbbell
1931254885Sdumbbell	radeon_connector = malloc(sizeof(struct radeon_connector),
1932282199Sdumbbell	    DRM_MEM_DRIVER, M_NOWAIT | M_ZERO);
1933254885Sdumbbell	if (!radeon_connector)
1934254885Sdumbbell		return;
1935254885Sdumbbell
1936254885Sdumbbell	connector = &radeon_connector->base;
1937254885Sdumbbell
1938254885Sdumbbell	radeon_connector->connector_id = connector_id;
1939254885Sdumbbell	radeon_connector->devices = supported_device;
1940254885Sdumbbell	radeon_connector->connector_object_id = connector_object_id;
1941254885Sdumbbell	radeon_connector->hpd = *hpd;
1942254885Sdumbbell
1943254885Sdumbbell	switch (connector_type) {
1944254885Sdumbbell	case DRM_MODE_CONNECTOR_VGA:
1945254885Sdumbbell		drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
1946254885Sdumbbell		drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs);
1947254885Sdumbbell		if (i2c_bus->valid) {
1948254885Sdumbbell			radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus);
1949254885Sdumbbell			if (!radeon_connector->ddc_bus)
1950254885Sdumbbell				DRM_ERROR("VGA: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
1951254885Sdumbbell		}
1952254885Sdumbbell		radeon_connector->dac_load_detect = true;
1953282199Sdumbbell		drm_object_attach_property(&radeon_connector->base.base,
1954254885Sdumbbell					      rdev->mode_info.load_detect_property,
1955254885Sdumbbell					      1);
1956254885Sdumbbell		/* no HPD on analog connectors */
1957254885Sdumbbell		radeon_connector->hpd.hpd = RADEON_HPD_NONE;
1958254885Sdumbbell		connector->polled = DRM_CONNECTOR_POLL_CONNECT;
1959254885Sdumbbell		connector->interlace_allowed = true;
1960254885Sdumbbell		connector->doublescan_allowed = true;
1961254885Sdumbbell		break;
1962254885Sdumbbell	case DRM_MODE_CONNECTOR_DVIA:
1963254885Sdumbbell		drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
1964254885Sdumbbell		drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs);
1965254885Sdumbbell		if (i2c_bus->valid) {
1966254885Sdumbbell			radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus);
1967254885Sdumbbell			if (!radeon_connector->ddc_bus)
1968254885Sdumbbell				DRM_ERROR("DVIA: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
1969254885Sdumbbell		}
1970254885Sdumbbell		radeon_connector->dac_load_detect = true;
1971282199Sdumbbell		drm_object_attach_property(&radeon_connector->base.base,
1972254885Sdumbbell					      rdev->mode_info.load_detect_property,
1973254885Sdumbbell					      1);
1974254885Sdumbbell		/* no HPD on analog connectors */
1975254885Sdumbbell		radeon_connector->hpd.hpd = RADEON_HPD_NONE;
1976254885Sdumbbell		connector->interlace_allowed = true;
1977254885Sdumbbell		connector->doublescan_allowed = true;
1978254885Sdumbbell		break;
1979254885Sdumbbell	case DRM_MODE_CONNECTOR_DVII:
1980254885Sdumbbell	case DRM_MODE_CONNECTOR_DVID:
1981254885Sdumbbell		drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type);
1982254885Sdumbbell		drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs);
1983254885Sdumbbell		if (i2c_bus->valid) {
1984254885Sdumbbell			radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus);
1985254885Sdumbbell			if (!radeon_connector->ddc_bus)
1986254885Sdumbbell				DRM_ERROR("DVI: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
1987254885Sdumbbell		}
1988254885Sdumbbell		if (connector_type == DRM_MODE_CONNECTOR_DVII) {
1989254885Sdumbbell			radeon_connector->dac_load_detect = true;
1990282199Sdumbbell			drm_object_attach_property(&radeon_connector->base.base,
1991254885Sdumbbell						      rdev->mode_info.load_detect_property,
1992254885Sdumbbell						      1);
1993254885Sdumbbell		}
1994254885Sdumbbell		subpixel_order = SubPixelHorizontalRGB;
1995254885Sdumbbell		connector->interlace_allowed = true;
1996254885Sdumbbell		if (connector_type == DRM_MODE_CONNECTOR_DVII)
1997254885Sdumbbell			connector->doublescan_allowed = true;
1998254885Sdumbbell		else
1999254885Sdumbbell			connector->doublescan_allowed = false;
2000254885Sdumbbell		break;
2001254885Sdumbbell	case DRM_MODE_CONNECTOR_SVIDEO:
2002254885Sdumbbell	case DRM_MODE_CONNECTOR_Composite:
2003254885Sdumbbell	case DRM_MODE_CONNECTOR_9PinDIN:
2004254885Sdumbbell		drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type);
2005254885Sdumbbell		drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs);
2006254885Sdumbbell		radeon_connector->dac_load_detect = true;
2007254885Sdumbbell		/* RS400,RC410,RS480 chipset seems to report a lot
2008254885Sdumbbell		 * of false positive on load detect, we haven't yet
2009254885Sdumbbell		 * found a way to make load detect reliable on those
2010254885Sdumbbell		 * chipset, thus just disable it for TV.
2011254885Sdumbbell		 */
2012254885Sdumbbell		if (rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480)
2013254885Sdumbbell			radeon_connector->dac_load_detect = false;
2014282199Sdumbbell		drm_object_attach_property(&radeon_connector->base.base,
2015254885Sdumbbell					      rdev->mode_info.load_detect_property,
2016254885Sdumbbell					      radeon_connector->dac_load_detect);
2017282199Sdumbbell		drm_object_attach_property(&radeon_connector->base.base,
2018254885Sdumbbell					      rdev->mode_info.tv_std_property,
2019254885Sdumbbell					      radeon_combios_get_tv_info(rdev));
2020254885Sdumbbell		/* no HPD on analog connectors */
2021254885Sdumbbell		radeon_connector->hpd.hpd = RADEON_HPD_NONE;
2022254885Sdumbbell		connector->interlace_allowed = false;
2023254885Sdumbbell		connector->doublescan_allowed = false;
2024254885Sdumbbell		break;
2025254885Sdumbbell	case DRM_MODE_CONNECTOR_LVDS:
2026254885Sdumbbell		drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type);
2027254885Sdumbbell		drm_connector_helper_add(&radeon_connector->base, &radeon_lvds_connector_helper_funcs);
2028254885Sdumbbell		if (i2c_bus->valid) {
2029254885Sdumbbell			radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus);
2030254885Sdumbbell			if (!radeon_connector->ddc_bus)
2031254885Sdumbbell				DRM_ERROR("LVDS: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
2032254885Sdumbbell		}
2033282199Sdumbbell		drm_object_attach_property(&radeon_connector->base.base,
2034254885Sdumbbell					      dev->mode_config.scaling_mode_property,
2035254885Sdumbbell					      DRM_MODE_SCALE_FULLSCREEN);
2036254885Sdumbbell		subpixel_order = SubPixelHorizontalRGB;
2037254885Sdumbbell		connector->interlace_allowed = false;
2038254885Sdumbbell		connector->doublescan_allowed = false;
2039254885Sdumbbell		break;
2040254885Sdumbbell	}
2041254885Sdumbbell
2042254885Sdumbbell	if (radeon_connector->hpd.hpd == RADEON_HPD_NONE) {
2043254885Sdumbbell		if (i2c_bus->valid)
2044254885Sdumbbell			connector->polled = DRM_CONNECTOR_POLL_CONNECT;
2045254885Sdumbbell	} else
2046254885Sdumbbell		connector->polled = DRM_CONNECTOR_POLL_HPD;
2047254885Sdumbbell	connector->display_info.subpixel_order = subpixel_order;
2048282199Sdumbbell#ifdef FREEBSD_WIP
2049254885Sdumbbell	drm_sysfs_connector_add(connector);
2050282199Sdumbbell#endif /* FREEBSD_WIP */
2051254885Sdumbbell}
2052