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