2 * Copyright 2007-8 Advanced Micro Devices, Inc.
3 * Copyright 2008 Red Hat Inc.
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:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
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.
23 * Authors: Dave Airlie
28 #include "drm_crtc_helper.h"
29 #include "radeon_drm.h"
33 radeon_combios_connected_scratch_regs(struct drm_connector
*connector
,
34 struct drm_encoder
*encoder
,
37 radeon_atombios_connected_scratch_regs(struct drm_connector
*connector
,
38 struct drm_encoder
*encoder
,
42 radeon_connector_update_scratch_regs(struct drm_connector
*connector
, enum drm_connector_status status
)
44 struct drm_device
*dev
= connector
->dev
;
45 struct radeon_device
*rdev
= dev
->dev_private
;
46 struct drm_encoder
*best_encoder
= NULL
;
47 struct drm_encoder
*encoder
= NULL
;
48 struct drm_connector_helper_funcs
*connector_funcs
= connector
->helper_private
;
49 struct drm_mode_object
*obj
;
53 best_encoder
= connector_funcs
->best_encoder(connector
);
55 for (i
= 0; i
< DRM_CONNECTOR_MAX_ENCODER
; i
++) {
56 if (connector
->encoder_ids
[i
] == 0)
59 obj
= drm_mode_object_find(connector
->dev
,
60 connector
->encoder_ids
[i
],
61 DRM_MODE_OBJECT_ENCODER
);
65 encoder
= obj_to_encoder(obj
);
67 if ((encoder
== best_encoder
) && (status
== connector_status_connected
))
72 if (rdev
->is_atom_bios
)
73 radeon_atombios_connected_scratch_regs(connector
, encoder
, connected
);
75 radeon_combios_connected_scratch_regs(connector
, encoder
, connected
);
80 struct drm_encoder
*radeon_best_single_encoder(struct drm_connector
*connector
)
82 int enc_id
= connector
->encoder_ids
[0];
83 struct drm_mode_object
*obj
;
84 struct drm_encoder
*encoder
;
86 /* pick the encoder ids */
88 obj
= drm_mode_object_find(connector
->dev
, enc_id
, DRM_MODE_OBJECT_ENCODER
);
91 encoder
= obj_to_encoder(obj
);
97 static struct drm_display_mode
*radeon_fp_native_mode(struct drm_encoder
*encoder
)
99 struct drm_device
*dev
= encoder
->dev
;
100 struct radeon_encoder
*radeon_encoder
= to_radeon_encoder(encoder
);
101 struct drm_display_mode
*mode
= NULL
;
102 struct radeon_native_mode
*native_mode
= &radeon_encoder
->native_mode
;
104 if (native_mode
->panel_xres
!= 0 &&
105 native_mode
->panel_yres
!= 0 &&
106 native_mode
->dotclock
!= 0) {
107 mode
= drm_mode_create(dev
);
109 mode
->hdisplay
= native_mode
->panel_xres
;
110 mode
->vdisplay
= native_mode
->panel_yres
;
112 mode
->htotal
= mode
->hdisplay
+ native_mode
->hblank
;
113 mode
->hsync_start
= mode
->hdisplay
+ native_mode
->hoverplus
;
114 mode
->hsync_end
= mode
->hsync_start
+ native_mode
->hsync_width
;
115 mode
->vtotal
= mode
->vdisplay
+ native_mode
->vblank
;
116 mode
->vsync_start
= mode
->vdisplay
+ native_mode
->voverplus
;
117 mode
->vsync_end
= mode
->vsync_start
+ native_mode
->vsync_width
;
118 mode
->clock
= native_mode
->dotclock
;
121 mode
->type
= DRM_MODE_TYPE_PREFERRED
| DRM_MODE_TYPE_DRIVER
;
122 drm_mode_set_name(mode
);
124 DRM_DEBUG("Adding native panel mode %s\n", mode
->name
);
129 int radeon_connector_set_property(struct drm_connector
*connector
, struct drm_property
*property
,
136 static int radeon_lvds_get_modes(struct drm_connector
*connector
)
138 struct radeon_connector
*radeon_connector
= to_radeon_connector(connector
);
139 struct drm_encoder
*encoder
;
141 struct drm_display_mode
*mode
;
143 if (radeon_connector
->ddc_bus
) {
144 ret
= radeon_ddc_get_modes(radeon_connector
);
150 encoder
= radeon_best_single_encoder(connector
);
154 /* we have no EDID modes */
155 mode
= radeon_fp_native_mode(encoder
);
158 drm_mode_probed_add(connector
, mode
);
163 static int radeon_lvds_mode_valid(struct drm_connector
*connector
,
164 struct drm_display_mode
*mode
)
169 static enum drm_connector_status
radeon_lvds_detect(struct drm_connector
*connector
)
171 enum drm_connector_status ret
= connector_status_connected
;
172 /* check acpi lid status ??? */
173 radeon_connector_update_scratch_regs(connector
, ret
);
177 static void radeon_connector_destroy(struct drm_connector
*connector
)
179 struct radeon_connector
*radeon_connector
= to_radeon_connector(connector
);
181 if (radeon_connector
->ddc_bus
)
182 radeon_i2c_destroy(radeon_connector
->ddc_bus
);
183 kfree(radeon_connector
->con_priv
);
184 drm_sysfs_connector_remove(connector
);
185 drm_connector_cleanup(connector
);
189 struct drm_connector_helper_funcs radeon_lvds_connector_helper_funcs
= {
190 .get_modes
= radeon_lvds_get_modes
,
191 .mode_valid
= radeon_lvds_mode_valid
,
192 .best_encoder
= radeon_best_single_encoder
,
195 struct drm_connector_funcs radeon_lvds_connector_funcs
= {
196 .dpms
= drm_helper_connector_dpms
,
197 .detect
= radeon_lvds_detect
,
198 .fill_modes
= drm_helper_probe_single_connector_modes
,
199 .destroy
= radeon_connector_destroy
,
200 .set_property
= radeon_connector_set_property
,
203 static int radeon_vga_get_modes(struct drm_connector
*connector
)
205 struct radeon_connector
*radeon_connector
= to_radeon_connector(connector
);
208 ret
= radeon_ddc_get_modes(radeon_connector
);
213 static int radeon_vga_mode_valid(struct drm_connector
*connector
,
214 struct drm_display_mode
*mode
)
220 static enum drm_connector_status
radeon_vga_detect(struct drm_connector
*connector
)
222 struct radeon_connector
*radeon_connector
= to_radeon_connector(connector
);
223 struct drm_encoder
*encoder
;
224 struct drm_encoder_helper_funcs
*encoder_funcs
;
226 enum drm_connector_status ret
= connector_status_disconnected
;
228 radeon_i2c_do_lock(radeon_connector
, 1);
229 dret
= radeon_ddc_probe(radeon_connector
);
230 radeon_i2c_do_lock(radeon_connector
, 0);
232 ret
= connector_status_connected
;
234 /* if EDID fails to a load detect */
235 encoder
= radeon_best_single_encoder(connector
);
237 ret
= connector_status_disconnected
;
239 encoder_funcs
= encoder
->helper_private
;
240 ret
= encoder_funcs
->detect(encoder
, connector
);
244 radeon_connector_update_scratch_regs(connector
, ret
);
248 struct drm_connector_helper_funcs radeon_vga_connector_helper_funcs
= {
249 .get_modes
= radeon_vga_get_modes
,
250 .mode_valid
= radeon_vga_mode_valid
,
251 .best_encoder
= radeon_best_single_encoder
,
254 struct drm_connector_funcs radeon_vga_connector_funcs
= {
255 .dpms
= drm_helper_connector_dpms
,
256 .detect
= radeon_vga_detect
,
257 .fill_modes
= drm_helper_probe_single_connector_modes
,
258 .destroy
= radeon_connector_destroy
,
259 .set_property
= radeon_connector_set_property
,
262 static int radeon_dvi_get_modes(struct drm_connector
*connector
)
264 struct radeon_connector
*radeon_connector
= to_radeon_connector(connector
);
267 ret
= radeon_ddc_get_modes(radeon_connector
);
268 /* reset scratch regs here since radeon_dvi_detect doesn't check digital bit */
269 radeon_connector_update_scratch_regs(connector
, connector_status_connected
);
273 static enum drm_connector_status
radeon_dvi_detect(struct drm_connector
*connector
)
275 struct radeon_connector
*radeon_connector
= to_radeon_connector(connector
);
276 struct drm_encoder
*encoder
;
277 struct drm_encoder_helper_funcs
*encoder_funcs
;
278 struct drm_mode_object
*obj
;
280 enum drm_connector_status ret
= connector_status_disconnected
;
283 radeon_i2c_do_lock(radeon_connector
, 1);
284 dret
= radeon_ddc_probe(radeon_connector
);
285 radeon_i2c_do_lock(radeon_connector
, 0);
287 ret
= connector_status_connected
;
289 for (i
= 0; i
< DRM_CONNECTOR_MAX_ENCODER
; i
++) {
290 if (connector
->encoder_ids
[i
] == 0)
293 obj
= drm_mode_object_find(connector
->dev
,
294 connector
->encoder_ids
[i
],
295 DRM_MODE_OBJECT_ENCODER
);
299 encoder
= obj_to_encoder(obj
);
301 encoder_funcs
= encoder
->helper_private
;
302 if (encoder_funcs
->detect
) {
303 ret
= encoder_funcs
->detect(encoder
, connector
);
304 if (ret
== connector_status_connected
) {
305 radeon_connector
->use_digital
= 0;
312 /* updated in get modes as well since we need to know if it's analog or digital */
313 radeon_connector_update_scratch_regs(connector
, ret
);
317 /* okay need to be smart in here about which encoder to pick */
318 struct drm_encoder
*radeon_dvi_encoder(struct drm_connector
*connector
)
320 int enc_id
= connector
->encoder_ids
[0];
321 struct radeon_connector
*radeon_connector
= to_radeon_connector(connector
);
322 struct drm_mode_object
*obj
;
323 struct drm_encoder
*encoder
;
325 for (i
= 0; i
< DRM_CONNECTOR_MAX_ENCODER
; i
++) {
326 if (connector
->encoder_ids
[i
] == 0)
329 obj
= drm_mode_object_find(connector
->dev
, connector
->encoder_ids
[i
], DRM_MODE_OBJECT_ENCODER
);
333 encoder
= obj_to_encoder(obj
);
335 if (radeon_connector
->use_digital
) {
336 if (encoder
->encoder_type
== DRM_MODE_ENCODER_TMDS
)
339 if (encoder
->encoder_type
== DRM_MODE_ENCODER_DAC
||
340 encoder
->encoder_type
== DRM_MODE_ENCODER_TVDAC
)
345 /* see if we have a default encoder TODO */
347 /* then check use digitial */
348 /* pick the first one */
350 obj
= drm_mode_object_find(connector
->dev
, enc_id
, DRM_MODE_OBJECT_ENCODER
);
353 encoder
= obj_to_encoder(obj
);
359 struct drm_connector_helper_funcs radeon_dvi_connector_helper_funcs
= {
360 .get_modes
= radeon_dvi_get_modes
,
361 .mode_valid
= radeon_vga_mode_valid
,
362 .best_encoder
= radeon_dvi_encoder
,
365 struct drm_connector_funcs radeon_dvi_connector_funcs
= {
366 .dpms
= drm_helper_connector_dpms
,
367 .detect
= radeon_dvi_detect
,
368 .fill_modes
= drm_helper_probe_single_connector_modes
,
369 .set_property
= radeon_connector_set_property
,
370 .destroy
= radeon_connector_destroy
,
374 radeon_add_atom_connector(struct drm_device
*dev
,
375 uint32_t connector_id
,
376 uint32_t supported_device
,
378 struct radeon_i2c_bus_rec
*i2c_bus
,
380 uint32_t igp_lane_info
)
382 struct drm_connector
*connector
;
383 struct radeon_connector
*radeon_connector
;
384 struct radeon_connector_atom_dig
*radeon_dig_connector
;
385 uint32_t subpixel_order
= SubPixelNone
;
387 /* fixme - tv/cv/din */
388 if ((connector_type
== DRM_MODE_CONNECTOR_Unknown
) ||
389 (connector_type
== DRM_MODE_CONNECTOR_SVIDEO
) ||
390 (connector_type
== DRM_MODE_CONNECTOR_Composite
) ||
391 (connector_type
== DRM_MODE_CONNECTOR_9PinDIN
))
394 /* see if we already added it */
395 list_for_each_entry(connector
, &dev
->mode_config
.connector_list
, head
) {
396 radeon_connector
= to_radeon_connector(connector
);
397 if (radeon_connector
->connector_id
== connector_id
) {
398 radeon_connector
->devices
|= supported_device
;
403 radeon_connector
= kzalloc(sizeof(struct radeon_connector
), GFP_KERNEL
);
404 if (!radeon_connector
)
407 connector
= &radeon_connector
->base
;
409 radeon_connector
->connector_id
= connector_id
;
410 radeon_connector
->devices
= supported_device
;
411 switch (connector_type
) {
412 case DRM_MODE_CONNECTOR_VGA
:
413 drm_connector_init(dev
, &radeon_connector
->base
, &radeon_vga_connector_funcs
, connector_type
);
414 drm_connector_helper_add(&radeon_connector
->base
, &radeon_vga_connector_helper_funcs
);
415 if (i2c_bus
->valid
) {
416 radeon_connector
->ddc_bus
= radeon_i2c_create(dev
, i2c_bus
, "VGA");
417 if (!radeon_connector
->ddc_bus
)
421 case DRM_MODE_CONNECTOR_DVIA
:
422 drm_connector_init(dev
, &radeon_connector
->base
, &radeon_vga_connector_funcs
, connector_type
);
423 drm_connector_helper_add(&radeon_connector
->base
, &radeon_vga_connector_helper_funcs
);
424 if (i2c_bus
->valid
) {
425 radeon_connector
->ddc_bus
= radeon_i2c_create(dev
, i2c_bus
, "DVI");
426 if (!radeon_connector
->ddc_bus
)
430 case DRM_MODE_CONNECTOR_DVII
:
431 case DRM_MODE_CONNECTOR_DVID
:
432 radeon_dig_connector
= kzalloc(sizeof(struct radeon_connector_atom_dig
), GFP_KERNEL
);
433 if (!radeon_dig_connector
)
435 radeon_dig_connector
->linkb
= linkb
;
436 radeon_dig_connector
->igp_lane_info
= igp_lane_info
;
437 radeon_connector
->con_priv
= radeon_dig_connector
;
438 drm_connector_init(dev
, &radeon_connector
->base
, &radeon_dvi_connector_funcs
, connector_type
);
439 drm_connector_helper_add(&radeon_connector
->base
, &radeon_dvi_connector_helper_funcs
);
440 if (i2c_bus
->valid
) {
441 radeon_connector
->ddc_bus
= radeon_i2c_create(dev
, i2c_bus
, "DVI");
442 if (!radeon_connector
->ddc_bus
)
445 subpixel_order
= SubPixelHorizontalRGB
;
447 case DRM_MODE_CONNECTOR_HDMIA
:
448 case DRM_MODE_CONNECTOR_HDMIB
:
449 radeon_dig_connector
= kzalloc(sizeof(struct radeon_connector_atom_dig
), GFP_KERNEL
);
450 if (!radeon_dig_connector
)
452 radeon_dig_connector
->linkb
= linkb
;
453 radeon_dig_connector
->igp_lane_info
= igp_lane_info
;
454 radeon_connector
->con_priv
= radeon_dig_connector
;
455 drm_connector_init(dev
, &radeon_connector
->base
, &radeon_dvi_connector_funcs
, connector_type
);
456 drm_connector_helper_add(&radeon_connector
->base
, &radeon_dvi_connector_helper_funcs
);
457 if (i2c_bus
->valid
) {
458 radeon_connector
->ddc_bus
= radeon_i2c_create(dev
, i2c_bus
, "HDMI");
459 if (!radeon_connector
->ddc_bus
)
462 subpixel_order
= SubPixelHorizontalRGB
;
464 case DRM_MODE_CONNECTOR_DisplayPort
:
465 radeon_dig_connector
= kzalloc(sizeof(struct radeon_connector_atom_dig
), GFP_KERNEL
);
466 if (!radeon_dig_connector
)
468 radeon_dig_connector
->linkb
= linkb
;
469 radeon_dig_connector
->igp_lane_info
= igp_lane_info
;
470 radeon_connector
->con_priv
= radeon_dig_connector
;
471 drm_connector_init(dev
, &radeon_connector
->base
, &radeon_dvi_connector_funcs
, connector_type
);
472 drm_connector_helper_add(&radeon_connector
->base
, &radeon_dvi_connector_helper_funcs
);
473 if (i2c_bus
->valid
) {
474 radeon_connector
->ddc_bus
= radeon_i2c_create(dev
, i2c_bus
, "DP");
475 if (!radeon_connector
->ddc_bus
)
478 subpixel_order
= SubPixelHorizontalRGB
;
480 case DRM_MODE_CONNECTOR_SVIDEO
:
481 case DRM_MODE_CONNECTOR_Composite
:
482 case DRM_MODE_CONNECTOR_9PinDIN
:
484 case DRM_MODE_CONNECTOR_LVDS
:
485 radeon_dig_connector
= kzalloc(sizeof(struct radeon_connector_atom_dig
), GFP_KERNEL
);
486 if (!radeon_dig_connector
)
488 radeon_dig_connector
->linkb
= linkb
;
489 radeon_dig_connector
->igp_lane_info
= igp_lane_info
;
490 radeon_connector
->con_priv
= radeon_dig_connector
;
491 drm_connector_init(dev
, &radeon_connector
->base
, &radeon_lvds_connector_funcs
, connector_type
);
492 drm_connector_helper_add(&radeon_connector
->base
, &radeon_lvds_connector_helper_funcs
);
493 if (i2c_bus
->valid
) {
494 radeon_connector
->ddc_bus
= radeon_i2c_create(dev
, i2c_bus
, "LVDS");
495 if (!radeon_connector
->ddc_bus
)
498 subpixel_order
= SubPixelHorizontalRGB
;
502 connector
->display_info
.subpixel_order
= subpixel_order
;
503 drm_sysfs_connector_add(connector
);
507 if (radeon_connector
->ddc_bus
)
508 radeon_i2c_destroy(radeon_connector
->ddc_bus
);
509 drm_connector_cleanup(connector
);
514 radeon_add_legacy_connector(struct drm_device
*dev
,
515 uint32_t connector_id
,
516 uint32_t supported_device
,
518 struct radeon_i2c_bus_rec
*i2c_bus
)
520 struct drm_connector
*connector
;
521 struct radeon_connector
*radeon_connector
;
522 uint32_t subpixel_order
= SubPixelNone
;
524 /* fixme - tv/cv/din */
525 if ((connector_type
== DRM_MODE_CONNECTOR_Unknown
) ||
526 (connector_type
== DRM_MODE_CONNECTOR_SVIDEO
) ||
527 (connector_type
== DRM_MODE_CONNECTOR_Composite
) ||
528 (connector_type
== DRM_MODE_CONNECTOR_9PinDIN
))
531 /* see if we already added it */
532 list_for_each_entry(connector
, &dev
->mode_config
.connector_list
, head
) {
533 radeon_connector
= to_radeon_connector(connector
);
534 if (radeon_connector
->connector_id
== connector_id
) {
535 radeon_connector
->devices
|= supported_device
;
540 radeon_connector
= kzalloc(sizeof(struct radeon_connector
), GFP_KERNEL
);
541 if (!radeon_connector
)
544 connector
= &radeon_connector
->base
;
546 radeon_connector
->connector_id
= connector_id
;
547 radeon_connector
->devices
= supported_device
;
548 switch (connector_type
) {
549 case DRM_MODE_CONNECTOR_VGA
:
550 drm_connector_init(dev
, &radeon_connector
->base
, &radeon_vga_connector_funcs
, connector_type
);
551 drm_connector_helper_add(&radeon_connector
->base
, &radeon_vga_connector_helper_funcs
);
552 if (i2c_bus
->valid
) {
553 radeon_connector
->ddc_bus
= radeon_i2c_create(dev
, i2c_bus
, "VGA");
554 if (!radeon_connector
->ddc_bus
)
558 case DRM_MODE_CONNECTOR_DVIA
:
559 drm_connector_init(dev
, &radeon_connector
->base
, &radeon_vga_connector_funcs
, connector_type
);
560 drm_connector_helper_add(&radeon_connector
->base
, &radeon_vga_connector_helper_funcs
);
561 if (i2c_bus
->valid
) {
562 radeon_connector
->ddc_bus
= radeon_i2c_create(dev
, i2c_bus
, "DVI");
563 if (!radeon_connector
->ddc_bus
)
567 case DRM_MODE_CONNECTOR_DVII
:
568 case DRM_MODE_CONNECTOR_DVID
:
569 drm_connector_init(dev
, &radeon_connector
->base
, &radeon_dvi_connector_funcs
, connector_type
);
570 drm_connector_helper_add(&radeon_connector
->base
, &radeon_dvi_connector_helper_funcs
);
571 if (i2c_bus
->valid
) {
572 radeon_connector
->ddc_bus
= radeon_i2c_create(dev
, i2c_bus
, "DVI");
573 if (!radeon_connector
->ddc_bus
)
576 subpixel_order
= SubPixelHorizontalRGB
;
578 case DRM_MODE_CONNECTOR_SVIDEO
:
579 case DRM_MODE_CONNECTOR_Composite
:
580 case DRM_MODE_CONNECTOR_9PinDIN
:
582 case DRM_MODE_CONNECTOR_LVDS
:
583 drm_connector_init(dev
, &radeon_connector
->base
, &radeon_lvds_connector_funcs
, connector_type
);
584 drm_connector_helper_add(&radeon_connector
->base
, &radeon_lvds_connector_helper_funcs
);
585 if (i2c_bus
->valid
) {
586 radeon_connector
->ddc_bus
= radeon_i2c_create(dev
, i2c_bus
, "LVDS");
587 if (!radeon_connector
->ddc_bus
)
590 subpixel_order
= SubPixelHorizontalRGB
;
594 connector
->display_info
.subpixel_order
= subpixel_order
;
595 drm_sysfs_connector_add(connector
);
599 if (radeon_connector
->ddc_bus
)
600 radeon_i2c_destroy(radeon_connector
->ddc_bus
);
601 drm_connector_cleanup(connector
);