aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Deucher <alexdeucher@gmail.com>2009-11-23 18:40:40 -0500
committerDave Airlie <airlied@redhat.com>2009-12-07 19:22:43 -0500
commitf92a8b6758bdc0f277c4f42aa7d736a205ac9ded (patch)
tree3feb11b2cb76229767c42a4a3d34d6e525b73364
parent4143e919ea999c9356ae4f71b5a3a80e075290d5 (diff)
drm/radeon/kms: handle dp sinks in atom encoder/transmitter tables
Signed-off-by: Alex Deucher <alexdeucher@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r--drivers/gpu/drm/radeon/atombios_dp.c69
-rw-r--r--drivers/gpu/drm/radeon/radeon_encoders.c41
-rw-r--r--drivers/gpu/drm/radeon/radeon_mode.h2
3 files changed, 100 insertions, 12 deletions
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c
index e761fefaacb1..76eb5c8a7016 100644
--- a/drivers/gpu/drm/radeon/atombios_dp.c
+++ b/drivers/gpu/drm/radeon/atombios_dp.c
@@ -33,6 +33,75 @@
33 33
34#define DP_LINK_STATUS_SIZE 6 34#define DP_LINK_STATUS_SIZE 6
35 35
36/* move these to drm_dp_helper.c/h */
37
38static const int dp_clocks[] = {
39 54000, // 1 lane, 1.62 Ghz
40 90000, // 1 lane, 2.70 Ghz
41 108000, // 2 lane, 1.62 Ghz
42 180000, // 2 lane, 2.70 Ghz
43 216000, // 4 lane, 1.62 Ghz
44 360000, // 4 lane, 2.70 Ghz
45};
46
47static const int num_dp_clocks = sizeof(dp_clocks) / sizeof(int);
48
49int dp_lanes_for_mode_clock(int max_link_bw, int mode_clock)
50{
51 int i;
52
53 switch (max_link_bw) {
54 case DP_LINK_BW_1_62:
55 default:
56 for (i = 0; i < num_dp_clocks; i++) {
57 if (i % 2)
58 continue;
59 if (dp_clocks[i] > mode_clock) {
60 if (i < 2)
61 return 1;
62 else if (i < 4)
63 return 2;
64 else
65 return 4;
66 }
67 }
68 break;
69 case DP_LINK_BW_2_7:
70 for (i = 0; i < num_dp_clocks; i++) {
71 if (dp_clocks[i] > mode_clock) {
72 if (i < 2)
73 return 1;
74 else if (i < 4)
75 return 2;
76 else
77 return 4;
78 }
79 }
80 break;
81 }
82
83 return 0;
84}
85
86int dp_link_clock_for_mode_clock(int max_link_bw, int mode_clock)
87{
88 int i;
89
90 switch (max_link_bw) {
91 case DP_LINK_BW_1_62:
92 default:
93 return 162000;
94 break;
95 case DP_LINK_BW_2_7:
96 for (i = 0; i < num_dp_clocks; i++) {
97 if (dp_clocks[i] > mode_clock)
98 return (i % 2) ? 270000 : 162000;
99 }
100 }
101
102 return 0;
103}
104
36bool radeon_process_aux_ch(struct radeon_i2c_chan *chan, u8 *req_bytes, 105bool radeon_process_aux_ch(struct radeon_i2c_chan *chan, u8 *req_bytes,
37 int num_bytes, u8 *read_byte, 106 int num_bytes, u8 *read_byte,
38 u8 read_buf_len, u8 delay) 107 u8 read_buf_len, u8 delay)
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c
index b4e7abadbfb2..8f3d67b6032c 100644
--- a/drivers/gpu/drm/radeon/radeon_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_encoders.c
@@ -554,6 +554,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
554{ 554{
555 struct drm_connector *connector; 555 struct drm_connector *connector;
556 struct radeon_connector *radeon_connector; 556 struct radeon_connector *radeon_connector;
557 struct radeon_connector_atom_dig *radeon_dig_connector;
557 558
558 connector = radeon_get_connector_for_encoder(encoder); 559 connector = radeon_get_connector_for_encoder(encoder);
559 if (!connector) 560 if (!connector)
@@ -583,10 +584,10 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
583 return ATOM_ENCODER_MODE_LVDS; 584 return ATOM_ENCODER_MODE_LVDS;
584 break; 585 break;
585 case DRM_MODE_CONNECTOR_DisplayPort: 586 case DRM_MODE_CONNECTOR_DisplayPort:
586 /*if (radeon_output->MonType == MT_DP) 587 radeon_dig_connector = radeon_connector->con_priv;
587 return ATOM_ENCODER_MODE_DP; 588 if (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT)
588 else*/ 589 return ATOM_ENCODER_MODE_DP;
589 if (drm_detect_hdmi_monitor(radeon_connector->edid)) 590 else if (drm_detect_hdmi_monitor(radeon_connector->edid))
590 return ATOM_ENCODER_MODE_HDMI; 591 return ATOM_ENCODER_MODE_HDMI;
591 else 592 else
592 return ATOM_ENCODER_MODE_DVI; 593 return ATOM_ENCODER_MODE_DVI;
@@ -715,7 +716,15 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action)
715 } 716 }
716 } 717 }
717 718
718 if (radeon_encoder->pixel_clock > 165000) 719 args.ucEncoderMode = atombios_get_encoder_mode(encoder);
720
721 if (args.ucEncoderMode == ATOM_ENCODER_MODE_DP) {
722 if (dp_link_clock_for_mode_clock(dig_connector->dpcd[1],
723 radeon_encoder->pixel_clock) == 270000)
724 args.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ;
725 args.ucLaneNum = dp_lanes_for_mode_clock(dig_connector->dpcd[1],
726 radeon_encoder->pixel_clock);
727 } else if (radeon_encoder->pixel_clock > 165000)
719 args.ucLaneNum = 8; 728 args.ucLaneNum = 8;
720 else 729 else
721 args.ucLaneNum = 4; 730 args.ucLaneNum = 4;
@@ -725,8 +734,6 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action)
725 else 734 else
726 args.ucConfig |= ATOM_ENCODER_CONFIG_LINKA; 735 args.ucConfig |= ATOM_ENCODER_CONFIG_LINKA;
727 736
728 args.ucEncoderMode = atombios_get_encoder_mode(encoder);
729
730 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); 737 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
731 738
732} 739}
@@ -749,6 +756,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
749 struct drm_connector *connector; 756 struct drm_connector *connector;
750 struct radeon_connector *radeon_connector; 757 struct radeon_connector *radeon_connector;
751 struct radeon_connector_atom_dig *dig_connector; 758 struct radeon_connector_atom_dig *dig_connector;
759 bool is_dp = false;
752 760
753 connector = radeon_get_connector_for_encoder(encoder); 761 connector = radeon_get_connector_for_encoder(encoder);
754 if (!connector) 762 if (!connector)
@@ -766,6 +774,9 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
766 774
767 dig_connector = radeon_connector->con_priv; 775 dig_connector = radeon_connector->con_priv;
768 776
777 if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP)
778 is_dp = true;
779
769 memset(&args, 0, sizeof(args)); 780 memset(&args, 0, sizeof(args));
770 781
771 if (ASIC_IS_DCE32(rdev)) 782 if (ASIC_IS_DCE32(rdev))
@@ -790,14 +801,16 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
790 args.v1.asMode.ucLaneSel = lane_num; 801 args.v1.asMode.ucLaneSel = lane_num;
791 args.v1.asMode.ucLaneSet = lane_set; 802 args.v1.asMode.ucLaneSet = lane_set;
792 } else { 803 } else {
793 if (radeon_encoder->pixel_clock > 165000) 804 if (is_dp)
805 args.v1.usPixelClock =
806 cpu_to_le16(dp_link_clock_for_mode_clock(dig_connector->dpcd[1],
807 radeon_encoder->pixel_clock) / 10);
808 else if (radeon_encoder->pixel_clock > 165000)
794 args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); 809 args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10);
795 else 810 else
796 args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); 811 args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
797 } 812 }
798 if (ASIC_IS_DCE32(rdev)) { 813 if (ASIC_IS_DCE32(rdev)) {
799 if (radeon_encoder->pixel_clock > 165000)
800 args.v2.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10);
801 if (dig->dig_block) 814 if (dig->dig_block)
802 args.v2.acConfig.ucEncoderSel = 1; 815 args.v2.acConfig.ucEncoderSel = 1;
803 if (dig_connector->linkb) 816 if (dig_connector->linkb)
@@ -818,7 +831,9 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
818 break; 831 break;
819 } 832 }
820 833
821 if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { 834 if (is_dp)
835 args.v2.acConfig.fCoherentMode = 1;
836 else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
822 if (dig->coherent_mode) 837 if (dig->coherent_mode)
823 args.v2.acConfig.fCoherentMode = 1; 838 args.v2.acConfig.fCoherentMode = 1;
824 } 839 }
@@ -866,7 +881,9 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
866 else 881 else
867 args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA; 882 args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA;
868 883
869 if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { 884 if (is_dp)
885 args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT;
886 else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
870 if (dig->coherent_mode) 887 if (dig->coherent_mode)
871 args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT; 888 args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT;
872 } 889 }
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index 338d0af18510..b516401c151a 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -366,6 +366,8 @@ struct radeon_framebuffer {
366 struct drm_gem_object *obj; 366 struct drm_gem_object *obj;
367}; 367};
368 368
369extern int dp_lanes_for_mode_clock(int max_link_bw, int mode_clock);
370extern int dp_link_clock_for_mode_clock(int max_link_bw, int mode_clock);
369extern u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector); 371extern u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector);
370extern void radeon_dp_getdpcd(struct radeon_connector *radeon_connector); 372extern void radeon_dp_getdpcd(struct radeon_connector *radeon_connector);
371extern int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, 373extern int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,