diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_sdvo.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_sdvo.c | 126 |
1 files changed, 22 insertions, 104 deletions
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index c245383cf7ed..6739a7455174 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -854,115 +854,33 @@ static void intel_sdvo_dump_hdmi_buf(struct intel_sdvo *intel_sdvo) | |||
854 | } | 854 | } |
855 | #endif | 855 | #endif |
856 | 856 | ||
857 | static bool intel_sdvo_set_hdmi_buf(struct intel_sdvo *intel_sdvo, | 857 | static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo) |
858 | int index, | ||
859 | uint8_t *data, int8_t size, uint8_t tx_rate) | ||
860 | { | ||
861 | uint8_t set_buf_index[2]; | ||
862 | |||
863 | set_buf_index[0] = index; | ||
864 | set_buf_index[1] = 0; | ||
865 | |||
866 | if (!intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_HBUF_INDEX, | ||
867 | set_buf_index, 2)) | ||
868 | return false; | ||
869 | |||
870 | for (; size > 0; size -= 8) { | ||
871 | if (!intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_HBUF_DATA, data, 8)) | ||
872 | return false; | ||
873 | |||
874 | data += 8; | ||
875 | } | ||
876 | |||
877 | return intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_HBUF_TXRATE, &tx_rate, 1); | ||
878 | } | ||
879 | |||
880 | static uint8_t intel_sdvo_calc_hbuf_csum(uint8_t *data, uint8_t size) | ||
881 | { | ||
882 | uint8_t csum = 0; | ||
883 | int i; | ||
884 | |||
885 | for (i = 0; i < size; i++) | ||
886 | csum += data[i]; | ||
887 | |||
888 | return 0x100 - csum; | ||
889 | } | ||
890 | |||
891 | #define DIP_TYPE_AVI 0x82 | ||
892 | #define DIP_VERSION_AVI 0x2 | ||
893 | #define DIP_LEN_AVI 13 | ||
894 | |||
895 | struct dip_infoframe { | ||
896 | uint8_t type; | ||
897 | uint8_t version; | ||
898 | uint8_t len; | ||
899 | uint8_t checksum; | ||
900 | union { | ||
901 | struct { | ||
902 | /* Packet Byte #1 */ | ||
903 | uint8_t S:2; | ||
904 | uint8_t B:2; | ||
905 | uint8_t A:1; | ||
906 | uint8_t Y:2; | ||
907 | uint8_t rsvd1:1; | ||
908 | /* Packet Byte #2 */ | ||
909 | uint8_t R:4; | ||
910 | uint8_t M:2; | ||
911 | uint8_t C:2; | ||
912 | /* Packet Byte #3 */ | ||
913 | uint8_t SC:2; | ||
914 | uint8_t Q:2; | ||
915 | uint8_t EC:3; | ||
916 | uint8_t ITC:1; | ||
917 | /* Packet Byte #4 */ | ||
918 | uint8_t VIC:7; | ||
919 | uint8_t rsvd2:1; | ||
920 | /* Packet Byte #5 */ | ||
921 | uint8_t PR:4; | ||
922 | uint8_t rsvd3:4; | ||
923 | /* Packet Byte #6~13 */ | ||
924 | uint16_t top_bar_end; | ||
925 | uint16_t bottom_bar_start; | ||
926 | uint16_t left_bar_end; | ||
927 | uint16_t right_bar_start; | ||
928 | } avi; | ||
929 | struct { | ||
930 | /* Packet Byte #1 */ | ||
931 | uint8_t channel_count:3; | ||
932 | uint8_t rsvd1:1; | ||
933 | uint8_t coding_type:4; | ||
934 | /* Packet Byte #2 */ | ||
935 | uint8_t sample_size:2; /* SS0, SS1 */ | ||
936 | uint8_t sample_frequency:3; | ||
937 | uint8_t rsvd2:3; | ||
938 | /* Packet Byte #3 */ | ||
939 | uint8_t coding_type_private:5; | ||
940 | uint8_t rsvd3:3; | ||
941 | /* Packet Byte #4 */ | ||
942 | uint8_t channel_allocation; | ||
943 | /* Packet Byte #5 */ | ||
944 | uint8_t rsvd4:3; | ||
945 | uint8_t level_shift:4; | ||
946 | uint8_t downmix_inhibit:1; | ||
947 | } audio; | ||
948 | uint8_t payload[28]; | ||
949 | } __attribute__ ((packed)) u; | ||
950 | } __attribute__((packed)); | ||
951 | |||
952 | static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo, | ||
953 | struct drm_display_mode * mode) | ||
954 | { | 858 | { |
955 | struct dip_infoframe avi_if = { | 859 | struct dip_infoframe avi_if = { |
956 | .type = DIP_TYPE_AVI, | 860 | .type = DIP_TYPE_AVI, |
957 | .version = DIP_VERSION_AVI, | 861 | .ver = DIP_VERSION_AVI, |
958 | .len = DIP_LEN_AVI, | 862 | .len = DIP_LEN_AVI, |
959 | }; | 863 | }; |
864 | uint8_t tx_rate = SDVO_HBUF_TX_VSYNC; | ||
865 | uint8_t set_buf_index[2] = { 1, 0 }; | ||
866 | uint64_t *data = (uint64_t *)&avi_if; | ||
867 | unsigned i; | ||
868 | |||
869 | intel_dip_infoframe_csum(&avi_if); | ||
870 | |||
871 | if (!intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_HBUF_INDEX, | ||
872 | set_buf_index, 2)) | ||
873 | return false; | ||
874 | |||
875 | for (i = 0; i < sizeof(avi_if); i += 8) { | ||
876 | if (!intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_HBUF_DATA, | ||
877 | data, 8)) | ||
878 | return false; | ||
879 | data++; | ||
880 | } | ||
960 | 881 | ||
961 | avi_if.checksum = intel_sdvo_calc_hbuf_csum((uint8_t *)&avi_if, | 882 | return intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_HBUF_TXRATE, |
962 | 4 + avi_if.len); | 883 | &tx_rate, 1); |
963 | return intel_sdvo_set_hdmi_buf(intel_sdvo, 1, (uint8_t *)&avi_if, | ||
964 | 4 + avi_if.len, | ||
965 | SDVO_HBUF_TX_VSYNC); | ||
966 | } | 884 | } |
967 | 885 | ||
968 | static bool intel_sdvo_set_tv_format(struct intel_sdvo *intel_sdvo) | 886 | static bool intel_sdvo_set_tv_format(struct intel_sdvo *intel_sdvo) |
@@ -1116,7 +1034,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1116 | return; | 1034 | return; |
1117 | 1035 | ||
1118 | if (intel_sdvo->is_hdmi && | 1036 | if (intel_sdvo->is_hdmi && |
1119 | !intel_sdvo_set_avi_infoframe(intel_sdvo, mode)) | 1037 | !intel_sdvo_set_avi_infoframe(intel_sdvo)) |
1120 | return; | 1038 | return; |
1121 | 1039 | ||
1122 | if (intel_sdvo->is_tv && | 1040 | if (intel_sdvo->is_tv && |