radeon_encoders.c revision 1.2
1/*	$OpenBSD: radeon_encoders.c,v 1.2 2015/04/18 14:47:35 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
40
41static uint32_t radeon_encoder_clones(struct drm_encoder *encoder)
42{
43	struct drm_device *dev = encoder->dev;
44	struct radeon_device *rdev = dev->dev_private;
45	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
46	struct drm_encoder *clone_encoder;
47	uint32_t index_mask = 0;
48	int count;
49
50	/* DIG routing gets problematic */
51	if (rdev->family >= CHIP_R600)
52		return index_mask;
53	/* LVDS/TV are too wacky */
54	if (radeon_encoder->devices & ATOM_DEVICE_LCD_SUPPORT)
55		return index_mask;
56	/* DVO requires 2x ppll clocks depending on tmds chip */
57	if (radeon_encoder->devices & ATOM_DEVICE_DFP2_SUPPORT)
58		return index_mask;
59
60	count = -1;
61	list_for_each_entry(clone_encoder, &dev->mode_config.encoder_list, head) {
62		struct radeon_encoder *radeon_clone = to_radeon_encoder(clone_encoder);
63		count++;
64
65		if (clone_encoder == encoder)
66			continue;
67		if (radeon_clone->devices & (ATOM_DEVICE_LCD_SUPPORT))
68			continue;
69		if (radeon_clone->devices & ATOM_DEVICE_DFP2_SUPPORT)
70			continue;
71		else
72			index_mask |= (1 << count);
73	}
74	return index_mask;
75}
76
77void radeon_setup_encoder_clones(struct drm_device *dev)
78{
79	struct drm_encoder *encoder;
80
81	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
82		encoder->possible_clones = radeon_encoder_clones(encoder);
83	}
84}
85
86uint32_t
87radeon_get_encoder_enum(struct drm_device *dev, uint32_t supported_device, uint8_t dac)
88{
89	struct radeon_device *rdev = dev->dev_private;
90	uint32_t ret = 0;
91
92	switch (supported_device) {
93	case ATOM_DEVICE_CRT1_SUPPORT:
94	case ATOM_DEVICE_TV1_SUPPORT:
95	case ATOM_DEVICE_TV2_SUPPORT:
96	case ATOM_DEVICE_CRT2_SUPPORT:
97	case ATOM_DEVICE_CV_SUPPORT:
98		switch (dac) {
99		case 1: /* dac a */
100			if ((rdev->family == CHIP_RS300) ||
101			    (rdev->family == CHIP_RS400) ||
102			    (rdev->family == CHIP_RS480))
103				ret = ENCODER_INTERNAL_DAC2_ENUM_ID1;
104			else if (ASIC_IS_AVIVO(rdev))
105				ret = ENCODER_INTERNAL_KLDSCP_DAC1_ENUM_ID1;
106			else
107				ret = ENCODER_INTERNAL_DAC1_ENUM_ID1;
108			break;
109		case 2: /* dac b */
110			if (ASIC_IS_AVIVO(rdev))
111				ret = ENCODER_INTERNAL_KLDSCP_DAC2_ENUM_ID1;
112			else {
113				/*if (rdev->family == CHIP_R200)
114				  ret = ENCODER_INTERNAL_DVO1_ENUM_ID1;
115				  else*/
116				ret = ENCODER_INTERNAL_DAC2_ENUM_ID1;
117			}
118			break;
119		case 3: /* external dac */
120			if (ASIC_IS_AVIVO(rdev))
121				ret = ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1;
122			else
123				ret = ENCODER_INTERNAL_DVO1_ENUM_ID1;
124			break;
125		}
126		break;
127	case ATOM_DEVICE_LCD1_SUPPORT:
128		if (ASIC_IS_AVIVO(rdev))
129			ret = ENCODER_INTERNAL_LVTM1_ENUM_ID1;
130		else
131			ret = ENCODER_INTERNAL_LVDS_ENUM_ID1;
132		break;
133	case ATOM_DEVICE_DFP1_SUPPORT:
134		if ((rdev->family == CHIP_RS300) ||
135		    (rdev->family == CHIP_RS400) ||
136		    (rdev->family == CHIP_RS480))
137			ret = ENCODER_INTERNAL_DVO1_ENUM_ID1;
138		else if (ASIC_IS_AVIVO(rdev))
139			ret = ENCODER_INTERNAL_KLDSCP_TMDS1_ENUM_ID1;
140		else
141			ret = ENCODER_INTERNAL_TMDS1_ENUM_ID1;
142		break;
143	case ATOM_DEVICE_LCD2_SUPPORT:
144	case ATOM_DEVICE_DFP2_SUPPORT:
145		if ((rdev->family == CHIP_RS600) ||
146		    (rdev->family == CHIP_RS690) ||
147		    (rdev->family == CHIP_RS740))
148			ret = ENCODER_INTERNAL_DDI_ENUM_ID1;
149		else if (ASIC_IS_AVIVO(rdev))
150			ret = ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1;
151		else
152			ret = ENCODER_INTERNAL_DVO1_ENUM_ID1;
153		break;
154	case ATOM_DEVICE_DFP3_SUPPORT:
155		ret = ENCODER_INTERNAL_LVTM1_ENUM_ID1;
156		break;
157	}
158
159	return ret;
160}
161
162void
163radeon_link_encoder_connector(struct drm_device *dev)
164{
165	struct radeon_device *rdev = dev->dev_private;
166	struct drm_connector *connector;
167	struct radeon_connector *radeon_connector;
168	struct drm_encoder *encoder;
169	struct radeon_encoder *radeon_encoder;
170
171	/* walk the list and link encoders to connectors */
172	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
173		radeon_connector = to_radeon_connector(connector);
174		list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
175			radeon_encoder = to_radeon_encoder(encoder);
176			if (radeon_encoder->devices & radeon_connector->devices) {
177				drm_mode_connector_attach_encoder(connector, encoder);
178				if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
179					if (rdev->is_atom_bios)
180						radeon_atom_backlight_init(radeon_encoder, connector);
181					else
182						radeon_legacy_backlight_init(radeon_encoder, connector);
183					rdev->mode_info.bl_encoder = radeon_encoder;
184				}
185			}
186		}
187	}
188}
189
190void radeon_encoder_set_active_device(struct drm_encoder *encoder)
191{
192	struct drm_device *dev = encoder->dev;
193	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
194	struct drm_connector *connector;
195
196	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
197		if (connector->encoder == encoder) {
198			struct radeon_connector *radeon_connector = to_radeon_connector(connector);
199			radeon_encoder->active_device = radeon_encoder->devices & radeon_connector->devices;
200			DRM_DEBUG_KMS("setting active device to %08x from %08x %08x for encoder %d\n",
201				  radeon_encoder->active_device, radeon_encoder->devices,
202				  radeon_connector->devices, encoder->encoder_type);
203		}
204	}
205}
206
207struct drm_connector *
208radeon_get_connector_for_encoder(struct drm_encoder *encoder)
209{
210	struct drm_device *dev = encoder->dev;
211	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
212	struct drm_connector *connector;
213	struct radeon_connector *radeon_connector;
214
215	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
216		radeon_connector = to_radeon_connector(connector);
217		if (radeon_encoder->active_device & radeon_connector->devices)
218			return connector;
219	}
220	return NULL;
221}
222
223struct drm_connector *
224radeon_get_connector_for_encoder_init(struct drm_encoder *encoder)
225{
226	struct drm_device *dev = encoder->dev;
227	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
228	struct drm_connector *connector;
229	struct radeon_connector *radeon_connector;
230
231	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
232		radeon_connector = to_radeon_connector(connector);
233		if (radeon_encoder->devices & radeon_connector->devices)
234			return connector;
235	}
236	return NULL;
237}
238
239struct drm_encoder *radeon_get_external_encoder(struct drm_encoder *encoder)
240{
241	struct drm_device *dev = encoder->dev;
242	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
243	struct drm_encoder *other_encoder;
244	struct radeon_encoder *other_radeon_encoder;
245
246	if (radeon_encoder->is_ext_encoder)
247		return NULL;
248
249	list_for_each_entry(other_encoder, &dev->mode_config.encoder_list, head) {
250		if (other_encoder == encoder)
251			continue;
252		other_radeon_encoder = to_radeon_encoder(other_encoder);
253		if (other_radeon_encoder->is_ext_encoder &&
254		    (radeon_encoder->devices & other_radeon_encoder->devices))
255			return other_encoder;
256	}
257	return NULL;
258}
259
260u16 radeon_encoder_get_dp_bridge_encoder_id(struct drm_encoder *encoder)
261{
262	struct drm_encoder *other_encoder = radeon_get_external_encoder(encoder);
263
264	if (other_encoder) {
265		struct radeon_encoder *radeon_encoder = to_radeon_encoder(other_encoder);
266
267		switch (radeon_encoder->encoder_id) {
268		case ENCODER_OBJECT_ID_TRAVIS:
269		case ENCODER_OBJECT_ID_NUTMEG:
270			return radeon_encoder->encoder_id;
271		default:
272			return ENCODER_OBJECT_ID_NONE;
273		}
274	}
275	return ENCODER_OBJECT_ID_NONE;
276}
277
278void radeon_panel_mode_fixup(struct drm_encoder *encoder,
279			     struct drm_display_mode *adjusted_mode)
280{
281	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
282	struct drm_device *dev = encoder->dev;
283	struct radeon_device *rdev = dev->dev_private;
284	struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
285	unsigned hblank = native_mode->htotal - native_mode->hdisplay;
286	unsigned vblank = native_mode->vtotal - native_mode->vdisplay;
287	unsigned hover = native_mode->hsync_start - native_mode->hdisplay;
288	unsigned vover = native_mode->vsync_start - native_mode->vdisplay;
289	unsigned hsync_width = native_mode->hsync_end - native_mode->hsync_start;
290	unsigned vsync_width = native_mode->vsync_end - native_mode->vsync_start;
291
292	adjusted_mode->clock = native_mode->clock;
293	adjusted_mode->flags = native_mode->flags;
294
295	if (ASIC_IS_AVIVO(rdev)) {
296		adjusted_mode->hdisplay = native_mode->hdisplay;
297		adjusted_mode->vdisplay = native_mode->vdisplay;
298	}
299
300	adjusted_mode->htotal = native_mode->hdisplay + hblank;
301	adjusted_mode->hsync_start = native_mode->hdisplay + hover;
302	adjusted_mode->hsync_end = adjusted_mode->hsync_start + hsync_width;
303
304	adjusted_mode->vtotal = native_mode->vdisplay + vblank;
305	adjusted_mode->vsync_start = native_mode->vdisplay + vover;
306	adjusted_mode->vsync_end = adjusted_mode->vsync_start + vsync_width;
307
308	drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
309
310	if (ASIC_IS_AVIVO(rdev)) {
311		adjusted_mode->crtc_hdisplay = native_mode->hdisplay;
312		adjusted_mode->crtc_vdisplay = native_mode->vdisplay;
313	}
314
315	adjusted_mode->crtc_htotal = adjusted_mode->crtc_hdisplay + hblank;
316	adjusted_mode->crtc_hsync_start = adjusted_mode->crtc_hdisplay + hover;
317	adjusted_mode->crtc_hsync_end = adjusted_mode->crtc_hsync_start + hsync_width;
318
319	adjusted_mode->crtc_vtotal = adjusted_mode->crtc_vdisplay + vblank;
320	adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + vover;
321	adjusted_mode->crtc_vsync_end = adjusted_mode->crtc_vsync_start + vsync_width;
322
323}
324
325bool radeon_dig_monitor_is_duallink(struct drm_encoder *encoder,
326				    u32 pixel_clock)
327{
328	struct drm_device *dev = encoder->dev;
329	struct radeon_device *rdev = dev->dev_private;
330	struct drm_connector *connector;
331	struct radeon_connector *radeon_connector;
332	struct radeon_connector_atom_dig *dig_connector;
333
334	connector = radeon_get_connector_for_encoder(encoder);
335	/* if we don't have an active device yet, just use one of
336	 * the connectors tied to the encoder.
337	 */
338	if (!connector)
339		connector = radeon_get_connector_for_encoder_init(encoder);
340	radeon_connector = to_radeon_connector(connector);
341
342	switch (connector->connector_type) {
343	case DRM_MODE_CONNECTOR_DVII:
344	case DRM_MODE_CONNECTOR_HDMIB:
345		if (radeon_connector->use_digital) {
346			/* HDMI 1.3 supports up to 340 Mhz over single link */
347			if (ASIC_IS_DCE6(rdev) && drm_detect_hdmi_monitor(radeon_connector->edid)) {
348				if (pixel_clock > 340000)
349					return true;
350				else
351					return false;
352			} else {
353				if (pixel_clock > 165000)
354					return true;
355				else
356					return false;
357			}
358		} else
359			return false;
360	case DRM_MODE_CONNECTOR_DVID:
361	case DRM_MODE_CONNECTOR_HDMIA:
362	case DRM_MODE_CONNECTOR_DisplayPort:
363		dig_connector = radeon_connector->con_priv;
364		if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
365		    (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP))
366			return false;
367		else {
368			/* HDMI 1.3 supports up to 340 Mhz over single link */
369			if (ASIC_IS_DCE6(rdev) && drm_detect_hdmi_monitor(radeon_connector->edid)) {
370				if (pixel_clock > 340000)
371					return true;
372				else
373					return false;
374			} else {
375				if (pixel_clock > 165000)
376					return true;
377				else
378					return false;
379			}
380		}
381	default:
382		return false;
383	}
384}
385
386