Rev 2997 | Rev 5078 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2997 | Rev 3764 | ||
---|---|---|---|
Line 22... | Line 22... | ||
22 | * OTHER DEALINGS IN THE SOFTWARE. |
22 | * OTHER DEALINGS IN THE SOFTWARE. |
23 | * |
23 | * |
24 | * Authors: Christian König |
24 | * Authors: Christian König |
25 | * Rafał Miłecki |
25 | * Rafał Miłecki |
26 | */ |
26 | */ |
- | 27 | #include |
|
27 | #include |
28 | #include |
28 | #include |
29 | #include |
29 | #include "radeon.h" |
30 | #include "radeon.h" |
30 | #include "radeon_asic.h" |
31 | #include "radeon_asic.h" |
31 | #include "evergreend.h" |
32 | #include "evergreend.h" |
Line 51... | Line 52... | ||
51 | 52 | ||
52 | WREG32(HDMI_ACR_48_0 + offset, HDMI_ACR_CTS_48(acr.cts_48khz)); |
53 | WREG32(HDMI_ACR_48_0 + offset, HDMI_ACR_CTS_48(acr.cts_48khz)); |
53 | WREG32(HDMI_ACR_48_1 + offset, acr.n_48khz); |
54 | WREG32(HDMI_ACR_48_1 + offset, acr.n_48khz); |
Line 54... | Line -... | ||
54 | } |
- | |
55 | - | ||
56 | /* |
- | |
57 | * calculate the crc for a given info frame |
55 | } |
58 | */ |
- | |
59 | static void evergreen_hdmi_infoframe_checksum(uint8_t packetType, |
- | |
60 | uint8_t versionNumber, |
- | |
61 | uint8_t length, |
56 | |
- | 57 | static void evergreen_hdmi_write_sad_regs(struct drm_encoder *encoder) |
|
- | 58 | { |
|
- | 59 | struct radeon_device *rdev = encoder->dev->dev_private; |
|
- | 60 | struct drm_connector *connector; |
|
- | 61 | struct radeon_connector *radeon_connector = NULL; |
|
- | 62 | struct cea_sad *sads; |
|
- | 63 | int i, sad_count; |
|
- | 64 | ||
- | 65 | static const u16 eld_reg_to_type[][2] = { |
|
- | 66 | { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR0, HDMI_AUDIO_CODING_TYPE_PCM }, |
|
- | 67 | { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR1, HDMI_AUDIO_CODING_TYPE_AC3 }, |
|
- | 68 | { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR2, HDMI_AUDIO_CODING_TYPE_MPEG1 }, |
|
- | 69 | { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR3, HDMI_AUDIO_CODING_TYPE_MP3 }, |
|
- | 70 | { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR4, HDMI_AUDIO_CODING_TYPE_MPEG2 }, |
|
- | 71 | { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR5, HDMI_AUDIO_CODING_TYPE_AAC_LC }, |
|
- | 72 | { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR6, HDMI_AUDIO_CODING_TYPE_DTS }, |
|
- | 73 | { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR7, HDMI_AUDIO_CODING_TYPE_ATRAC }, |
|
- | 74 | { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR9, HDMI_AUDIO_CODING_TYPE_EAC3 }, |
|
- | 75 | { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR10, HDMI_AUDIO_CODING_TYPE_DTS_HD }, |
|
- | 76 | { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR11, HDMI_AUDIO_CODING_TYPE_MLP }, |
|
- | 77 | { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR13, HDMI_AUDIO_CODING_TYPE_WMA_PRO }, |
|
- | 78 | }; |
|
- | 79 | ||
- | 80 | list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) { |
|
- | 81 | if (connector->encoder == encoder) |
|
- | 82 | radeon_connector = to_radeon_connector(connector); |
|
- | 83 | } |
|
- | 84 | ||
- | 85 | if (!radeon_connector) { |
|
- | 86 | DRM_ERROR("Couldn't find encoder's connector\n"); |
|
- | 87 | return; |
|
- | 88 | } |
|
- | 89 | ||
- | 90 | sad_count = drm_edid_to_sad(radeon_connector->edid, &sads); |
|
62 | uint8_t *frame) |
91 | if (sad_count < 0) { |
- | 92 | DRM_ERROR("Couldn't read SADs: %d\n", sad_count); |
|
- | 93 | return; |
|
- | 94 | } |
|
63 | { |
95 | BUG_ON(!sads); |
- | 96 | ||
- | 97 | for (i = 0; i < ARRAY_SIZE(eld_reg_to_type); i++) { |
|
- | 98 | u32 value = 0; |
|
64 | int i; |
99 | int j; |
65 | frame[0] = packetType + versionNumber + length; |
100 | |
- | 101 | for (j = 0; j < sad_count; j++) { |
|
- | 102 | struct cea_sad *sad = &sads[j]; |
|
66 | for (i = 1; i <= length; i++) |
103 | |
- | 104 | if (sad->format == eld_reg_to_type[i][1]) { |
|
- | 105 | value = MAX_CHANNELS(sad->channels) | |
|
- | 106 | DESCRIPTOR_BYTE_2(sad->byte2) | |
|
- | 107 | SUPPORTED_FREQUENCIES(sad->freq); |
|
- | 108 | if (sad->format == HDMI_AUDIO_CODING_TYPE_PCM) |
|
- | 109 | value |= SUPPORTED_FREQUENCIES_STEREO(sad->freq); |
|
- | 110 | break; |
|
- | 111 | } |
|
- | 112 | } |
|
- | 113 | WREG32(eld_reg_to_type[i][0], value); |
|
- | 114 | } |
|
67 | frame[0] += frame[i]; |
115 | |
Line 68... | Line 116... | ||
68 | frame[0] = 0x100 - frame[0]; |
116 | kfree(sads); |
69 | } |
117 | } |
70 | 118 | ||
71 | /* |
119 | /* |
72 | * build a HDMI Video Info Frame |
- | |
73 | */ |
- | |
74 | static void evergreen_hdmi_videoinfoframe( |
120 | * build a HDMI Video Info Frame |
75 | struct drm_encoder *encoder, |
- | |
76 | uint8_t color_format, |
- | |
77 | int active_information_present, |
- | |
78 | uint8_t active_format_aspect_ratio, |
- | |
79 | uint8_t scan_information, |
- | |
80 | uint8_t colorimetry, |
- | |
81 | uint8_t ex_colorimetry, |
- | |
82 | uint8_t quantization, |
- | |
83 | int ITC, |
- | |
84 | uint8_t picture_aspect_ratio, |
- | |
85 | uint8_t video_format_identification, |
- | |
86 | uint8_t pixel_repetition, |
- | |
87 | uint8_t non_uniform_picture_scaling, |
- | |
88 | uint8_t bar_info_data_valid, |
- | |
89 | uint16_t top_bar, |
- | |
90 | uint16_t bottom_bar, |
- | |
91 | uint16_t left_bar, |
121 | */ |
92 | uint16_t right_bar |
122 | static void evergreen_hdmi_update_avi_infoframe(struct drm_encoder *encoder, |
93 | ) |
123 | void *buffer, size_t size) |
94 | { |
124 | { |
95 | struct drm_device *dev = encoder->dev; |
125 | struct drm_device *dev = encoder->dev; |
96 | struct radeon_device *rdev = dev->dev_private; |
126 | struct radeon_device *rdev = dev->dev_private; |
- | 127 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
|
Line 97... | Line -... | ||
97 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
- | |
98 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
- | |
99 | uint32_t offset = dig->afmt->offset; |
- | |
100 | - | ||
101 | uint8_t frame[14]; |
- | |
102 | - | ||
103 | frame[0x0] = 0; |
- | |
104 | frame[0x1] = |
- | |
105 | (scan_information & 0x3) | |
- | |
106 | ((bar_info_data_valid & 0x3) << 2) | |
- | |
107 | ((active_information_present & 0x1) << 4) | |
- | |
108 | ((color_format & 0x3) << 5); |
- | |
109 | frame[0x2] = |
- | |
110 | (active_format_aspect_ratio & 0xF) | |
- | |
111 | ((picture_aspect_ratio & 0x3) << 4) | |
- | |
112 | ((colorimetry & 0x3) << 6); |
- | |
113 | frame[0x3] = |
- | |
114 | (non_uniform_picture_scaling & 0x3) | |
- | |
115 | ((quantization & 0x3) << 2) | |
- | |
116 | ((ex_colorimetry & 0x7) << 4) | |
- | |
117 | ((ITC & 0x1) << 7); |
- | |
118 | frame[0x4] = (video_format_identification & 0x7F); |
- | |
119 | frame[0x5] = (pixel_repetition & 0xF); |
- | |
120 | frame[0x6] = (top_bar & 0xFF); |
- | |
121 | frame[0x7] = (top_bar >> 8); |
- | |
122 | frame[0x8] = (bottom_bar & 0xFF); |
- | |
123 | frame[0x9] = (bottom_bar >> 8); |
- | |
124 | frame[0xA] = (left_bar & 0xFF); |
- | |
125 | frame[0xB] = (left_bar >> 8); |
- | |
126 | frame[0xC] = (right_bar & 0xFF); |
128 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
127 | frame[0xD] = (right_bar >> 8); |
129 | uint32_t offset = dig->afmt->offset; |
128 | 130 | uint8_t *frame = buffer + 3; |
|
129 | evergreen_hdmi_infoframe_checksum(0x82, 0x02, 0x0D, frame); |
131 | |
130 | /* Our header values (type, version, length) should be alright, Intel |
132 | /* Our header values (type, version, length) should be alright, Intel |
Line 152... | Line 154... | ||
152 | { |
154 | { |
153 | struct drm_device *dev = encoder->dev; |
155 | struct drm_device *dev = encoder->dev; |
154 | struct radeon_device *rdev = dev->dev_private; |
156 | struct radeon_device *rdev = dev->dev_private; |
155 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
157 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
156 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
158 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
- | 159 | u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE]; |
|
- | 160 | struct hdmi_avi_infoframe frame; |
|
157 | uint32_t offset; |
161 | uint32_t offset; |
- | 162 | ssize_t err; |
|
Line 158... | Line 163... | ||
158 | 163 | ||
159 | /* Silent, r600_hdmi_enable will raise WARN for us */ |
164 | /* Silent, r600_hdmi_enable will raise WARN for us */ |
160 | if (!dig->afmt->enabled) |
165 | if (!dig->afmt->enabled) |
161 | return; |
166 | return; |
Line 198... | Line 203... | ||
198 | HDMI_AVI_INFO_LINE(2) | /* anything other than 0 */ |
203 | HDMI_AVI_INFO_LINE(2) | /* anything other than 0 */ |
199 | HDMI_AUDIO_INFO_LINE(2)); /* anything other than 0 */ |
204 | HDMI_AUDIO_INFO_LINE(2)); /* anything other than 0 */ |
Line 200... | Line 205... | ||
200 | 205 | ||
Line -... | Line 206... | ||
- | 206 | WREG32(HDMI_GC + offset, 0); /* unset HDMI_GC_AVMUTE */ |
|
- | 207 | ||
- | 208 | err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode); |
|
- | 209 | if (err < 0) { |
|
- | 210 | DRM_ERROR("failed to setup AVI infoframe: %zd\n", err); |
|
- | 211 | return; |
|
201 | WREG32(HDMI_GC + offset, 0); /* unset HDMI_GC_AVMUTE */ |
212 | } |
202 | 213 | ||
- | 214 | err = hdmi_avi_infoframe_pack(&frame, buffer, sizeof(buffer)); |
|
- | 215 | if (err < 0) { |
|
- | 216 | DRM_ERROR("failed to pack AVI infoframe: %zd\n", err); |
|
Line -... | Line 217... | ||
- | 217 | return; |
|
203 | evergreen_hdmi_videoinfoframe(encoder, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
218 | } |
Line 204... | Line 219... | ||
204 | 0, 0, 0, 0, 0, 0); |
219 | |
205 | 220 | evergreen_hdmi_update_avi_infoframe(encoder, buffer, sizeof(buffer)); |
|
206 | evergreen_hdmi_update_ACR(encoder, mode->clock); |
221 | evergreen_hdmi_update_ACR(encoder, mode->clock); |