aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2009-09-09 03:40:54 -0400
committerDave Airlie <airlied@redhat.com>2009-09-18 02:02:00 -0400
commit445282db9e815e7f5e82761c3c971dc9ea988d85 (patch)
treee40e85ded303f2688b8adc1f5695b0062669a93a /drivers/gpu
parentc88f9f0c91de55efaece6d9bd9ec920b90244776 (diff)
drm/radeon/kms: add initial connector properties
This adds: coherent mode: TMDS coherent mode for atom cards. scaling mode: LVDS scaler mode load detect: DAC load detection, DVI-I, VGA, TV tmds pll: legacy TMDS pll selection tv standard: TV standard selection. for later: other TV ones? dvi subconnector selection using std prop [contains fixes pointed out on dri-devel for atom bios mixups by Michel] Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/radeon/radeon_atombios.c15
-rw-r--r--drivers/gpu/drm/radeon/radeon_combios.c46
-rw-r--r--drivers/gpu/drm/radeon/radeon_connectors.c237
-rw-r--r--drivers/gpu/drm/radeon/radeon_display.c81
-rw-r--r--drivers/gpu/drm/radeon/radeon_encoders.c10
-rw-r--r--drivers/gpu/drm/radeon/radeon_legacy_encoders.c29
-rw-r--r--drivers/gpu/drm/radeon/radeon_mode.h20
7 files changed, 376 insertions, 62 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c
index cb5efcaf2bab..743742128307 100644
--- a/drivers/gpu/drm/radeon/radeon_atombios.c
+++ b/drivers/gpu/drm/radeon/radeon_atombios.c
@@ -719,9 +719,8 @@ bool radeon_atom_get_clock_info(struct drm_device *dev)
719 return false; 719 return false;
720} 720}
721 721
722struct radeon_encoder_int_tmds *radeon_atombios_get_tmds_info(struct 722bool radeon_atombios_get_tmds_info(struct radeon_encoder *encoder,
723 radeon_encoder 723 struct radeon_encoder_int_tmds *tmds)
724 *encoder)
725{ 724{
726 struct drm_device *dev = encoder->base.dev; 725 struct drm_device *dev = encoder->base.dev;
727 struct radeon_device *rdev = dev->dev_private; 726 struct radeon_device *rdev = dev->dev_private;
@@ -732,7 +731,6 @@ struct radeon_encoder_int_tmds *radeon_atombios_get_tmds_info(struct
732 uint8_t frev, crev; 731 uint8_t frev, crev;
733 uint16_t maxfreq; 732 uint16_t maxfreq;
734 int i; 733 int i;
735 struct radeon_encoder_int_tmds *tmds = NULL;
736 734
737 atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, 735 atom_parse_data_header(mode_info->atom_context, index, NULL, &frev,
738 &crev, &data_offset); 736 &crev, &data_offset);
@@ -742,12 +740,6 @@ struct radeon_encoder_int_tmds *radeon_atombios_get_tmds_info(struct
742 data_offset); 740 data_offset);
743 741
744 if (tmds_info) { 742 if (tmds_info) {
745 tmds =
746 kzalloc(sizeof(struct radeon_encoder_int_tmds), GFP_KERNEL);
747
748 if (!tmds)
749 return NULL;
750
751 maxfreq = le16_to_cpu(tmds_info->usMaxFrequency); 743 maxfreq = le16_to_cpu(tmds_info->usMaxFrequency);
752 for (i = 0; i < 4; i++) { 744 for (i = 0; i < 4; i++) {
753 tmds->tmds_pll[i].freq = 745 tmds->tmds_pll[i].freq =
@@ -773,8 +765,9 @@ struct radeon_encoder_int_tmds *radeon_atombios_get_tmds_info(struct
773 break; 765 break;
774 } 766 }
775 } 767 }
768 return true;
776 } 769 }
777 return tmds; 770 return false;
778} 771}
779 772
780union lvds_info { 773union lvds_info {
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c
index cb60f5532334..748265a105b3 100644
--- a/drivers/gpu/drm/radeon/radeon_combios.c
+++ b/drivers/gpu/drm/radeon/radeon_combios.c
@@ -998,48 +998,37 @@ static const struct radeon_tmds_pll default_tmds_pll[CHIP_LAST][4] = {
998 {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}}, /* CHIP_RS480 */ 998 {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}}, /* CHIP_RS480 */
999}; 999};
1000 1000
1001static struct radeon_encoder_int_tmds 1001bool radeon_legacy_get_tmds_info_from_table(struct radeon_encoder *encoder,
1002 *radeon_legacy_get_tmds_info_from_table(struct radeon_device *rdev) 1002 struct radeon_encoder_int_tmds *tmds)
1003{ 1003{
1004 struct drm_device *dev = encoder->base.dev;
1005 struct radeon_device *rdev = dev->dev_private;
1004 int i; 1006 int i;
1005 struct radeon_encoder_int_tmds *tmds = NULL;
1006
1007 tmds = kzalloc(sizeof(struct radeon_encoder_int_tmds), GFP_KERNEL);
1008
1009 if (!tmds)
1010 return NULL;
1011 1007
1012 for (i = 0; i < 4; i++) { 1008 for (i = 0; i < 4; i++) {
1013 tmds->tmds_pll[i].value = 1009 tmds->tmds_pll[i].value =
1014 default_tmds_pll[rdev->family][i].value; 1010 default_tmds_pll[rdev->family][i].value;
1015 tmds->tmds_pll[i].freq = default_tmds_pll[rdev->family][i].freq; 1011 tmds->tmds_pll[i].freq = default_tmds_pll[rdev->family][i].freq;
1016 } 1012 }
1017 1013
1018 return tmds; 1014 return true;
1019} 1015}
1020 1016
1021struct radeon_encoder_int_tmds *radeon_combios_get_tmds_info(struct 1017bool radeon_legacy_get_tmds_info_from_combios(struct radeon_encoder *encoder,
1022 radeon_encoder 1018 struct radeon_encoder_int_tmds *tmds)
1023 *encoder)
1024{ 1019{
1025 struct drm_device *dev = encoder->base.dev; 1020 struct drm_device *dev = encoder->base.dev;
1026 struct radeon_device *rdev = dev->dev_private; 1021 struct radeon_device *rdev = dev->dev_private;
1027 uint16_t tmds_info; 1022 uint16_t tmds_info;
1028 int i, n; 1023 int i, n;
1029 uint8_t ver; 1024 uint8_t ver;
1030 struct radeon_encoder_int_tmds *tmds = NULL;
1031 1025
1032 if (rdev->bios == NULL) 1026 if (rdev->bios == NULL)
1033 return radeon_legacy_get_tmds_info_from_table(rdev); 1027 return false;
1034 1028
1035 tmds_info = combios_get_table_offset(dev, COMBIOS_DFP_INFO_TABLE); 1029 tmds_info = combios_get_table_offset(dev, COMBIOS_DFP_INFO_TABLE);
1036 1030
1037 if (tmds_info) { 1031 if (tmds_info) {
1038 tmds =
1039 kzalloc(sizeof(struct radeon_encoder_int_tmds), GFP_KERNEL);
1040
1041 if (!tmds)
1042 return NULL;
1043 1032
1044 ver = RBIOS8(tmds_info); 1033 ver = RBIOS8(tmds_info);
1045 DRM_INFO("DFP table revision: %d\n", ver); 1034 DRM_INFO("DFP table revision: %d\n", ver);
@@ -1077,6 +1066,23 @@ struct radeon_encoder_int_tmds *radeon_combios_get_tmds_info(struct
1077 } 1066 }
1078 } else 1067 } else
1079 DRM_INFO("No TMDS info found in BIOS\n"); 1068 DRM_INFO("No TMDS info found in BIOS\n");
1069 return true;
1070}
1071
1072struct radeon_encoder_int_tmds *radeon_combios_get_tmds_info(struct radeon_encoder *encoder)
1073{
1074 struct radeon_encoder_int_tmds *tmds = NULL;
1075 bool ret;
1076
1077 tmds = kzalloc(sizeof(struct radeon_encoder_int_tmds), GFP_KERNEL);
1078
1079 if (!tmds)
1080 return NULL;
1081
1082 ret = radeon_legacy_get_tmds_info_from_combios(encoder, tmds);
1083 if (ret == false)
1084 radeon_legacy_get_tmds_info_from_table(encoder, tmds);
1085
1080 return tmds; 1086 return tmds;
1081} 1087}
1082 1088
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
index 5ee81b6a8799..af1d551f1a8f 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -39,6 +39,15 @@ radeon_atombios_connected_scratch_regs(struct drm_connector *connector,
39 struct drm_encoder *encoder, 39 struct drm_encoder *encoder,
40 bool connected); 40 bool connected);
41 41
42static void radeon_property_change_mode(struct drm_encoder *encoder)
43{
44 struct drm_crtc *crtc = encoder->crtc;
45
46 if (crtc && crtc->enabled) {
47 drm_crtc_helper_set_mode(crtc, &crtc->mode,
48 crtc->x, crtc->y, crtc->fb);
49 }
50}
42static void 51static void
43radeon_connector_update_scratch_regs(struct drm_connector *connector, enum drm_connector_status status) 52radeon_connector_update_scratch_regs(struct drm_connector *connector, enum drm_connector_status status)
44{ 53{
@@ -78,6 +87,27 @@ radeon_connector_update_scratch_regs(struct drm_connector *connector, enum drm_c
78 } 87 }
79} 88}
80 89
90struct drm_encoder *radeon_find_encoder(struct drm_connector *connector, int encoder_type)
91{
92 struct drm_mode_object *obj;
93 struct drm_encoder *encoder;
94 int i;
95
96 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
97 if (connector->encoder_ids[i] == 0)
98 break;
99
100 obj = drm_mode_object_find(connector->dev, connector->encoder_ids[i], DRM_MODE_OBJECT_ENCODER);
101 if (!obj)
102 continue;
103
104 encoder = obj_to_encoder(obj);
105 if (encoder->encoder_type == encoder_type)
106 return encoder;
107 }
108 return NULL;
109}
110
81struct drm_encoder *radeon_best_single_encoder(struct drm_connector *connector) 111struct drm_encoder *radeon_best_single_encoder(struct drm_connector *connector)
82{ 112{
83 int enc_id = connector->encoder_ids[0]; 113 int enc_id = connector->encoder_ids[0];
@@ -95,7 +125,6 @@ struct drm_encoder *radeon_best_single_encoder(struct drm_connector *connector)
95 return NULL; 125 return NULL;
96} 126}
97 127
98
99/* 128/*
100 * radeon_connector_analog_encoder_conflict_solve 129 * radeon_connector_analog_encoder_conflict_solve
101 * - search for other connectors sharing this encoder 130 * - search for other connectors sharing this encoder
@@ -224,6 +253,89 @@ static void radeon_add_common_modes(struct drm_encoder *encoder, struct drm_conn
224int radeon_connector_set_property(struct drm_connector *connector, struct drm_property *property, 253int radeon_connector_set_property(struct drm_connector *connector, struct drm_property *property,
225 uint64_t val) 254 uint64_t val)
226{ 255{
256 struct drm_device *dev = connector->dev;
257 struct radeon_device *rdev = dev->dev_private;
258 struct drm_encoder *encoder;
259 struct radeon_encoder *radeon_encoder;
260
261 if (property == rdev->mode_info.coherent_mode_property) {
262 struct radeon_encoder_atom_dig *dig;
263
264 /* need to find digital encoder on connector */
265 encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS);
266 if (!encoder)
267 return 0;
268
269 radeon_encoder = to_radeon_encoder(encoder);
270
271 if (!radeon_encoder->enc_priv)
272 return 0;
273
274 dig = radeon_encoder->enc_priv;
275 dig->coherent_mode = val ? true : false;
276 radeon_property_change_mode(&radeon_encoder->base);
277 }
278
279 if (property == rdev->mode_info.tv_std_property) {
280 encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TVDAC);
281 if (!encoder) {
282 encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_DAC);
283 }
284
285 if (!encoder)
286 return 0;
287
288 radeon_encoder = to_radeon_encoder(encoder);
289 if (!radeon_encoder->enc_priv)
290 return 0;
291 if (rdev->is_atom_bios) {
292 struct radeon_encoder_atom_dac *dac_int;
293 dac_int = radeon_encoder->enc_priv;
294 dac_int->tv_std = val;
295 } else {
296 struct radeon_encoder_tv_dac *dac_int;
297 dac_int = radeon_encoder->enc_priv;
298 dac_int->tv_std = val;
299 }
300 radeon_property_change_mode(&radeon_encoder->base);
301 }
302
303 if (property == rdev->mode_info.load_detect_property) {
304 struct radeon_connector *radeon_connector =
305 to_radeon_connector(connector);
306
307 if (val == 0)
308 radeon_connector->dac_load_detect = false;
309 else
310 radeon_connector->dac_load_detect = true;
311 }
312
313 if (property == rdev->mode_info.tmds_pll_property) {
314 struct radeon_encoder_int_tmds *tmds = NULL;
315 bool ret = false;
316 /* need to find digital encoder on connector */
317 encoder = radeon_find_encoder(connector, DRM_MODE_ENCODER_TMDS);
318 if (!encoder)
319 return 0;
320
321 radeon_encoder = to_radeon_encoder(encoder);
322
323 tmds = radeon_encoder->enc_priv;
324 if (!tmds)
325 return 0;
326
327 if (val == 0) {
328 if (rdev->is_atom_bios)
329 ret = radeon_atombios_get_tmds_info(radeon_encoder, tmds);
330 else
331 ret = radeon_legacy_get_tmds_info_from_combios(radeon_encoder, tmds);
332 }
333 if (val == 1 || ret == false) {
334 radeon_legacy_get_tmds_info_from_table(radeon_encoder, tmds);
335 }
336 radeon_property_change_mode(&radeon_encoder->base);
337 }
338
227 return 0; 339 return 0;
228} 340}
229 341
@@ -320,6 +432,42 @@ static void radeon_connector_destroy(struct drm_connector *connector)
320 kfree(connector); 432 kfree(connector);
321} 433}
322 434
435static int radeon_lvds_set_property(struct drm_connector *connector,
436 struct drm_property *property,
437 uint64_t value)
438{
439 struct drm_device *dev = connector->dev;
440 struct radeon_encoder *radeon_encoder;
441 enum radeon_rmx_type rmx_type;
442
443 DRM_DEBUG("\n");
444 if (property != dev->mode_config.scaling_mode_property)
445 return 0;
446
447 if (connector->encoder)
448 radeon_encoder = to_radeon_encoder(connector->encoder);
449 else {
450 struct drm_connector_helper_funcs *connector_funcs = connector->helper_private;
451 radeon_encoder = to_radeon_encoder(connector_funcs->best_encoder(connector));
452 }
453
454 switch (value) {
455 case DRM_MODE_SCALE_NONE: rmx_type = RMX_OFF; break;
456 case DRM_MODE_SCALE_CENTER: rmx_type = RMX_CENTER; break;
457 case DRM_MODE_SCALE_ASPECT: rmx_type = RMX_ASPECT; break;
458 default:
459 case DRM_MODE_SCALE_FULLSCREEN: rmx_type = RMX_FULL; break;
460 }
461 if (radeon_encoder->rmx_type == rmx_type)
462 return 0;
463
464 radeon_encoder->rmx_type = rmx_type;
465
466 radeon_property_change_mode(&radeon_encoder->base);
467 return 0;
468}
469
470
323struct drm_connector_helper_funcs radeon_lvds_connector_helper_funcs = { 471struct drm_connector_helper_funcs radeon_lvds_connector_helper_funcs = {
324 .get_modes = radeon_lvds_get_modes, 472 .get_modes = radeon_lvds_get_modes,
325 .mode_valid = radeon_lvds_mode_valid, 473 .mode_valid = radeon_lvds_mode_valid,
@@ -331,7 +479,7 @@ struct drm_connector_funcs radeon_lvds_connector_funcs = {
331 .detect = radeon_lvds_detect, 479 .detect = radeon_lvds_detect,
332 .fill_modes = drm_helper_probe_single_connector_modes, 480 .fill_modes = drm_helper_probe_single_connector_modes,
333 .destroy = radeon_connector_destroy, 481 .destroy = radeon_connector_destroy,
334 .set_property = radeon_connector_set_property, 482 .set_property = radeon_lvds_set_property,
335}; 483};
336 484
337static int radeon_vga_get_modes(struct drm_connector *connector) 485static int radeon_vga_get_modes(struct drm_connector *connector)
@@ -368,8 +516,10 @@ static enum drm_connector_status radeon_vga_detect(struct drm_connector *connect
368 if (dret) 516 if (dret)
369 ret = connector_status_connected; 517 ret = connector_status_connected;
370 else { 518 else {
371 encoder_funcs = encoder->helper_private; 519 if (radeon_connector->dac_load_detect) {
372 ret = encoder_funcs->detect(encoder, connector); 520 encoder_funcs = encoder->helper_private;
521 ret = encoder_funcs->detect(encoder, connector);
522 }
373 } 523 }
374 524
375 if (ret == connector_status_connected) 525 if (ret == connector_status_connected)
@@ -426,7 +576,11 @@ static enum drm_connector_status radeon_tv_detect(struct drm_connector *connecto
426{ 576{
427 struct drm_encoder *encoder; 577 struct drm_encoder *encoder;
428 struct drm_encoder_helper_funcs *encoder_funcs; 578 struct drm_encoder_helper_funcs *encoder_funcs;
429 int ret; 579 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
580 enum drm_connector_status ret = connector_status_disconnected;
581
582 if (!radeon_connector->dac_load_detect)
583 return ret;
430 584
431 encoder = radeon_best_single_encoder(connector); 585 encoder = radeon_best_single_encoder(connector);
432 if (!encoder) 586 if (!encoder)
@@ -510,27 +664,29 @@ static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connect
510 goto out; 664 goto out;
511 665
512 /* find analog encoder */ 666 /* find analog encoder */
513 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { 667 if (radeon_connector->dac_load_detect) {
514 if (connector->encoder_ids[i] == 0) 668 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
515 break; 669 if (connector->encoder_ids[i] == 0)
670 break;
516 671
517 obj = drm_mode_object_find(connector->dev, 672 obj = drm_mode_object_find(connector->dev,
518 connector->encoder_ids[i], 673 connector->encoder_ids[i],
519 DRM_MODE_OBJECT_ENCODER); 674 DRM_MODE_OBJECT_ENCODER);
520 if (!obj) 675 if (!obj)
521 continue; 676 continue;
522 677
523 encoder = obj_to_encoder(obj); 678 encoder = obj_to_encoder(obj);
524 679
525 encoder_funcs = encoder->helper_private; 680 encoder_funcs = encoder->helper_private;
526 if (encoder_funcs->detect) { 681 if (encoder_funcs->detect) {
527 if (ret != connector_status_connected) { 682 if (ret != connector_status_connected) {
528 ret = encoder_funcs->detect(encoder, connector); 683 ret = encoder_funcs->detect(encoder, connector);
529 if (ret == connector_status_connected) { 684 if (ret == connector_status_connected) {
530 radeon_connector->use_digital = false; 685 radeon_connector->use_digital = false;
686 }
531 } 687 }
688 break;
532 } 689 }
533 break;
534 } 690 }
535 } 691 }
536 692
@@ -610,6 +766,7 @@ radeon_add_atom_connector(struct drm_device *dev,
610 bool linkb, 766 bool linkb,
611 uint32_t igp_lane_info) 767 uint32_t igp_lane_info)
612{ 768{
769 struct radeon_device *rdev = dev->dev_private;
613 struct drm_connector *connector; 770 struct drm_connector *connector;
614 struct radeon_connector *radeon_connector; 771 struct radeon_connector *radeon_connector;
615 struct radeon_connector_atom_dig *radeon_dig_connector; 772 struct radeon_connector_atom_dig *radeon_dig_connector;
@@ -645,6 +802,9 @@ radeon_add_atom_connector(struct drm_device *dev,
645 if (!radeon_connector->ddc_bus) 802 if (!radeon_connector->ddc_bus)
646 goto failed; 803 goto failed;
647 } 804 }
805 drm_connector_attach_property(&radeon_connector->base,
806 rdev->mode_info.load_detect_property,
807 1);
648 break; 808 break;
649 case DRM_MODE_CONNECTOR_DVIA: 809 case DRM_MODE_CONNECTOR_DVIA:
650 drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); 810 drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
@@ -654,6 +814,9 @@ radeon_add_atom_connector(struct drm_device *dev,
654 if (!radeon_connector->ddc_bus) 814 if (!radeon_connector->ddc_bus)
655 goto failed; 815 goto failed;
656 } 816 }
817 drm_connector_attach_property(&radeon_connector->base,
818 rdev->mode_info.load_detect_property,
819 1);
657 break; 820 break;
658 case DRM_MODE_CONNECTOR_DVII: 821 case DRM_MODE_CONNECTOR_DVII:
659 case DRM_MODE_CONNECTOR_DVID: 822 case DRM_MODE_CONNECTOR_DVID:
@@ -671,6 +834,12 @@ radeon_add_atom_connector(struct drm_device *dev,
671 goto failed; 834 goto failed;
672 } 835 }
673 subpixel_order = SubPixelHorizontalRGB; 836 subpixel_order = SubPixelHorizontalRGB;
837 drm_connector_attach_property(&radeon_connector->base,
838 rdev->mode_info.coherent_mode_property,
839 1);
840 drm_connector_attach_property(&radeon_connector->base,
841 rdev->mode_info.load_detect_property,
842 1);
674 break; 843 break;
675 case DRM_MODE_CONNECTOR_HDMIA: 844 case DRM_MODE_CONNECTOR_HDMIA:
676 case DRM_MODE_CONNECTOR_HDMIB: 845 case DRM_MODE_CONNECTOR_HDMIB:
@@ -687,6 +856,9 @@ radeon_add_atom_connector(struct drm_device *dev,
687 if (!radeon_connector->ddc_bus) 856 if (!radeon_connector->ddc_bus)
688 goto failed; 857 goto failed;
689 } 858 }
859 drm_connector_attach_property(&radeon_connector->base,
860 rdev->mode_info.coherent_mode_property,
861 1);
690 subpixel_order = SubPixelHorizontalRGB; 862 subpixel_order = SubPixelHorizontalRGB;
691 break; 863 break;
692 case DRM_MODE_CONNECTOR_DisplayPort: 864 case DRM_MODE_CONNECTOR_DisplayPort:
@@ -712,6 +884,9 @@ radeon_add_atom_connector(struct drm_device *dev,
712 drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type); 884 drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type);
713 drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs); 885 drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs);
714 } 886 }
887 drm_connector_attach_property(&radeon_connector->base,
888 rdev->mode_info.load_detect_property,
889 1);
715 break; 890 break;
716 case DRM_MODE_CONNECTOR_LVDS: 891 case DRM_MODE_CONNECTOR_LVDS:
717 radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); 892 radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL);
@@ -727,6 +902,10 @@ radeon_add_atom_connector(struct drm_device *dev,
727 if (!radeon_connector->ddc_bus) 902 if (!radeon_connector->ddc_bus)
728 goto failed; 903 goto failed;
729 } 904 }
905 drm_mode_create_scaling_mode_property(dev);
906 drm_connector_attach_property(&radeon_connector->base,
907 dev->mode_config.scaling_mode_property,
908 DRM_MODE_SCALE_FULLSCREEN);
730 subpixel_order = SubPixelHorizontalRGB; 909 subpixel_order = SubPixelHorizontalRGB;
731 break; 910 break;
732 } 911 }
@@ -749,6 +928,7 @@ radeon_add_legacy_connector(struct drm_device *dev,
749 int connector_type, 928 int connector_type,
750 struct radeon_i2c_bus_rec *i2c_bus) 929 struct radeon_i2c_bus_rec *i2c_bus)
751{ 930{
931 struct radeon_device *rdev = dev->dev_private;
752 struct drm_connector *connector; 932 struct drm_connector *connector;
753 struct radeon_connector *radeon_connector; 933 struct radeon_connector *radeon_connector;
754 uint32_t subpixel_order = SubPixelNone; 934 uint32_t subpixel_order = SubPixelNone;
@@ -783,6 +963,9 @@ radeon_add_legacy_connector(struct drm_device *dev,
783 if (!radeon_connector->ddc_bus) 963 if (!radeon_connector->ddc_bus)
784 goto failed; 964 goto failed;
785 } 965 }
966 drm_connector_attach_property(&radeon_connector->base,
967 rdev->mode_info.load_detect_property,
968 1);
786 break; 969 break;
787 case DRM_MODE_CONNECTOR_DVIA: 970 case DRM_MODE_CONNECTOR_DVIA:
788 drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); 971 drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
@@ -792,6 +975,9 @@ radeon_add_legacy_connector(struct drm_device *dev,
792 if (!radeon_connector->ddc_bus) 975 if (!radeon_connector->ddc_bus)
793 goto failed; 976 goto failed;
794 } 977 }
978 drm_connector_attach_property(&radeon_connector->base,
979 rdev->mode_info.load_detect_property,
980 1);
795 break; 981 break;
796 case DRM_MODE_CONNECTOR_DVII: 982 case DRM_MODE_CONNECTOR_DVII:
797 case DRM_MODE_CONNECTOR_DVID: 983 case DRM_MODE_CONNECTOR_DVID:
@@ -801,6 +987,9 @@ radeon_add_legacy_connector(struct drm_device *dev,
801 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI"); 987 radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI");
802 if (!radeon_connector->ddc_bus) 988 if (!radeon_connector->ddc_bus)
803 goto failed; 989 goto failed;
990 drm_connector_attach_property(&radeon_connector->base,
991 rdev->mode_info.load_detect_property,
992 1);
804 } 993 }
805 subpixel_order = SubPixelHorizontalRGB; 994 subpixel_order = SubPixelHorizontalRGB;
806 break; 995 break;
@@ -810,6 +999,9 @@ radeon_add_legacy_connector(struct drm_device *dev,
810 if (radeon_tv == 1) { 999 if (radeon_tv == 1) {
811 drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type); 1000 drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type);
812 drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs); 1001 drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs);
1002 drm_connector_attach_property(&radeon_connector->base,
1003 rdev->mode_info.load_detect_property,
1004 1);
813 } 1005 }
814 break; 1006 break;
815 case DRM_MODE_CONNECTOR_LVDS: 1007 case DRM_MODE_CONNECTOR_LVDS:
@@ -820,6 +1012,9 @@ radeon_add_legacy_connector(struct drm_device *dev,
820 if (!radeon_connector->ddc_bus) 1012 if (!radeon_connector->ddc_bus)
821 goto failed; 1013 goto failed;
822 } 1014 }
1015 drm_connector_attach_property(&radeon_connector->base,
1016 dev->mode_config.scaling_mode_property,
1017 DRM_MODE_SCALE_FULLSCREEN);
823 subpixel_order = SubPixelHorizontalRGB; 1018 subpixel_order = SubPixelHorizontalRGB;
824 break; 1019 break;
825 } 1020 }
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index 22da85fe5ae7..5d8141b13765 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -623,6 +623,83 @@ static const struct drm_mode_config_funcs radeon_mode_funcs = {
623 .fb_changed = radeonfb_probe, 623 .fb_changed = radeonfb_probe,
624}; 624};
625 625
626struct drm_prop_enum_list {
627 int type;
628 char *name;
629};
630
631static struct drm_prop_enum_list radeon_tmds_pll_enum_list[] =
632{ { 0, "driver" },
633 { 1, "bios" },
634};
635
636static struct drm_prop_enum_list radeon_tv_std_enum_list[] =
637{ { TV_STD_NTSC, "ntsc" },
638 { TV_STD_PAL, "pal" },
639 { TV_STD_PAL_M, "pal-m" },
640 { TV_STD_PAL_60, "pal-60" },
641 { TV_STD_NTSC_J, "ntsc-j" },
642 { TV_STD_SCART_PAL, "scart-pal" },
643 { TV_STD_PAL_CN, "pal-cn" },
644 { TV_STD_SECAM, "secam" },
645};
646
647int radeon_modeset_create_props(struct radeon_device *rdev)
648{
649 int i, sz;
650
651 if (rdev->is_atom_bios) {
652 rdev->mode_info.coherent_mode_property =
653 drm_property_create(rdev->ddev,
654 DRM_MODE_PROP_RANGE,
655 "coherent", 2);
656 if (!rdev->mode_info.coherent_mode_property)
657 return -ENOMEM;
658
659 rdev->mode_info.coherent_mode_property->values[0] = 0;
660 rdev->mode_info.coherent_mode_property->values[0] = 1;
661 }
662
663 if (!ASIC_IS_AVIVO(rdev)) {
664 sz = ARRAY_SIZE(radeon_tmds_pll_enum_list);
665 rdev->mode_info.tmds_pll_property =
666 drm_property_create(rdev->ddev,
667 DRM_MODE_PROP_ENUM,
668 "tmds_pll", sz);
669 for (i = 0; i < sz; i++) {
670 drm_property_add_enum(rdev->mode_info.tmds_pll_property,
671 i,
672 radeon_tmds_pll_enum_list[i].type,
673 radeon_tmds_pll_enum_list[i].name);
674 }
675 }
676
677 rdev->mode_info.load_detect_property =
678 drm_property_create(rdev->ddev,
679 DRM_MODE_PROP_RANGE,
680 "load detection", 2);
681 if (!rdev->mode_info.load_detect_property)
682 return -ENOMEM;
683 rdev->mode_info.load_detect_property->values[0] = 0;
684 rdev->mode_info.load_detect_property->values[0] = 1;
685
686 drm_mode_create_scaling_mode_property(rdev->ddev);
687
688 sz = ARRAY_SIZE(radeon_tv_std_enum_list);
689 rdev->mode_info.tv_std_property =
690 drm_property_create(rdev->ddev,
691 DRM_MODE_PROP_ENUM,
692 "tv standard", sz);
693 for (i = 0; i < sz; i++) {
694 drm_property_add_enum(rdev->mode_info.tv_std_property,
695 i,
696 radeon_tv_std_enum_list[i].type,
697 radeon_tv_std_enum_list[i].name);
698 }
699
700 return 0;
701}
702
626int radeon_modeset_init(struct radeon_device *rdev) 703int radeon_modeset_init(struct radeon_device *rdev)
627{ 704{
628 int num_crtc = 2, i; 705 int num_crtc = 2, i;
@@ -643,6 +720,10 @@ int radeon_modeset_init(struct radeon_device *rdev)
643 720
644 rdev->ddev->mode_config.fb_base = rdev->mc.aper_base; 721 rdev->ddev->mode_config.fb_base = rdev->mc.aper_base;
645 722
723 ret = radeon_modeset_create_props(rdev);
724 if (ret) {
725 return ret;
726 }
646 /* allocate crtcs - TODO single crtc */ 727 /* allocate crtcs - TODO single crtc */
647 for (i = 0; i < num_crtc; i++) { 728 for (i = 0; i < num_crtc; i++) {
648 radeon_crtc_init(rdev->ddev, i); 729 radeon_crtc_init(rdev->ddev, i);
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c
index e274bb13866e..621646752cd2 100644
--- a/drivers/gpu/drm/radeon/radeon_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_encoders.c
@@ -241,9 +241,12 @@ atombios_dac_setup(struct drm_encoder *encoder, int action)
241 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 241 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
242 DAC_ENCODER_CONTROL_PS_ALLOCATION args; 242 DAC_ENCODER_CONTROL_PS_ALLOCATION args;
243 int index = 0, num = 0; 243 int index = 0, num = 0;
244 /* fixme - fill in enc_priv for atom dac */ 244 struct radeon_encoder_atom_dac *dac_info = radeon_encoder->enc_priv;
245 enum radeon_tv_std tv_std = TV_STD_NTSC; 245 enum radeon_tv_std tv_std = TV_STD_NTSC;
246 246
247 if (dac_info->tv_std)
248 tv_std = dac_info->tv_std;
249
247 memset(&args, 0, sizeof(args)); 250 memset(&args, 0, sizeof(args));
248 251
249 switch (radeon_encoder->encoder_id) { 252 switch (radeon_encoder->encoder_id) {
@@ -296,9 +299,12 @@ atombios_tv_setup(struct drm_encoder *encoder, int action)
296 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 299 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
297 TV_ENCODER_CONTROL_PS_ALLOCATION args; 300 TV_ENCODER_CONTROL_PS_ALLOCATION args;
298 int index = 0; 301 int index = 0;
299 /* fixme - fill in enc_priv for atom dac */ 302 struct radeon_encoder_atom_dac *dac_info = radeon_encoder->enc_priv;
300 enum radeon_tv_std tv_std = TV_STD_NTSC; 303 enum radeon_tv_std tv_std = TV_STD_NTSC;
301 304
305 if (dac_info->tv_std)
306 tv_std = dac_info->tv_std;
307
302 memset(&args, 0, sizeof(args)); 308 memset(&args, 0, sizeof(args));
303 309
304 index = GetIndexIntoMasterTable(COMMAND, TVEncoderControl); 310 index = GetIndexIntoMasterTable(COMMAND, TVEncoderControl);
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
index 0aaafcd2089f..b1547f700d73 100644
--- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
@@ -1271,6 +1271,30 @@ static const struct drm_encoder_funcs radeon_legacy_tv_dac_enc_funcs = {
1271 .destroy = radeon_enc_destroy, 1271 .destroy = radeon_enc_destroy,
1272}; 1272};
1273 1273
1274
1275static struct radeon_encoder_int_tmds *radeon_legacy_get_tmds_info(struct radeon_encoder *encoder)
1276{
1277 struct drm_device *dev = encoder->base.dev;
1278 struct radeon_device *rdev = dev->dev_private;
1279 struct radeon_encoder_int_tmds *tmds = NULL;
1280 bool ret;
1281
1282 tmds = kzalloc(sizeof(struct radeon_encoder_int_tmds), GFP_KERNEL);
1283
1284 if (!tmds)
1285 return NULL;
1286
1287 if (rdev->is_atom_bios)
1288 ret = radeon_atombios_get_tmds_info(encoder, tmds);
1289 else
1290 ret = radeon_legacy_get_tmds_info_from_combios(encoder, tmds);
1291
1292 if (ret == false)
1293 radeon_legacy_get_tmds_info_from_table(encoder, tmds);
1294
1295 return tmds;
1296}
1297
1274void 1298void
1275radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t supported_device) 1299radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t supported_device)
1276{ 1300{
@@ -1317,10 +1341,7 @@ radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t
1317 case ENCODER_OBJECT_ID_INTERNAL_TMDS1: 1341 case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
1318 drm_encoder_init(dev, encoder, &radeon_legacy_tmds_int_enc_funcs, DRM_MODE_ENCODER_TMDS); 1342 drm_encoder_init(dev, encoder, &radeon_legacy_tmds_int_enc_funcs, DRM_MODE_ENCODER_TMDS);
1319 drm_encoder_helper_add(encoder, &radeon_legacy_tmds_int_helper_funcs); 1343 drm_encoder_helper_add(encoder, &radeon_legacy_tmds_int_helper_funcs);
1320 if (rdev->is_atom_bios) 1344 radeon_encoder->enc_priv = radeon_legacy_get_tmds_info(radeon_encoder);
1321 radeon_encoder->enc_priv = radeon_atombios_get_tmds_info(radeon_encoder);
1322 else
1323 radeon_encoder->enc_priv = radeon_combios_get_tmds_info(radeon_encoder);
1324 break; 1345 break;
1325 case ENCODER_OBJECT_ID_INTERNAL_DAC1: 1346 case ENCODER_OBJECT_ID_INTERNAL_DAC1:
1326 drm_encoder_init(dev, encoder, &radeon_legacy_primary_dac_enc_funcs, DRM_MODE_ENCODER_DAC); 1347 drm_encoder_init(dev, encoder, &radeon_legacy_primary_dac_enc_funcs, DRM_MODE_ENCODER_DAC);
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index dde13817dee0..570a58729daf 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -175,6 +175,15 @@ struct radeon_mode_info {
175 enum radeon_connector_table connector_table; 175 enum radeon_connector_table connector_table;
176 bool mode_config_initialized; 176 bool mode_config_initialized;
177 struct radeon_crtc *crtcs[2]; 177 struct radeon_crtc *crtcs[2];
178 /* DVI-I properties */
179 struct drm_property *coherent_mode_property;
180 /* DAC enable load detect */
181 struct drm_property *load_detect_property;
182 /* TV standard load detect */
183 struct drm_property *tv_std_property;
184 /* legacy TMDS PLL detect */
185 struct drm_property *tmds_pll_property;
186
178}; 187};
179 188
180struct radeon_native_mode { 189struct radeon_native_mode {
@@ -304,6 +313,7 @@ struct radeon_connector {
304 and get modes due to analog/digital/tvencoder */ 313 and get modes due to analog/digital/tvencoder */
305 struct edid *edid; 314 struct edid *edid;
306 void *con_priv; 315 void *con_priv;
316 bool dac_load_detect;
307}; 317};
308 318
309struct radeon_framebuffer { 319struct radeon_framebuffer {
@@ -364,16 +374,18 @@ extern bool radeon_atom_get_clock_info(struct drm_device *dev);
364extern bool radeon_combios_get_clock_info(struct drm_device *dev); 374extern bool radeon_combios_get_clock_info(struct drm_device *dev);
365extern struct radeon_encoder_atom_dig * 375extern struct radeon_encoder_atom_dig *
366radeon_atombios_get_lvds_info(struct radeon_encoder *encoder); 376radeon_atombios_get_lvds_info(struct radeon_encoder *encoder);
367extern struct radeon_encoder_int_tmds * 377bool radeon_atombios_get_tmds_info(struct radeon_encoder *encoder,
368radeon_atombios_get_tmds_info(struct radeon_encoder *encoder); 378 struct radeon_encoder_int_tmds *tmds);
379bool radeon_legacy_get_tmds_info_from_combios(struct radeon_encoder *encoder,
380 struct radeon_encoder_int_tmds *tmds);
381bool radeon_legacy_get_tmds_info_from_table(struct radeon_encoder *encoder,
382 struct radeon_encoder_int_tmds *tmds);
369extern struct radeon_encoder_primary_dac * 383extern struct radeon_encoder_primary_dac *
370radeon_atombios_get_primary_dac_info(struct radeon_encoder *encoder); 384radeon_atombios_get_primary_dac_info(struct radeon_encoder *encoder);
371extern struct radeon_encoder_tv_dac * 385extern struct radeon_encoder_tv_dac *
372radeon_atombios_get_tv_dac_info(struct radeon_encoder *encoder); 386radeon_atombios_get_tv_dac_info(struct radeon_encoder *encoder);
373extern struct radeon_encoder_lvds * 387extern struct radeon_encoder_lvds *
374radeon_combios_get_lvds_info(struct radeon_encoder *encoder); 388radeon_combios_get_lvds_info(struct radeon_encoder *encoder);
375extern struct radeon_encoder_int_tmds *
376radeon_combios_get_tmds_info(struct radeon_encoder *encoder);
377extern void radeon_combios_get_ext_tmds_info(struct radeon_encoder *encoder); 389extern void radeon_combios_get_ext_tmds_info(struct radeon_encoder *encoder);
378extern struct radeon_encoder_tv_dac * 390extern struct radeon_encoder_tv_dac *
379radeon_combios_get_tv_dac_info(struct radeon_encoder *encoder); 391radeon_combios_get_tv_dac_info(struct radeon_encoder *encoder);