diff options
author | Alex Deucher <alexdeucher@gmail.com> | 2009-11-23 18:40:40 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2009-12-07 19:22:43 -0500 |
commit | f92a8b6758bdc0f277c4f42aa7d736a205ac9ded (patch) | |
tree | 3feb11b2cb76229767c42a4a3d34d6e525b73364 | |
parent | 4143e919ea999c9356ae4f71b5a3a80e075290d5 (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.c | 69 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_encoders.c | 41 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_mode.h | 2 |
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 | |||
38 | static 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 | |||
47 | static const int num_dp_clocks = sizeof(dp_clocks) / sizeof(int); | ||
48 | |||
49 | int 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 | |||
86 | int 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 | |||
36 | bool radeon_process_aux_ch(struct radeon_i2c_chan *chan, u8 *req_bytes, | 105 | bool 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 | ||
369 | extern int dp_lanes_for_mode_clock(int max_link_bw, int mode_clock); | ||
370 | extern int dp_link_clock_for_mode_clock(int max_link_bw, int mode_clock); | ||
369 | extern u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector); | 371 | extern u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector); |
370 | extern void radeon_dp_getdpcd(struct radeon_connector *radeon_connector); | 372 | extern void radeon_dp_getdpcd(struct radeon_connector *radeon_connector); |
371 | extern int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, | 373 | extern int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, |