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 21... | Line 21... | ||
21 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
21 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
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 | */ |
25 | */ |
- | 26 | #include |
|
26 | #include |
27 | #include |
27 | #include |
28 | #include |
28 | #include "radeon.h" |
29 | #include "radeon.h" |
29 | #include "radeon_asic.h" |
30 | #include "radeon_asic.h" |
30 | #include "r600d.h" |
31 | #include "r600d.h" |
Line 119... | Line 120... | ||
119 | WREG32(HDMI0_ACR_48_0 + offset, HDMI0_ACR_CTS_48(acr.cts_48khz)); |
120 | WREG32(HDMI0_ACR_48_0 + offset, HDMI0_ACR_CTS_48(acr.cts_48khz)); |
120 | WREG32(HDMI0_ACR_48_1 + offset, acr.n_48khz); |
121 | WREG32(HDMI0_ACR_48_1 + offset, acr.n_48khz); |
121 | } |
122 | } |
Line 122... | Line 123... | ||
122 | 123 | ||
123 | /* |
- | |
124 | * calculate the crc for a given info frame |
- | |
125 | */ |
- | |
126 | static void r600_hdmi_infoframe_checksum(uint8_t packetType, |
- | |
127 | uint8_t versionNumber, |
- | |
128 | uint8_t length, |
- | |
129 | uint8_t *frame) |
- | |
130 | { |
- | |
131 | int i; |
- | |
132 | frame[0] = packetType + versionNumber + length; |
- | |
133 | for (i = 1; i <= length; i++) |
- | |
134 | frame[0] += frame[i]; |
- | |
135 | frame[0] = 0x100 - frame[0]; |
- | |
136 | } |
- | |
137 | - | ||
138 | /* |
124 | /* |
139 | * build a HDMI Video Info Frame |
125 | * build a HDMI Video Info Frame |
140 | */ |
126 | */ |
141 | static void r600_hdmi_videoinfoframe( |
- | |
142 | struct drm_encoder *encoder, |
- | |
143 | enum r600_hdmi_color_format color_format, |
127 | static void r600_hdmi_update_avi_infoframe(struct drm_encoder *encoder, |
144 | int active_information_present, |
- | |
145 | uint8_t active_format_aspect_ratio, |
- | |
146 | uint8_t scan_information, |
- | |
147 | uint8_t colorimetry, |
- | |
148 | uint8_t ex_colorimetry, |
- | |
149 | uint8_t quantization, |
- | |
150 | int ITC, |
- | |
151 | uint8_t picture_aspect_ratio, |
- | |
152 | uint8_t video_format_identification, |
- | |
153 | uint8_t pixel_repetition, |
- | |
154 | uint8_t non_uniform_picture_scaling, |
- | |
155 | uint8_t bar_info_data_valid, |
- | |
156 | uint16_t top_bar, |
- | |
157 | uint16_t bottom_bar, |
- | |
158 | uint16_t left_bar, |
- | |
159 | uint16_t right_bar |
- | |
160 | ) |
128 | void *buffer, size_t size) |
161 | { |
129 | { |
162 | struct drm_device *dev = encoder->dev; |
130 | struct drm_device *dev = encoder->dev; |
163 | struct radeon_device *rdev = dev->dev_private; |
131 | struct radeon_device *rdev = dev->dev_private; |
164 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
132 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
165 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
133 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
- | 134 | uint32_t offset = dig->afmt->offset; |
|
Line 166... | Line -... | ||
166 | uint32_t offset = dig->afmt->offset; |
- | |
167 | - | ||
168 | uint8_t frame[14]; |
- | |
169 | - | ||
170 | frame[0x0] = 0; |
- | |
171 | frame[0x1] = |
- | |
172 | (scan_information & 0x3) | |
- | |
173 | ((bar_info_data_valid & 0x3) << 2) | |
- | |
174 | ((active_information_present & 0x1) << 4) | |
- | |
175 | ((color_format & 0x3) << 5); |
- | |
176 | frame[0x2] = |
- | |
177 | (active_format_aspect_ratio & 0xF) | |
- | |
178 | ((picture_aspect_ratio & 0x3) << 4) | |
- | |
179 | ((colorimetry & 0x3) << 6); |
- | |
180 | frame[0x3] = |
- | |
181 | (non_uniform_picture_scaling & 0x3) | |
- | |
182 | ((quantization & 0x3) << 2) | |
- | |
183 | ((ex_colorimetry & 0x7) << 4) | |
- | |
184 | ((ITC & 0x1) << 7); |
- | |
185 | frame[0x4] = (video_format_identification & 0x7F); |
- | |
186 | frame[0x5] = (pixel_repetition & 0xF); |
- | |
187 | frame[0x6] = (top_bar & 0xFF); |
- | |
188 | frame[0x7] = (top_bar >> 8); |
- | |
189 | frame[0x8] = (bottom_bar & 0xFF); |
- | |
190 | frame[0x9] = (bottom_bar >> 8); |
- | |
191 | frame[0xA] = (left_bar & 0xFF); |
- | |
192 | frame[0xB] = (left_bar >> 8); |
- | |
193 | frame[0xC] = (right_bar & 0xFF); |
- | |
194 | frame[0xD] = (right_bar >> 8); |
- | |
195 | 135 | uint8_t *frame = buffer + 3; |
|
196 | r600_hdmi_infoframe_checksum(0x82, 0x02, 0x0D, frame); |
136 | |
197 | /* Our header values (type, version, length) should be alright, Intel |
137 | /* Our header values (type, version, length) should be alright, Intel |
198 | * is using the same. Checksum function also seems to be OK, it works |
138 | * is using the same. Checksum function also seems to be OK, it works |
199 | * fine for audio infoframe. However calculated value is always lower |
139 | * fine for audio infoframe. However calculated value is always lower |
Line 213... | Line 153... | ||
213 | } |
153 | } |
Line 214... | Line 154... | ||
214 | 154 | ||
215 | /* |
155 | /* |
216 | * build a Audio Info Frame |
156 | * build a Audio Info Frame |
217 | */ |
157 | */ |
218 | static void r600_hdmi_audioinfoframe( |
158 | static void r600_hdmi_update_audio_infoframe(struct drm_encoder *encoder, |
219 | struct drm_encoder *encoder, |
- | |
220 | uint8_t channel_count, |
- | |
221 | uint8_t coding_type, |
- | |
222 | uint8_t sample_size, |
- | |
223 | uint8_t sample_frequency, |
- | |
224 | uint8_t format, |
- | |
225 | uint8_t channel_allocation, |
- | |
226 | uint8_t level_shift, |
- | |
227 | int downmix_inhibit |
- | |
228 | ) |
159 | const void *buffer, size_t size) |
229 | { |
160 | { |
230 | struct drm_device *dev = encoder->dev; |
161 | struct drm_device *dev = encoder->dev; |
231 | struct radeon_device *rdev = dev->dev_private; |
162 | struct radeon_device *rdev = dev->dev_private; |
232 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
163 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
233 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
164 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
234 | uint32_t offset = dig->afmt->offset; |
- | |
235 | 165 | uint32_t offset = dig->afmt->offset; |
|
236 | uint8_t frame[11]; |
- | |
237 | - | ||
238 | frame[0x0] = 0; |
- | |
239 | frame[0x1] = (channel_count & 0x7) | ((coding_type & 0xF) << 4); |
- | |
240 | frame[0x2] = (sample_size & 0x3) | ((sample_frequency & 0x7) << 2); |
- | |
241 | frame[0x3] = format; |
- | |
242 | frame[0x4] = channel_allocation; |
- | |
243 | frame[0x5] = ((level_shift & 0xF) << 3) | ((downmix_inhibit & 0x1) << 7); |
- | |
244 | frame[0x6] = 0; |
- | |
245 | frame[0x7] = 0; |
- | |
246 | frame[0x8] = 0; |
- | |
247 | frame[0x9] = 0; |
- | |
248 | frame[0xA] = 0; |
- | |
249 | - | ||
Line 250... | Line 166... | ||
250 | r600_hdmi_infoframe_checksum(0x84, 0x01, 0x0A, frame); |
166 | const u8 *frame = buffer + 3; |
251 | 167 | ||
252 | WREG32(HDMI0_AUDIO_INFO0 + offset, |
168 | WREG32(HDMI0_AUDIO_INFO0 + offset, |
253 | frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24)); |
169 | frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24)); |
Line 308... | Line 224... | ||
308 | value = HDMI0_AUDIO_TEST_EN; /* enable workaround */ |
224 | value = HDMI0_AUDIO_TEST_EN; /* enable workaround */ |
309 | WREG32_P(HDMI0_AUDIO_PACKET_CONTROL + offset, |
225 | WREG32_P(HDMI0_AUDIO_PACKET_CONTROL + offset, |
310 | value, ~HDMI0_AUDIO_TEST_EN); |
226 | value, ~HDMI0_AUDIO_TEST_EN); |
311 | } |
227 | } |
Line -... | Line 228... | ||
- | 228 | ||
- | 229 | void r600_audio_set_dto(struct drm_encoder *encoder, u32 clock) |
|
- | 230 | { |
|
- | 231 | struct drm_device *dev = encoder->dev; |
|
- | 232 | struct radeon_device *rdev = dev->dev_private; |
|
- | 233 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
|
- | 234 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
|
- | 235 | u32 base_rate = 24000; |
|
- | 236 | ||
- | 237 | if (!dig || !dig->afmt) |
|
- | 238 | return; |
|
- | 239 | ||
- | 240 | /* there are two DTOs selected by DCCG_AUDIO_DTO_SELECT. |
|
- | 241 | * doesn't matter which one you use. Just use the first one. |
|
- | 242 | */ |
|
- | 243 | /* XXX two dtos; generally use dto0 for hdmi */ |
|
- | 244 | /* Express [24MHz / target pixel clock] as an exact rational |
|
- | 245 | * number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE |
|
- | 246 | * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator |
|
- | 247 | */ |
|
- | 248 | if (ASIC_IS_DCE3(rdev)) { |
|
- | 249 | /* according to the reg specs, this should DCE3.2 only, but in |
|
- | 250 | * practice it seems to cover DCE3.0 as well. |
|
- | 251 | */ |
|
- | 252 | WREG32(DCCG_AUDIO_DTO0_PHASE, base_rate * 100); |
|
- | 253 | WREG32(DCCG_AUDIO_DTO0_MODULE, clock * 100); |
|
- | 254 | WREG32(DCCG_AUDIO_DTO_SELECT, 0); /* select DTO0 */ |
|
- | 255 | } else { |
|
- | 256 | /* according to the reg specs, this should be DCE2.0 and DCE3.0 */ |
|
- | 257 | WREG32(AUDIO_DTO, AUDIO_DTO_PHASE(base_rate / 10) | |
|
- | 258 | AUDIO_DTO_MODULE(clock / 10)); |
|
- | 259 | } |
|
Line 312... | Line 260... | ||
312 | 260 | } |
|
313 | 261 | ||
314 | /* |
262 | /* |
315 | * update the info frames with the data from the current display mode |
263 | * update the info frames with the data from the current display mode |
316 | */ |
264 | */ |
317 | void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode) |
265 | void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode) |
318 | { |
266 | { |
319 | struct drm_device *dev = encoder->dev; |
267 | struct drm_device *dev = encoder->dev; |
320 | struct radeon_device *rdev = dev->dev_private; |
268 | struct radeon_device *rdev = dev->dev_private; |
- | 269 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
|
- | 270 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
|
321 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
271 | u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE]; |
- | 272 | struct hdmi_avi_infoframe frame; |
|
Line 322... | Line 273... | ||
322 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
273 | uint32_t offset; |
323 | uint32_t offset; |
274 | ssize_t err; |
324 | 275 | ||
325 | /* Silent, r600_hdmi_enable will raise WARN for us */ |
276 | /* Silent, r600_hdmi_enable will raise WARN for us */ |
Line 369... | Line 320... | ||
369 | HDMI0_AVI_INFO_LINE(2) | /* anything other than 0 */ |
320 | HDMI0_AVI_INFO_LINE(2) | /* anything other than 0 */ |
370 | HDMI0_AUDIO_INFO_LINE(2)); /* anything other than 0 */ |
321 | HDMI0_AUDIO_INFO_LINE(2)); /* anything other than 0 */ |
Line 371... | Line 322... | ||
371 | 322 | ||
Line -... | Line 323... | ||
- | 323 | WREG32(HDMI0_GC + offset, 0); /* unset HDMI0_GC_AVMUTE */ |
|
- | 324 | ||
- | 325 | err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode); |
|
- | 326 | if (err < 0) { |
|
- | 327 | DRM_ERROR("failed to setup AVI infoframe: %zd\n", err); |
|
- | 328 | return; |
|
372 | WREG32(HDMI0_GC + offset, 0); /* unset HDMI0_GC_AVMUTE */ |
329 | } |
- | 330 | ||
373 | 331 | err = hdmi_avi_infoframe_pack(&frame, buffer, sizeof(buffer)); |
|
- | 332 | if (err < 0) { |
|
- | 333 | DRM_ERROR("failed to pack AVI infoframe: %zd\n", err); |
|
Line -... | Line 334... | ||
- | 334 | return; |
|
374 | r600_hdmi_videoinfoframe(encoder, RGB, 0, 0, 0, 0, |
335 | } |
Line 375... | Line 336... | ||
375 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); |
336 | |
376 | 337 | r600_hdmi_update_avi_infoframe(encoder, buffer, sizeof(buffer)); |
|
377 | r600_hdmi_update_ACR(encoder, mode->clock); |
338 | r600_hdmi_update_ACR(encoder, mode->clock); |
Line 394... | Line 355... | ||
394 | struct drm_device *dev = encoder->dev; |
355 | struct drm_device *dev = encoder->dev; |
395 | struct radeon_device *rdev = dev->dev_private; |
356 | struct radeon_device *rdev = dev->dev_private; |
396 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
357 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
397 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
358 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
398 | struct r600_audio audio = r600_audio_status(rdev); |
359 | struct r600_audio audio = r600_audio_status(rdev); |
- | 360 | uint8_t buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AUDIO_INFOFRAME_SIZE]; |
|
- | 361 | struct hdmi_audio_infoframe frame; |
|
399 | uint32_t offset; |
362 | uint32_t offset; |
400 | uint32_t iec; |
363 | uint32_t iec; |
- | 364 | ssize_t err; |
|
Line 401... | Line 365... | ||
401 | 365 | ||
402 | if (!dig->afmt || !dig->afmt->enabled) |
366 | if (!dig->afmt || !dig->afmt->enabled) |
403 | return; |
367 | return; |
Line 461... | Line 425... | ||
461 | } |
425 | } |
462 | if (audio.status_bits & AUDIO_STATUS_V) |
426 | if (audio.status_bits & AUDIO_STATUS_V) |
463 | iec |= 0x5 << 16; |
427 | iec |= 0x5 << 16; |
464 | WREG32_P(HDMI0_60958_1 + offset, iec, ~0x5000f); |
428 | WREG32_P(HDMI0_60958_1 + offset, iec, ~0x5000f); |
Line -... | Line 429... | ||
- | 429 | ||
- | 430 | err = hdmi_audio_infoframe_init(&frame); |
|
- | 431 | if (err < 0) { |
|
- | 432 | DRM_ERROR("failed to setup audio infoframe\n"); |
|
- | 433 | return; |
|
- | 434 | } |
|
- | 435 | ||
- | 436 | frame.channels = audio.channels; |
|
465 | 437 | ||
- | 438 | err = hdmi_audio_infoframe_pack(&frame, buffer, sizeof(buffer)); |
|
- | 439 | if (err < 0) { |
|
466 | r600_hdmi_audioinfoframe(encoder, audio.channels - 1, 0, 0, 0, 0, 0, 0, |
440 | DRM_ERROR("failed to pack audio infoframe\n"); |
- | 441 | return; |
|
Line -... | Line 442... | ||
- | 442 | } |
|
467 | 0); |
443 | |
468 | 444 | r600_hdmi_update_audio_infoframe(encoder, buffer, sizeof(buffer)); |
|
469 | r600_hdmi_audio_workaround(encoder); |
445 | r600_hdmi_audio_workaround(encoder); |
Line 470... | Line 446... | ||
470 | } |
446 | } |
471 | #endif |
447 | #endif |
472 | 448 | ||
473 | /* |
449 | /* |
474 | * enable the HDMI engine |
450 | * enable the HDMI engine |
475 | */ |
451 | */ |
476 | void r600_hdmi_enable(struct drm_encoder *encoder) |
452 | void r600_hdmi_enable(struct drm_encoder *encoder, bool enable) |
477 | { |
453 | { |
478 | struct drm_device *dev = encoder->dev; |
454 | struct drm_device *dev = encoder->dev; |
479 | struct radeon_device *rdev = dev->dev_private; |
- | |
480 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
455 | struct radeon_device *rdev = dev->dev_private; |
481 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
- | |
482 | uint32_t offset; |
- | |
483 | u32 hdmi; |
- | |
Line 484... | Line 456... | ||
484 | 456 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
|
485 | if (ASIC_IS_DCE6(rdev)) |
457 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
- | 458 | u32 hdmi = HDMI0_ERROR_ACK; |
|
- | 459 | ||
486 | return; |
460 | /* Silent, r600_hdmi_enable will raise WARN for us */ |
487 | - | ||
Line 488... | Line 461... | ||
488 | /* Silent, r600_hdmi_enable will raise WARN for us */ |
461 | if (enable && dig->afmt->enabled) |
489 | if (dig->afmt->enabled) |
462 | return; |
- | 463 | if (!enable && !dig->afmt->enabled) |
|
490 | return; |
464 | return; |
491 | offset = dig->afmt->offset; |
465 | |
492 | 466 | /* Older chipsets require setting HDMI and routing manually */ |
|
- | 467 | if (!ASIC_IS_DCE3(rdev)) { |
|
493 | /* Older chipsets require setting HDMI and routing manually */ |
468 | if (enable) |
494 | if (rdev->family >= CHIP_R600 && !ASIC_IS_DCE3(rdev)) { |
- | |
495 | hdmi = HDMI0_ERROR_ACK | HDMI0_ENABLE; |
469 | hdmi |= HDMI0_ENABLE; |
- | 470 | switch (radeon_encoder->encoder_id) { |
|
- | 471 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: |
|
- | 472 | if (enable) { |
|
496 | switch (radeon_encoder->encoder_id) { |
473 | WREG32_OR(AVIVO_TMDSA_CNTL, AVIVO_TMDSA_CNTL_HDMI_EN); |
497 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: |
474 | hdmi |= HDMI0_STREAM(HDMI0_STREAM_TMDSA); |
- | 475 | } else { |
|
498 | WREG32_P(AVIVO_TMDSA_CNTL, AVIVO_TMDSA_CNTL_HDMI_EN, |
476 | WREG32_AND(AVIVO_TMDSA_CNTL, ~AVIVO_TMDSA_CNTL_HDMI_EN); |
499 | ~AVIVO_TMDSA_CNTL_HDMI_EN); |
- | |
500 | hdmi |= HDMI0_STREAM(HDMI0_STREAM_TMDSA); |
477 | } |
- | 478 | break; |
|
- | 479 | case ENCODER_OBJECT_ID_INTERNAL_LVTM1: |
|
- | 480 | if (enable) { |
|
501 | break; |
481 | WREG32_OR(AVIVO_LVTMA_CNTL, AVIVO_LVTMA_CNTL_HDMI_EN); |
502 | case ENCODER_OBJECT_ID_INTERNAL_LVTM1: |
482 | hdmi |= HDMI0_STREAM(HDMI0_STREAM_LVTMA); |
- | 483 | } else { |
|
503 | WREG32_P(AVIVO_LVTMA_CNTL, AVIVO_LVTMA_CNTL_HDMI_EN, |
484 | WREG32_AND(AVIVO_LVTMA_CNTL, ~AVIVO_LVTMA_CNTL_HDMI_EN); |
504 | ~AVIVO_LVTMA_CNTL_HDMI_EN); |
485 | } |
- | 486 | break; |
|
- | 487 | case ENCODER_OBJECT_ID_INTERNAL_DDI: |
|
- | 488 | if (enable) { |
|
505 | hdmi |= HDMI0_STREAM(HDMI0_STREAM_LVTMA); |
489 | WREG32_OR(DDIA_CNTL, DDIA_HDMI_EN); |
506 | break; |
490 | hdmi |= HDMI0_STREAM(HDMI0_STREAM_DDIA); |
- | 491 | } else { |
|
507 | case ENCODER_OBJECT_ID_INTERNAL_DDI: |
492 | WREG32_AND(DDIA_CNTL, ~DDIA_HDMI_EN); |
508 | WREG32_P(DDIA_CNTL, DDIA_HDMI_EN, ~DDIA_HDMI_EN); |
493 | } |
509 | hdmi |= HDMI0_STREAM(HDMI0_STREAM_DDIA); |
494 | break; |
510 | break; |
495 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: |
511 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: |
496 | if (enable) |
512 | hdmi |= HDMI0_STREAM(HDMI0_STREAM_DVOA); |
497 | hdmi |= HDMI0_STREAM(HDMI0_STREAM_DVOA); |
513 | break; |
498 | break; |
514 | default: |
499 | default: |
515 | dev_err(rdev->dev, "Invalid encoder for HDMI: 0x%X\n", |
500 | dev_err(rdev->dev, "Invalid encoder for HDMI: 0x%X\n", |
Line 516... | Line 501... | ||
516 | radeon_encoder->encoder_id); |
501 | radeon_encoder->encoder_id); |
517 | break; |
502 | break; |
- | 503 | } |
|
- | 504 | WREG32(HDMI0_CONTROL + dig->afmt->offset, hdmi); |
|
518 | } |
505 | } |
- | 506 | ||
- | 507 | if (rdev->irq.installed) { |
|
519 | WREG32(HDMI0_CONTROL + offset, hdmi); |
508 | /* if irq is available use it */ |
Line 520... | Line 509... | ||
520 | } |
509 | /* XXX: shouldn't need this on any asics. Double check DCE2/3 */ |
521 | - | ||
522 | if (rdev->irq.installed) { |
- | |
523 | /* if irq is available use it */ |
- | |
524 | // radeon_irq_kms_enable_afmt(rdev, dig->afmt->id); |
- | |
525 | } |
- | |
526 | - | ||
527 | dig->afmt->enabled = true; |
- | |
528 | - | ||
529 | DRM_DEBUG("Enabling HDMI interface @ 0x%04X for encoder 0x%x\n", |
- | |
530 | offset, radeon_encoder->encoder_id); |
- | |
531 | } |
- | |
532 | - | ||
533 | /* |
- | |
534 | * disable the HDMI engine |
- | |
535 | */ |
- | |
536 | void r600_hdmi_disable(struct drm_encoder *encoder) |
- | |
537 | { |
- | |
538 | struct drm_device *dev = encoder->dev; |
- | |
539 | struct radeon_device *rdev = dev->dev_private; |
- | |
540 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
- | |
541 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
- | |
542 | uint32_t offset; |
- | |
543 | - | ||
544 | if (ASIC_IS_DCE6(rdev)) |
- | |
545 | return; |
- | |
546 | - | ||
547 | /* Called for ATOM_ENCODER_MODE_HDMI only */ |
- | |
548 | if (!dig || !dig->afmt) { |
- | |
549 | WARN_ON(1); |
- | |
550 | return; |
- | |
551 | } |
- | |
552 | if (!dig->afmt->enabled) |
- | |
553 | return; |
- | |
Line 554... | Line -... | ||
554 | offset = dig->afmt->offset; |
- | |
555 | - | ||
556 | DRM_DEBUG("Disabling HDMI interface @ 0x%04X for encoder 0x%x\n", |
- | |
557 | offset, radeon_encoder->encoder_id); |
- | |
558 | - | ||
559 | /* disable irq */ |
- | |
560 | // radeon_irq_kms_disable_afmt(rdev, dig->afmt->id); |
- | |
561 | - | ||
562 | /* Older chipsets not handled by AtomBIOS */ |
- | |
563 | if (rdev->family >= CHIP_R600 && !ASIC_IS_DCE3(rdev)) { |
- | |
564 | switch (radeon_encoder->encoder_id) { |
- | |
565 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: |
- | |
566 | WREG32_P(AVIVO_TMDSA_CNTL, 0, |
- | |
567 | ~AVIVO_TMDSA_CNTL_HDMI_EN); |
- | |
568 | break; |
- | |
569 | case ENCODER_OBJECT_ID_INTERNAL_LVTM1: |
- | |
570 | WREG32_P(AVIVO_LVTMA_CNTL, 0, |
- | |
571 | ~AVIVO_LVTMA_CNTL_HDMI_EN); |
510 | // if (enable) |
572 | break; |
511 | // radeon_irq_kms_enable_afmt(rdev, dig->afmt->id); |
573 | case ENCODER_OBJECT_ID_INTERNAL_DDI: |
- | |
574 | WREG32_P(DDIA_CNTL, 0, ~DDIA_HDMI_EN); |
- | |
575 | break; |
- | |
576 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: |
512 | // else |
Line 577... | Line -... | ||
577 | break; |
- | |
578 | default: |
- |