aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/r600_hdmi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/radeon/r600_hdmi.c')
-rw-r--r--drivers/gpu/drm/radeon/r600_hdmi.c65
1 files changed, 52 insertions, 13 deletions
diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c
index f5ac7e788d8..0b592067145 100644
--- a/drivers/gpu/drm/radeon/r600_hdmi.c
+++ b/drivers/gpu/drm/radeon/r600_hdmi.c
@@ -196,6 +196,13 @@ static void r600_hdmi_videoinfoframe(
196 frame[0xD] = (right_bar >> 8); 196 frame[0xD] = (right_bar >> 8);
197 197
198 r600_hdmi_infoframe_checksum(0x82, 0x02, 0x0D, frame); 198 r600_hdmi_infoframe_checksum(0x82, 0x02, 0x0D, frame);
199 /* Our header values (type, version, length) should be alright, Intel
200 * is using the same. Checksum function also seems to be OK, it works
201 * fine for audio infoframe. However calculated value is always lower
202 * by 2 in comparison to fglrx. It breaks displaying anything in case
203 * of TVs that strictly check the checksum. Hack it manually here to
204 * workaround this issue. */
205 frame[0x0] += 2;
199 206
200 WREG32(offset+R600_HDMI_VIDEOINFOFRAME_0, 207 WREG32(offset+R600_HDMI_VIDEOINFOFRAME_0,
201 frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24)); 208 frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24));
@@ -313,7 +320,7 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod
313 struct radeon_device *rdev = dev->dev_private; 320 struct radeon_device *rdev = dev->dev_private;
314 uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset; 321 uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset;
315 322
316 if (ASIC_IS_DCE4(rdev)) 323 if (ASIC_IS_DCE5(rdev))
317 return; 324 return;
318 325
319 if (!offset) 326 if (!offset)
@@ -455,13 +462,31 @@ static void r600_hdmi_assign_block(struct drm_encoder *encoder)
455 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 462 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
456 struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; 463 struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
457 464
465 u16 eg_offsets[] = {
466 EVERGREEN_CRTC0_REGISTER_OFFSET,
467 EVERGREEN_CRTC1_REGISTER_OFFSET,
468 EVERGREEN_CRTC2_REGISTER_OFFSET,
469 EVERGREEN_CRTC3_REGISTER_OFFSET,
470 EVERGREEN_CRTC4_REGISTER_OFFSET,
471 EVERGREEN_CRTC5_REGISTER_OFFSET,
472 };
473
458 if (!dig) { 474 if (!dig) {
459 dev_err(rdev->dev, "Enabling HDMI on non-dig encoder\n"); 475 dev_err(rdev->dev, "Enabling HDMI on non-dig encoder\n");
460 return; 476 return;
461 } 477 }
462 478
463 if (ASIC_IS_DCE4(rdev)) { 479 if (ASIC_IS_DCE5(rdev)) {
464 /* TODO */ 480 /* TODO */
481 } else if (ASIC_IS_DCE4(rdev)) {
482 if (dig->dig_encoder >= ARRAY_SIZE(eg_offsets)) {
483 dev_err(rdev->dev, "Enabling HDMI on unknown dig\n");
484 return;
485 }
486 radeon_encoder->hdmi_offset = EVERGREEN_HDMI_BASE +
487 eg_offsets[dig->dig_encoder];
488 radeon_encoder->hdmi_config_offset = radeon_encoder->hdmi_offset
489 + EVERGREEN_HDMI_CONFIG_OFFSET;
465 } else if (ASIC_IS_DCE3(rdev)) { 490 } else if (ASIC_IS_DCE3(rdev)) {
466 radeon_encoder->hdmi_offset = dig->dig_encoder ? 491 radeon_encoder->hdmi_offset = dig->dig_encoder ?
467 R600_HDMI_BLOCK3 : R600_HDMI_BLOCK1; 492 R600_HDMI_BLOCK3 : R600_HDMI_BLOCK1;
@@ -484,7 +509,7 @@ void r600_hdmi_enable(struct drm_encoder *encoder)
484 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 509 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
485 uint32_t offset; 510 uint32_t offset;
486 511
487 if (ASIC_IS_DCE4(rdev)) 512 if (ASIC_IS_DCE5(rdev))
488 return; 513 return;
489 514
490 if (!radeon_encoder->hdmi_offset) { 515 if (!radeon_encoder->hdmi_offset) {
@@ -497,16 +522,24 @@ void r600_hdmi_enable(struct drm_encoder *encoder)
497 } 522 }
498 523
499 offset = radeon_encoder->hdmi_offset; 524 offset = radeon_encoder->hdmi_offset;
500 if (ASIC_IS_DCE32(rdev) && !ASIC_IS_DCE4(rdev)) { 525 if (ASIC_IS_DCE5(rdev)) {
526 /* TODO */
527 } else if (ASIC_IS_DCE4(rdev)) {
528 WREG32_P(radeon_encoder->hdmi_config_offset + 0xc, 0x1, ~0x1);
529 } else if (ASIC_IS_DCE32(rdev)) {
501 WREG32_P(radeon_encoder->hdmi_config_offset + 0x4, 0x1, ~0x1); 530 WREG32_P(radeon_encoder->hdmi_config_offset + 0x4, 0x1, ~0x1);
502 } else if (rdev->family >= CHIP_R600 && !ASIC_IS_DCE3(rdev)) { 531 } else if (ASIC_IS_DCE3(rdev)) {
532 /* TODO */
533 } else if (rdev->family >= CHIP_R600) {
503 switch (radeon_encoder->encoder_id) { 534 switch (radeon_encoder->encoder_id) {
504 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: 535 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
505 WREG32_P(AVIVO_TMDSA_CNTL, 0x4, ~0x4); 536 WREG32_P(AVIVO_TMDSA_CNTL, AVIVO_TMDSA_CNTL_HDMI_EN,
537 ~AVIVO_TMDSA_CNTL_HDMI_EN);
506 WREG32(offset + R600_HDMI_ENABLE, 0x101); 538 WREG32(offset + R600_HDMI_ENABLE, 0x101);
507 break; 539 break;
508 case ENCODER_OBJECT_ID_INTERNAL_LVTM1: 540 case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
509 WREG32_P(AVIVO_LVTMA_CNTL, 0x4, ~0x4); 541 WREG32_P(AVIVO_LVTMA_CNTL, AVIVO_LVTMA_CNTL_HDMI_EN,
542 ~AVIVO_LVTMA_CNTL_HDMI_EN);
510 WREG32(offset + R600_HDMI_ENABLE, 0x105); 543 WREG32(offset + R600_HDMI_ENABLE, 0x105);
511 break; 544 break;
512 default: 545 default:
@@ -518,8 +551,8 @@ void r600_hdmi_enable(struct drm_encoder *encoder)
518 if (rdev->irq.installed 551 if (rdev->irq.installed
519 && rdev->family != CHIP_RS600 552 && rdev->family != CHIP_RS600
520 && rdev->family != CHIP_RS690 553 && rdev->family != CHIP_RS690
521 && rdev->family != CHIP_RS740) { 554 && rdev->family != CHIP_RS740
522 555 && !ASIC_IS_DCE4(rdev)) {
523 /* if irq is available use it */ 556 /* if irq is available use it */
524 rdev->irq.hdmi[offset == R600_HDMI_BLOCK1 ? 0 : 1] = true; 557 rdev->irq.hdmi[offset == R600_HDMI_BLOCK1 ? 0 : 1] = true;
525 radeon_irq_set(rdev); 558 radeon_irq_set(rdev);
@@ -544,7 +577,7 @@ void r600_hdmi_disable(struct drm_encoder *encoder)
544 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 577 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
545 uint32_t offset; 578 uint32_t offset;
546 579
547 if (ASIC_IS_DCE4(rdev)) 580 if (ASIC_IS_DCE5(rdev))
548 return; 581 return;
549 582
550 offset = radeon_encoder->hdmi_offset; 583 offset = radeon_encoder->hdmi_offset;
@@ -563,16 +596,22 @@ void r600_hdmi_disable(struct drm_encoder *encoder)
563 /* disable polling */ 596 /* disable polling */
564 r600_audio_disable_polling(encoder); 597 r600_audio_disable_polling(encoder);
565 598
566 if (ASIC_IS_DCE32(rdev) && !ASIC_IS_DCE4(rdev)) { 599 if (ASIC_IS_DCE5(rdev)) {
600 /* TODO */
601 } else if (ASIC_IS_DCE4(rdev)) {
602 WREG32_P(radeon_encoder->hdmi_config_offset + 0xc, 0, ~0x1);
603 } else if (ASIC_IS_DCE32(rdev)) {
567 WREG32_P(radeon_encoder->hdmi_config_offset + 0x4, 0, ~0x1); 604 WREG32_P(radeon_encoder->hdmi_config_offset + 0x4, 0, ~0x1);
568 } else if (rdev->family >= CHIP_R600 && !ASIC_IS_DCE3(rdev)) { 605 } else if (rdev->family >= CHIP_R600 && !ASIC_IS_DCE3(rdev)) {
569 switch (radeon_encoder->encoder_id) { 606 switch (radeon_encoder->encoder_id) {
570 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: 607 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
571 WREG32_P(AVIVO_TMDSA_CNTL, 0, ~0x4); 608 WREG32_P(AVIVO_TMDSA_CNTL, 0,
609 ~AVIVO_TMDSA_CNTL_HDMI_EN);
572 WREG32(offset + R600_HDMI_ENABLE, 0); 610 WREG32(offset + R600_HDMI_ENABLE, 0);
573 break; 611 break;
574 case ENCODER_OBJECT_ID_INTERNAL_LVTM1: 612 case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
575 WREG32_P(AVIVO_LVTMA_CNTL, 0, ~0x4); 613 WREG32_P(AVIVO_LVTMA_CNTL, 0,
614 ~AVIVO_LVTMA_CNTL_HDMI_EN);
576 WREG32(offset + R600_HDMI_ENABLE, 0); 615 WREG32(offset + R600_HDMI_ENABLE, 0);
577 break; 616 break;
578 default: 617 default: