radeon_encoders.c revision 1.1
1/*	$OpenBSD: radeon_encoders.c,v 1.1 2013/08/12 04:11:53 jsg Exp $	*/
2/*
3 * Copyright 2007-8 Advanced Micro Devices, Inc.
4 * Copyright 2008 Red Hat Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors: Dave Airlie
25 *          Alex Deucher
26 */
27#include <dev/pci/drm/drmP.h>
28#include <dev/pci/drm/drm_crtc_helper.h>
29#include <dev/pci/drm/radeon_drm.h>
30#include "radeon.h"
31#include "atom.h"
32
33extern void
34radeon_legacy_backlight_init(struct radeon_encoder *radeon_encoder,
35			     struct drm_connector *drm_connector);
36extern void
37radeon_atom_backlight_init(struct radeon_encoder *radeon_encoder,
38			   struct drm_connector *drm_connector);
39
40uint32_t	radeon_get_encoder_enum(struct drm_device *, uint32_t, uint8_t);
41void		radeon_link_encoder_connector(struct drm_device *);
42
43static uint32_t radeon_encoder_clones(struct drm_encoder *encoder)
44{
45	struct drm_device *dev = encoder->dev;
46	struct radeon_device *rdev = dev->dev_private;
47	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
48	struct drm_encoder *clone_encoder;
49	uint32_t index_mask = 0;
50	int count;
51
52	/* DIG routing gets problematic */
53	if (rdev->family >= CHIP_R600)
54		return index_mask;
55	/* LVDS/TV are too wacky */
56	if (radeon_encoder->devices & ATOM_DEVICE_LCD_SUPPORT)
57		return index_mask;
58	/* DVO requires 2x ppll clocks depending on tmds chip */
59	if (radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT)
60		return index_mask;
61
62	count = -1;
63	list_for_each_entry(clone_encoder, &dev->mode_config.encoder_list, head) {
64		struct radeon_encoder *radeon_clone = to_radeon_encoder(clone_encoder);
65		count++;
66
67		if (clone_encoder == encoder)
68			continue;
69		if (radeon_clone->devices & (ATOM_DEVICE_LCD_SUPPORT))
70			continue;
71		if (radeon_clone->devices & ATOM_DEVICE_DFP2_SUPPORT)
72			continue;
73		else
74			index_mask |= (1 << count);
75	}
76	return index_mask;
77}
78
79void radeon_setup_encoder_clones(struct drm_device *dev)
80{
81	struct drm_encoder *encoder;
82
83	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
84		encoder->possible_clones = radeon_encoder_clones(encoder);
85	}
86}
87
88uint32_t
89radeon_get_encoder_enum(struct drm_device *dev, uint32_t supported_device, uint8_t dac)
90{
91	struct radeon_device *rdev = dev->dev_private;
92	uint32_t ret = 0;
93
94	switch (supported_device) {
95	case ATOM_DEVICE_CRT1_SUPPORT:
96	case ATOM_DEVICE_TV1_SUPPORT:
97	case ATOM_DEVICE_TV2_SUPPORT:
98	case ATOM_DEVICE_CRT2_SUPPORT:
99	case ATOM_DEVICE_CV_SUPPORT:
100		switch (dac) {
101		case 1: /* dac a */
102			if ((rdev->family == CHIP_RS300) ||
103			    (rdev->family == CHIP_RS400) ||
104			    (rdev->family == CHIP_RS480))
105				ret = ENCODER_INTERNAL_DAC2_ENUM_ID1;
106			else if (ASIC_IS_AVIVO(rdev))
107				ret = ENCODER_INTERNAL_KLDSCP_DAC1_ENUM_ID1;
108			else
109				ret = ENCODER_INTERNAL_DAC1_ENUM_ID1;
110			break;
111		case 2: /* dac b */
112			if (ASIC_IS_AVIVO(rdev))
113				ret = ENCODER_INTERNAL_KLDSCP_DAC2_ENUM_ID1;
114			else {
115				/*if (rdev->family == CHIP_R200)
116				  ret = ENCODER_INTERNAL_DVO1_ENUM_ID1;
117				  else*/
118				ret = ENCODER_INTERNAL_DAC2_ENUM_ID1;
119			}
120			break;
121		case 3: /* external dac */
122			if (ASIC_IS_AVIVO(rdev))
123				ret = ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1;
124			else
125				ret = ENCODER_INTERNAL_DVO1_ENUM_ID1;
126			break;
127		}
128		break;
129	case ATOM_DEVICE_LCD1_SUPPORT:
130		if (ASIC_IS_AVIVO(rdev))
131			ret = ENCODER_INTERNAL_LVTM1_ENUM_ID1;
132		else
133			ret = ENCODER_INTERNAL_LVDS_ENUM_ID1;
134		break;
135	case ATOM_DEVICE_DFP1_SUPPORT:
136		if ((rdev->family == CHIP_RS300) ||
137		    (rdev->family == CHIP_RS400) ||
138		    (rdev->family == CHIP_RS480))
139			ret = ENCODER_INTERNAL_DVO1_ENUM_ID1;
140		else if (ASIC_IS_AVIVO(rdev))
141			ret = ENCODER_INTERNAL_KLDSCP_TMDS1_ENUM_ID1;
142		else
143			ret = ENCODER_INTERNAL_TMDS1_ENUM_ID1;
144		break;
145	case ATOM_DEVICE_LCD2_SUPPORT:
146	case ATOM_DEVICE_DFP2_SUPPORT:
147		if ((rdev->family == CHIP_RS600) ||
148		    (rdev->family == CHIP_RS690) ||
149		    (rdev->family == CHIP_RS740))
150			ret = ENCODER_INTERNAL_DDI_ENUM_ID1;
151		else if (ASIC_IS_AVIVO(rdev))
152			ret = ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1;
153		else
154			ret = ENCODER_INTERNAL_DVO1_ENUM_ID1;
155		break;
156	case ATOM_DEVICE_DFP3_SUPPORT:
157		ret = ENCODER_INTERNAL_LVTM1_ENUM_ID1;
158		break;
159	}
160
161	return ret;
162}
163
164void
165radeon_link_encoder_connector(struct drm_device *dev)
166{
167	struct radeon_device *rdev = dev->dev_private;
168	struct drm_connector *connector;
169	struct radeon_connector *radeon_connector;
170	struct drm_encoder *encoder;
171	struct radeon_encoder *radeon_encoder;
172
173	/* walk the list and link encoders to connectors */
174	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
175		radeon_connector = to_radeon_connector(connector);
176		list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
177			radeon_encoder = to_radeon_encoder(encoder);
178			if (radeon_encoder->devices & radeon_connector->devices) {
179				drm_mode_connector_attach_encoder(connector, encoder);
180				if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
181					if (rdev->is_atom_bios)
182						radeon_atom_backlight_init(radeon_encoder, connector);
183					else
184						radeon_legacy_backlight_init(radeon_encoder, connector);
185					rdev->mode_info.bl_encoder = radeon_encoder;
186				}
187			}
188		}
189	}
190}
191
192void radeon_encoder_set_active_device(struct drm_encoder *encoder)
193{
194	struct drm_device *dev = encoder->dev;
195	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
196	struct drm_connector *connector;
197
198	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
199		if (connector->encoder == encoder) {
200			struct radeon_connector *radeon_connector = to_radeon_connector(connector);
201			radeon_encoder->active_device = radeon_encoder->devices & radeon_connector->devices;
202			DRM_DEBUG_KMS("setting active device to %08x from %08x %08x for encoder %d\n",
203				  radeon_encoder->active_device, radeon_encoder->devices,
204				  radeon_connector->devices, encoder->encoder_type);
205		}
206	}
207}
208
209struct drm_connector *
210radeon_get_connector_for_encoder(struct drm_encoder *encoder)
211{
212	struct drm_device *dev = encoder->dev;
213	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
214	struct drm_connector *connector;
215	struct radeon_connector *radeon_connector;
216
217	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
218		radeon_connector = to_radeon_connector(connector);
219		if (radeon_encoder->active_device & radeon_connector->devices)
220			return connector;
221	}
222	return NULL;
223}
224
225struct drm_connector *
226radeon_get_connector_for_encoder_init(struct drm_encoder *encoder)
227{
228	struct drm_device *dev = encoder->dev;
229	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
230	struct drm_connector *connector;
231	struct radeon_connector *radeon_connector;
232
233	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
234		radeon_connector = to_radeon_connector(connector);
235		if (radeon_encoder->devices & radeon_connector->devices)
236			return connector;
237	}
238	return NULL;
239}
240
241struct drm_encoder *radeon_get_external_encoder(struct drm_encoder *encoder)
242{
243	struct drm_device *dev = encoder->dev;
244	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
245	struct drm_encoder *other_encoder;
246	struct radeon_encoder *other_radeon_encoder;
247
248	if (radeon_encoder->is_ext_encoder)
249		return NULL;
250
251	list_for_each_entry(other_encoder, &dev->mode_config.encoder_list, head) {
252		if (other_encoder == encoder)
253			continue;
254		other_radeon_encoder = to_radeon_encoder(other_encoder);
255		if (other_radeon_encoder->is_ext_encoder &&
256		    (radeon_encoder->devices & other_radeon_encoder->devices))
257			return other_encoder;
258	}
259	return NULL;
260}
261
262u16 radeon_encoder_get_dp_bridge_encoder_id(struct drm_encoder *encoder)
263{
264	struct drm_encoder *other_encoder = radeon_get_external_encoder(encoder);
265
266	if (other_encoder) {
267		struct radeon_encoder *radeon_encoder = to_radeon_encoder(other_encoder);
268
269		switch (radeon_encoder->encoder_id) {
270		case ENCODER_OBJECT_ID_TRAVIS:
271		case ENCODER_OBJECT_ID_NUTMEG:
272			return radeon_encoder->encoder_id;
273		default:
274			return ENCODER_OBJECT_ID_NONE;
275		}
276	}
277	return ENCODER_OBJECT_ID_NONE;
278}
279
280void radeon_panel_mode_fixup(struct drm_encoder *encoder,
281			     struct drm_display_mode *adjusted_mode)
282{
283	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
284	struct drm_device *dev = encoder->dev;
285	struct radeon_device *rdev = dev->dev_private;
286	struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
287	unsigned hblank = native_mode->htotal - native_mode->hdisplay;
288	unsigned vblank = native_mode->vtotal - native_mode->vdisplay;
289	unsigned hover = native_mode->hsync_start - native_mode->hdisplay;
290	unsigned vover = native_mode->vsync_start - native_mode->vdisplay;
291	unsigned hsync_width = native_mode->hsync_end - native_mode->hsync_start;
292	unsigned vsync_width = native_mode->vsync_end - native_mode->vsync_start;
293
294	adjusted_mode->clock = native_mode->clock;
295	adjusted_mode->flags = native_mode->flags;
296
297	if (ASIC_IS_AVIVO(rdev)) {
298		adjusted_mode->hdisplay = native_mode->hdisplay;
299		adjusted_mode->vdisplay = native_mode->vdisplay;
300	}
301
302	adjusted_mode->htotal = native_mode->hdisplay + hblank;
303	adjusted_mode->hsync_start = native_mode->hdisplay + hover;
304	adjusted_mode->hsync_end = adjusted_mode->hsync_start + hsync_width;
305
306	adjusted_mode->vtotal = native_mode->vdisplay + vblank;
307	adjusted_mode->vsync_start = native_mode->vdisplay + vover;
308	adjusted_mode->vsync_end = adjusted_mode->vsync_start + vsync_width;
309
310	drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
311
312	if (ASIC_IS_AVIVO(rdev)) {
313		adjusted_mode->crtc_hdisplay = native_mode->hdisplay;
314		adjusted_mode->crtc_vdisplay = native_mode->vdisplay;
315	}
316
317	adjusted_mode->crtc_htotal = adjusted_mode->crtc_hdisplay + hblank;
318	adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hdisplay + hover;
319	adjusted_mode->crtc_hsync_end = adjusted_mode->crtc_hsync_start + hsync_width;
320
321	adjusted_mode->crtc_vtotal = adjusted_mode->crtc_vdisplay + vblank;
322	adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + vover;
323	adjusted_mode->crtc_vsync_end = adjusted_mode->crtc_vsync_start + vsync_width;
324
325}
326
327bool radeon_dig_monitor_is_duallink(struct drm_encoder *encoder,
328				    u32 pixel_clock)
329{
330	struct drm_device *dev = encoder->dev;
331	struct radeon_device *rdev = dev->dev_private;
332	struct drm_connector *connector;
333	struct radeon_connector *radeon_connector;
334	struct radeon_connector_atom_dig *dig_connector;
335
336	connector = radeon_get_connector_for_encoder(encoder);
337	/* if we don't have an active device yet, just use one of
338	 * the connectors tied to the encoder.
339	 */
340	if (!connector)
341		connector = radeon_get_connector_for_encoder_init(encoder);
342	radeon_connector = to_radeon_connector(connector);
343
344	switch (connector->connector_type) {
345	case DRM_MODE_CONNECTOR_DVII:
346	case DRM_MODE_CONNECTOR_HDMIB:
347		if (radeon_connector->use_digital) {
348			/* HDMI 1.3 supports up to 340 Mhz over single link */
349			if (ASIC_IS_DCE6(rdev) && drm_detect_hdmi_monitor(radeon_connector->edid)) {
350				if (pixel_clock > 340000)
351					return true;
352				else
353					return false;
354			} else {
355				if (pixel_clock > 165000)
356					return true;
357				else
358					return false;
359			}
360		} else
361			return false;
362	case DRM_MODE_CONNECTOR_DVID:
363	case DRM_MODE_CONNECTOR_HDMIA:
364	case DRM_MODE_CONNECTOR_DisplayPort:
365		dig_connector = radeon_connector->con_priv;
366		if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
367		    (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP))
368			return false;
369		else {
370			/* HDMI 1.3 supports up to 340 Mhz over single link */
371			if (ASIC_IS_DCE6(rdev) && drm_detect_hdmi_monitor(radeon_connector->edid)) {
372				if (pixel_clock > 340000)
373					return true;
374				else
375					return false;
376			} else {
377				if (pixel_clock > 165000)
378					return true;
379				else
380					return false;
381			}
382		}
383	default:
384		return false;
385	}
386}
387
388