Rev 5271 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 5271 | Rev 6104 | ||
---|---|---|---|
Line 22... | Line 22... | ||
22 | */ |
22 | */ |
23 | #include |
23 | #include |
24 | #include |
24 | #include |
25 | #include "radeon.h" |
25 | #include "radeon.h" |
26 | #include "radeon_asic.h" |
26 | #include "radeon_asic.h" |
- | 27 | #include "radeon_audio.h" |
|
27 | #include "r600d.h" |
28 | #include "r600d.h" |
Line 28... | Line 29... | ||
28 | 29 | ||
- | 30 | void dce3_2_afmt_hdmi_write_speaker_allocation(struct drm_encoder *encoder, |
|
29 | static void dce3_2_afmt_write_speaker_allocation(struct drm_encoder *encoder) |
31 | u8 *sadb, int sad_count) |
30 | { |
32 | { |
31 | struct radeon_device *rdev = encoder->dev->dev_private; |
- | |
32 | struct drm_connector *connector; |
- | |
33 | struct radeon_connector *radeon_connector = NULL; |
33 | struct radeon_device *rdev = encoder->dev->dev_private; |
34 | u32 tmp; |
- | |
35 | u8 *sadb = NULL; |
- | |
36 | int sad_count; |
- | |
37 | - | ||
38 | list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) { |
- | |
39 | if (connector->encoder == encoder) { |
- | |
40 | radeon_connector = to_radeon_connector(connector); |
- | |
41 | break; |
- | |
42 | } |
- | |
43 | } |
- | |
44 | - | ||
45 | if (!radeon_connector) { |
- | |
46 | DRM_ERROR("Couldn't find encoder's connector\n"); |
- | |
47 | return; |
- | |
48 | } |
- | |
49 | - | ||
50 | sad_count = drm_edid_to_speaker_allocation(radeon_connector->edid, &sadb); |
- | |
51 | if (sad_count < 0) { |
- | |
52 | DRM_DEBUG("Couldn't read Speaker Allocation Data Block: %d\n", sad_count); |
- | |
53 | sad_count = 0; |
- | |
Line 54... | Line 34... | ||
54 | } |
34 | u32 tmp; |
55 | 35 | ||
56 | /* program the speaker allocation */ |
36 | /* program the speaker allocation */ |
57 | tmp = RREG32(AZ_F0_CODEC_PIN0_CONTROL_CHANNEL_SPEAKER); |
37 | tmp = RREG32_ENDPOINT(0, AZ_F0_CODEC_PIN0_CONTROL_CHANNEL_SPEAKER); |
58 | tmp &= ~(DP_CONNECTION | SPEAKER_ALLOCATION_MASK); |
38 | tmp &= ~(DP_CONNECTION | SPEAKER_ALLOCATION_MASK); |
59 | /* set HDMI mode */ |
39 | /* set HDMI mode */ |
60 | tmp |= HDMI_CONNECTION; |
40 | tmp |= HDMI_CONNECTION; |
61 | if (sad_count) |
41 | if (sad_count) |
62 | tmp |= SPEAKER_ALLOCATION(sadb[0]); |
42 | tmp |= SPEAKER_ALLOCATION(sadb[0]); |
63 | else |
43 | else |
64 | tmp |= SPEAKER_ALLOCATION(5); /* stereo */ |
- | |
65 | WREG32(AZ_F0_CODEC_PIN0_CONTROL_CHANNEL_SPEAKER, tmp); |
- | |
66 | 44 | tmp |= SPEAKER_ALLOCATION(5); /* stereo */ |
|
Line 67... | Line 45... | ||
67 | kfree(sadb); |
45 | WREG32_ENDPOINT(0, AZ_F0_CODEC_PIN0_CONTROL_CHANNEL_SPEAKER, tmp); |
- | 46 | } |
|
68 | } |
47 | |
69 | 48 | void dce3_2_afmt_dp_write_speaker_allocation(struct drm_encoder *encoder, |
|
- | 49 | u8 *sadb, int sad_count) |
|
- | 50 | { |
|
70 | static void dce3_2_afmt_write_sad_regs(struct drm_encoder *encoder) |
51 | struct radeon_device *rdev = encoder->dev->dev_private; |
- | 52 | u32 tmp; |
|
71 | { |
53 | |
72 | struct radeon_device *rdev = encoder->dev->dev_private; |
54 | /* program the speaker allocation */ |
- | 55 | tmp = RREG32_ENDPOINT(0, AZ_F0_CODEC_PIN0_CONTROL_CHANNEL_SPEAKER); |
|
73 | struct drm_connector *connector; |
56 | tmp &= ~(HDMI_CONNECTION | SPEAKER_ALLOCATION_MASK); |
- | 57 | /* set DP mode */ |
|
- | 58 | tmp |= DP_CONNECTION; |
|
- | 59 | if (sad_count) |
|
- | 60 | tmp |= SPEAKER_ALLOCATION(sadb[0]); |
|
- | 61 | else |
|
Line -... | Line 62... | ||
- | 62 | tmp |= SPEAKER_ALLOCATION(5); /* stereo */ |
|
- | 63 | WREG32_ENDPOINT(0, AZ_F0_CODEC_PIN0_CONTROL_CHANNEL_SPEAKER, tmp); |
|
- | 64 | } |
|
- | 65 | ||
- | 66 | void dce3_2_afmt_write_sad_regs(struct drm_encoder *encoder, |
|
74 | struct radeon_connector *radeon_connector = NULL; |
67 | struct cea_sad *sads, int sad_count) |
75 | struct cea_sad *sads; |
68 | { |
76 | int i, sad_count; |
69 | int i; |
77 | 70 | struct radeon_device *rdev = encoder->dev->dev_private; |
|
78 | static const u16 eld_reg_to_type[][2] = { |
71 | static const u16 eld_reg_to_type[][2] = { |
Line 88... | Line 81... | ||
88 | { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR10, HDMI_AUDIO_CODING_TYPE_DTS_HD }, |
81 | { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR10, HDMI_AUDIO_CODING_TYPE_DTS_HD }, |
89 | { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR11, HDMI_AUDIO_CODING_TYPE_MLP }, |
82 | { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR11, HDMI_AUDIO_CODING_TYPE_MLP }, |
90 | { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR13, HDMI_AUDIO_CODING_TYPE_WMA_PRO }, |
83 | { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR13, HDMI_AUDIO_CODING_TYPE_WMA_PRO }, |
91 | }; |
84 | }; |
Line 92... | Line -... | ||
92 | - | ||
93 | list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) { |
- | |
94 | if (connector->encoder == encoder) { |
- | |
95 | radeon_connector = to_radeon_connector(connector); |
- | |
96 | break; |
- | |
97 | } |
- | |
98 | } |
- | |
99 | - | ||
100 | if (!radeon_connector) { |
- | |
101 | DRM_ERROR("Couldn't find encoder's connector\n"); |
- | |
102 | return; |
- | |
103 | } |
- | |
104 | - | ||
105 | sad_count = drm_edid_to_sad(radeon_connector->edid, &sads); |
- | |
106 | if (sad_count < 0) { |
- | |
107 | DRM_ERROR("Couldn't read SADs: %d\n", sad_count); |
- | |
108 | return; |
- | |
109 | } |
- | |
110 | BUG_ON(!sads); |
- | |
111 | 85 | ||
112 | for (i = 0; i < ARRAY_SIZE(eld_reg_to_type); i++) { |
86 | for (i = 0; i < ARRAY_SIZE(eld_reg_to_type); i++) { |
113 | u32 value = 0; |
87 | u32 value = 0; |
114 | u8 stereo_freqs = 0; |
88 | u8 stereo_freqs = 0; |
115 | int max_channels = -1; |
89 | int max_channels = -1; |
Line 133... | Line 107... | ||
133 | } |
107 | } |
134 | } |
108 | } |
Line 135... | Line 109... | ||
135 | 109 | ||
Line 136... | Line 110... | ||
136 | value |= SUPPORTED_FREQUENCIES_STEREO(stereo_freqs); |
110 | value |= SUPPORTED_FREQUENCIES_STEREO(stereo_freqs); |
- | 111 | ||
137 | 112 | WREG32_ENDPOINT(0, eld_reg_to_type[i][0], value); |
|
Line -... | Line 113... | ||
- | 113 | } |
|
- | 114 | } |
|
- | 115 | ||
- | 116 | void dce3_2_audio_set_dto(struct radeon_device *rdev, |
|
- | 117 | struct radeon_crtc *crtc, unsigned int clock) |
|
- | 118 | { |
|
- | 119 | struct radeon_encoder *radeon_encoder; |
|
- | 120 | struct radeon_encoder_atom_dig *dig; |
|
- | 121 | unsigned int max_ratio = clock / 24000; |
|
- | 122 | u32 dto_phase; |
|
- | 123 | u32 wallclock_ratio; |
|
- | 124 | u32 dto_cntl; |
|
- | 125 | ||
- | 126 | if (!crtc) |
|
- | 127 | return; |
|
- | 128 | ||
138 | WREG32(eld_reg_to_type[i][0], value); |
129 | radeon_encoder = to_radeon_encoder(crtc->encoder); |
- | 130 | dig = radeon_encoder->enc_priv; |
|
- | 131 | ||
- | 132 | if (!dig) |
|
- | 133 | return; |
|
- | 134 | ||
- | 135 | if (max_ratio >= 8) { |
|
- | 136 | dto_phase = 192 * 1000; |
|
- | 137 | wallclock_ratio = 3; |
|
- | 138 | } else if (max_ratio >= 4) { |
|
- | 139 | dto_phase = 96 * 1000; |
|
- | 140 | wallclock_ratio = 2; |
|
- | 141 | } else if (max_ratio >= 2) { |
|
- | 142 | dto_phase = 48 * 1000; |
|
- | 143 | wallclock_ratio = 1; |
|
139 | } |
144 | } else { |
Line 140... | Line -... | ||
140 | - | ||
- | 145 | dto_phase = 24 * 1000; |
|
- | 146 | wallclock_ratio = 0; |
|
141 | kfree(sads); |
147 | } |
142 | } |
148 | |
- | 149 | /* Express [24MHz / target pixel clock] as an exact rational |
|
- | 150 | * number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE |
|
- | 151 | * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator |
|
- | 152 | */ |
|
- | 153 | if (dig->dig_encoder == 0) { |
|
- | 154 | dto_cntl = RREG32(DCCG_AUDIO_DTO0_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK; |
|
- | 155 | dto_cntl |= DCCG_AUDIO_DTO_WALLCLOCK_RATIO(wallclock_ratio); |
|
- | 156 | WREG32(DCCG_AUDIO_DTO0_CNTL, dto_cntl); |
|
- | 157 | WREG32(DCCG_AUDIO_DTO0_PHASE, dto_phase); |
|
- | 158 | WREG32(DCCG_AUDIO_DTO0_MODULE, clock); |
|
- | 159 | WREG32(DCCG_AUDIO_DTO_SELECT, 0); /* select DTO0 */ |
|
- | 160 | } else { |
|
- | 161 | dto_cntl = RREG32(DCCG_AUDIO_DTO1_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK; |
|
- | 162 | dto_cntl |= DCCG_AUDIO_DTO_WALLCLOCK_RATIO(wallclock_ratio); |
|
- | 163 | WREG32(DCCG_AUDIO_DTO1_CNTL, dto_cntl); |
|
- | 164 | WREG32(DCCG_AUDIO_DTO1_PHASE, dto_phase); |
|
- | 165 | WREG32(DCCG_AUDIO_DTO1_MODULE, clock); |
|
143 | 166 | WREG32(DCCG_AUDIO_DTO_SELECT, 1); /* select DTO1 */ |
|
- | 167 | } |
|
144 | /* |
168 | } |
145 | * update the info frames with the data from the current display mode |
169 | |
146 | */ |
170 | void dce3_2_hdmi_update_acr(struct drm_encoder *encoder, long offset, |
147 | void dce3_1_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode) |
- | |
148 | { |
- | |
149 | struct drm_device *dev = encoder->dev; |
- | |
150 | struct radeon_device *rdev = dev->dev_private; |
- | |
151 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
- | |
152 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
- | |
153 | u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE]; |
- | |
154 | struct hdmi_avi_infoframe frame; |
- | |
155 | uint32_t offset; |
- | |
Line 156... | Line 171... | ||
156 | ssize_t err; |
171 | const struct radeon_hdmi_acr *acr) |
157 | - | ||
158 | if (!dig || !dig->afmt) |
- | |
159 | return; |
- | |
160 | - | ||
161 | /* Silent, r600_hdmi_enable will raise WARN for us */ |
172 | { |
162 | if (!dig->afmt->enabled) |
- | |
163 | return; |
173 | struct drm_device *dev = encoder->dev; |
164 | offset = dig->afmt->offset; |
- | |
165 | - | ||
Line -... | Line 174... | ||
- | 174 | struct radeon_device *rdev = dev->dev_private; |
|
- | 175 | ||
- | 176 | WREG32(DCE3_HDMI0_ACR_PACKET_CONTROL + offset, |
|
166 | /* disable audio prior to setting up hw */ |
177 | HDMI0_ACR_SOURCE | /* select SW CTS value */ |
- | 178 | HDMI0_ACR_AUTO_SEND); /* allow hw to sent ACR packets when required */ |
|
- | 179 | ||
- | 180 | WREG32_P(HDMI0_ACR_32_0 + offset, |
|
- | 181 | HDMI0_ACR_CTS_32(acr->cts_32khz), |
|
167 | dig->afmt->pin = r600_audio_get_pin(rdev); |
182 | ~HDMI0_ACR_CTS_32_MASK); |
- | 183 | WREG32_P(HDMI0_ACR_32_1 + offset, |
|
- | 184 | HDMI0_ACR_N_32(acr->n_32khz), |
|
- | 185 | ~HDMI0_ACR_N_32_MASK); |
|
- | 186 | ||
- | 187 | WREG32_P(HDMI0_ACR_44_0 + offset, |
|
- | 188 | HDMI0_ACR_CTS_44(acr->cts_44_1khz), |
|
- | 189 | ~HDMI0_ACR_CTS_44_MASK); |
|
- | 190 | WREG32_P(HDMI0_ACR_44_1 + offset, |
|
- | 191 | HDMI0_ACR_N_44(acr->n_44_1khz), |
|
- | 192 | ~HDMI0_ACR_N_44_MASK); |
|
- | 193 | ||
- | 194 | WREG32_P(HDMI0_ACR_48_0 + offset, |
|
Line -... | Line 195... | ||
- | 195 | HDMI0_ACR_CTS_48(acr->cts_48khz), |
|
- | 196 | ~HDMI0_ACR_CTS_48_MASK); |
|
- | 197 | WREG32_P(HDMI0_ACR_48_1 + offset, |
|
168 | r600_audio_enable(rdev, dig->afmt->pin, 0); |
198 | HDMI0_ACR_N_48(acr->n_48khz), |
Line 169... | Line -... | ||
169 | - | ||
170 | r600_audio_set_dto(encoder, mode->clock); |
199 | ~HDMI0_ACR_N_48_MASK); |
171 | 200 | } |
|
172 | WREG32(HDMI0_VBI_PACKET_CONTROL + offset, |
201 | |
- | 202 | void dce3_2_set_audio_packet(struct drm_encoder *encoder, u32 offset) |
|
173 | HDMI0_NULL_SEND); /* send null packets when required */ |
203 | { |
174 | 204 | struct drm_device *dev = encoder->dev; |
|
175 | WREG32(HDMI0_AUDIO_CRC_CONTROL + offset, 0x1000); |
205 | struct radeon_device *rdev = dev->dev_private; |
176 | - | ||
177 | if (ASIC_IS_DCE32(rdev)) { |
- | |
178 | WREG32(HDMI0_AUDIO_PACKET_CONTROL + offset, |
- | |
179 | HDMI0_AUDIO_DELAY_EN(1) | /* default audio delay */ |
- | |
180 | HDMI0_AUDIO_PACKETS_PER_LINE(3)); /* should be suffient for all audio modes and small enough for all hblanks */ |
- | |
181 | WREG32(AFMT_AUDIO_PACKET_CONTROL + offset, |
- | |
182 | AFMT_AUDIO_SAMPLE_SEND | /* send audio packets */ |
- | |
183 | AFMT_60958_CS_UPDATE); /* allow 60958 channel status fields to be updated */ |
- | |
184 | } else { |
- | |
185 | WREG32(HDMI0_AUDIO_PACKET_CONTROL + offset, |
- | |
186 | HDMI0_AUDIO_SAMPLE_SEND | /* send audio packets */ |
- | |
187 | HDMI0_AUDIO_DELAY_EN(1) | /* default audio delay */ |
- | |
188 | HDMI0_AUDIO_PACKETS_PER_LINE(3) | /* should be suffient for all audio modes and small enough for all hblanks */ |
- | |
189 | HDMI0_60958_CS_UPDATE); /* allow 60958 channel status fields to be updated */ |
- | |
190 | } |
- | |
191 | - | ||
Line 192... | Line -... | ||
192 | if (ASIC_IS_DCE32(rdev)) { |
- | |
193 | dce3_2_afmt_write_speaker_allocation(encoder); |
- | |
194 | dce3_2_afmt_write_sad_regs(encoder); |
- | |
195 | } |
- | |
196 | - | ||
197 | WREG32(HDMI0_ACR_PACKET_CONTROL + offset, |
- | |
198 | HDMI0_ACR_SOURCE | /* select SW CTS value - XXX verify that hw CTS works on all families */ |
206 | |
199 | HDMI0_ACR_AUTO_SEND); /* allow hw to sent ACR packets when required */ |
- | |
200 | - | ||
201 | WREG32(HDMI0_VBI_PACKET_CONTROL + offset, |
207 | WREG32(HDMI0_AUDIO_PACKET_CONTROL + offset, |
202 | HDMI0_NULL_SEND | /* send null packets when required */ |
208 | HDMI0_AUDIO_DELAY_EN(1) | /* default audio delay */ |
Line 203... | Line 209... | ||
203 | HDMI0_GC_SEND | /* send general control packets */ |
209 | HDMI0_AUDIO_PACKETS_PER_LINE(3)); /* should be suffient for all audio modes and small enough for all hblanks */ |
204 | HDMI0_GC_CONT); /* send general control packets every frame */ |
- | |
205 | 210 | ||
206 | /* TODO: HDMI0_AUDIO_INFO_UPDATE */ |
- | |
207 | WREG32(HDMI0_INFOFRAME_CONTROL0 + offset, |
- | |
208 | HDMI0_AVI_INFO_SEND | /* enable AVI info frames */ |
- | |
209 | HDMI0_AVI_INFO_CONT | /* send AVI info frames every frame/field */ |
- | |
210 | HDMI0_AUDIO_INFO_SEND | /* enable audio info frames (frames won't be set until audio is enabled) */ |
- | |
211 | HDMI0_AUDIO_INFO_CONT); /* send audio info frames every frame/field */ |
- | |
212 | - | ||
213 | WREG32(HDMI0_INFOFRAME_CONTROL1 + offset, |
211 | WREG32(AFMT_AUDIO_PACKET_CONTROL + offset, |
Line 214... | Line 212... | ||
214 | HDMI0_AVI_INFO_LINE(2) | /* anything other than 0 */ |
212 | AFMT_AUDIO_SAMPLE_SEND | /* send audio packets */ |
215 | HDMI0_AUDIO_INFO_LINE(2)); /* anything other than 0 */ |
- | |
216 | - | ||
217 | WREG32(HDMI0_GC + offset, 0); /* unset HDMI0_GC_AVMUTE */ |
- | |
218 | - | ||
219 | err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode); |
213 | AFMT_60958_CS_UPDATE); /* allow 60958 channel status fields to be updated */ |
220 | if (err < 0) { |
- | |
221 | DRM_ERROR("failed to setup AVI infoframe: %zd\n", err); |
214 | |
222 | return; |
- | |
223 | } |
- | |
224 | - | ||
225 | err = hdmi_avi_infoframe_pack(&frame, buffer, sizeof(buffer)); |
- | |
226 | if (err < 0) { |
- | |
227 | DRM_ERROR("failed to pack AVI infoframe: %zd\n", err); |
- | |
228 | return; |
- | |
229 | } |
215 | WREG32_OR(HDMI0_INFOFRAME_CONTROL0 + offset, |
Line -... | Line 216... | ||
- | 216 | HDMI0_AUDIO_INFO_SEND | /* enable audio info frames (frames won't be set until audio is enabled) */ |
|
230 | 217 | HDMI0_AUDIO_INFO_CONT); /* send audio info frames every frame/field */ |
|
- | 218 | ||
231 | r600_hdmi_update_avi_infoframe(encoder, buffer, sizeof(buffer)); |
219 | WREG32_OR(HDMI0_INFOFRAME_CONTROL1 + offset, |
232 | r600_hdmi_update_ACR(encoder, mode->clock); |
220 | HDMI0_AUDIO_INFO_LINE(2)); /* anything other than 0 */ |