aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/radeon/r600_hdmi.c71
1 files changed, 69 insertions, 2 deletions
diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c
index 5275a81b1df3..8fbfc73170fc 100644
--- a/drivers/gpu/drm/radeon/r600_hdmi.c
+++ b/drivers/gpu/drm/radeon/r600_hdmi.c
@@ -417,6 +417,39 @@ void r600_hdmi_update_audio_settings(struct drm_encoder *encoder,
417 WREG32_P(offset+R600_HDMI_CNTL, 0x04000000, ~0x04000000); 417 WREG32_P(offset+R600_HDMI_CNTL, 0x04000000, ~0x04000000);
418} 418}
419 419
420static int r600_hdmi_find_free_block(struct drm_device *dev)
421{
422 struct radeon_device *rdev = dev->dev_private;
423 struct drm_encoder *encoder;
424 struct radeon_encoder *radeon_encoder;
425 bool free_blocks[3] = { true, true, true };
426
427 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
428 radeon_encoder = to_radeon_encoder(encoder);
429 switch (radeon_encoder->hdmi_offset) {
430 case R600_HDMI_BLOCK1:
431 free_blocks[0] = false;
432 break;
433 case R600_HDMI_BLOCK2:
434 free_blocks[1] = false;
435 break;
436 case R600_HDMI_BLOCK3:
437 free_blocks[2] = false;
438 break;
439 }
440 }
441
442 if (rdev->family == CHIP_RS600 || rdev->family == CHIP_RS690) {
443 return free_blocks[0] ? R600_HDMI_BLOCK1 : 0;
444 } else if (rdev->family >= CHIP_R600) {
445 if (free_blocks[0])
446 return R600_HDMI_BLOCK1;
447 else if (free_blocks[1])
448 return R600_HDMI_BLOCK2;
449 }
450 return 0;
451}
452
420static void r600_hdmi_assign_block(struct drm_encoder *encoder) 453static void r600_hdmi_assign_block(struct drm_encoder *encoder)
421{ 454{
422 struct drm_device *dev = encoder->dev; 455 struct drm_device *dev = encoder->dev;
@@ -437,6 +470,8 @@ static void r600_hdmi_assign_block(struct drm_encoder *encoder)
437 if (ASIC_IS_DCE32(rdev)) 470 if (ASIC_IS_DCE32(rdev))
438 radeon_encoder->hdmi_config_offset = dig->dig_encoder ? 471 radeon_encoder->hdmi_config_offset = dig->dig_encoder ?
439 R600_HDMI_CONFIG2 : R600_HDMI_CONFIG1; 472 R600_HDMI_CONFIG2 : R600_HDMI_CONFIG1;
473 } else if (rdev->family >= CHIP_R600) {
474 radeon_encoder->hdmi_offset = r600_hdmi_find_free_block(dev);
440 } 475 }
441} 476}
442 477
@@ -458,8 +493,24 @@ void r600_hdmi_enable(struct drm_encoder *encoder)
458 } 493 }
459 } 494 }
460 495
461 if (ASIC_IS_DCE32(rdev) && !ASIC_IS_DCE4(rdev)) 496 if (ASIC_IS_DCE32(rdev) && !ASIC_IS_DCE4(rdev)) {
462 WREG32_P(radeon_encoder->hdmi_config_offset + 0x4, 0x1, ~0x1); 497 WREG32_P(radeon_encoder->hdmi_config_offset + 0x4, 0x1, ~0x1);
498 } else if (rdev->family >= CHIP_R600 && !ASIC_IS_DCE3(rdev)) {
499 int offset = radeon_encoder->hdmi_offset;
500 switch (radeon_encoder->encoder_id) {
501 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
502 WREG32_P(AVIVO_TMDSA_CNTL, 0x4, ~0x4);
503 WREG32(offset + R600_HDMI_ENABLE, 0x101);
504 break;
505 case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
506 WREG32_P(AVIVO_LVTMA_CNTL, 0x4, ~0x4);
507 WREG32(offset + R600_HDMI_ENABLE, 0x105);
508 break;
509 default:
510 dev_err(rdev->dev, "Unknown HDMI output type\n");
511 break;
512 }
513 }
463 514
464 DRM_DEBUG("Enabling HDMI interface @ 0x%04X for encoder 0x%x\n", 515 DRM_DEBUG("Enabling HDMI interface @ 0x%04X for encoder 0x%x\n",
465 radeon_encoder->hdmi_offset, radeon_encoder->encoder_id); 516 radeon_encoder->hdmi_offset, radeon_encoder->encoder_id);
@@ -482,8 +533,24 @@ void r600_hdmi_disable(struct drm_encoder *encoder)
482 DRM_DEBUG("Disabling HDMI interface @ 0x%04X for encoder 0x%x\n", 533 DRM_DEBUG("Disabling HDMI interface @ 0x%04X for encoder 0x%x\n",
483 radeon_encoder->hdmi_offset, radeon_encoder->encoder_id); 534 radeon_encoder->hdmi_offset, radeon_encoder->encoder_id);
484 535
485 if (ASIC_IS_DCE32(rdev) && !ASIC_IS_DCE4(rdev)) 536 if (ASIC_IS_DCE32(rdev) && !ASIC_IS_DCE4(rdev)) {
486 WREG32_P(radeon_encoder->hdmi_config_offset + 0x4, 0, ~0x1); 537 WREG32_P(radeon_encoder->hdmi_config_offset + 0x4, 0, ~0x1);
538 } else if (rdev->family >= CHIP_R600 && !ASIC_IS_DCE3(rdev)) {
539 int offset = radeon_encoder->hdmi_offset;
540 switch (radeon_encoder->encoder_id) {
541 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
542 WREG32_P(AVIVO_TMDSA_CNTL, 0, ~0x4);
543 WREG32(offset + R600_HDMI_ENABLE, 0);
544 break;
545 case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
546 WREG32_P(AVIVO_LVTMA_CNTL, 0, ~0x4);
547 WREG32(offset + R600_HDMI_ENABLE, 0);
548 break;
549 default:
550 dev_err(rdev->dev, "Unknown HDMI output type\n");
551 break;
552 }
553 }
487 554
488 radeon_encoder->hdmi_offset = 0; 555 radeon_encoder->hdmi_offset = 0;
489 radeon_encoder->hdmi_config_offset = 0; 556 radeon_encoder->hdmi_config_offset = 0;