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