drm/radeon/kms: add HDMI code for pre-DCE3 R6xx GPUs
Older GPUs are little different, HDMI blocks are not hard-wired, but routable. We should just find some free HDMI block and route it to choosen encoder. In case of RS6x0 there is only one HDMI block, we don't enable HDMI on RS6x00 yet however. Signed-off-by: Rafał Miłecki <zajec5@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
parent
2cd6218cb8
commit
5715f67cec
1 changed files with 69 additions and 2 deletions
|
@ -417,6 +417,39 @@ void r600_hdmi_update_audio_settings(struct drm_encoder *encoder,
|
|||
WREG32_P(offset+R600_HDMI_CNTL, 0x04000000, ~0x04000000);
|
||||
}
|
||||
|
||||
static int r600_hdmi_find_free_block(struct drm_device *dev)
|
||||
{
|
||||
struct radeon_device *rdev = dev->dev_private;
|
||||
struct drm_encoder *encoder;
|
||||
struct radeon_encoder *radeon_encoder;
|
||||
bool free_blocks[3] = { true, true, true };
|
||||
|
||||
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
|
||||
radeon_encoder = to_radeon_encoder(encoder);
|
||||
switch (radeon_encoder->hdmi_offset) {
|
||||
case R600_HDMI_BLOCK1:
|
||||
free_blocks[0] = false;
|
||||
break;
|
||||
case R600_HDMI_BLOCK2:
|
||||
free_blocks[1] = false;
|
||||
break;
|
||||
case R600_HDMI_BLOCK3:
|
||||
free_blocks[2] = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (rdev->family == CHIP_RS600 || rdev->family == CHIP_RS690) {
|
||||
return free_blocks[0] ? R600_HDMI_BLOCK1 : 0;
|
||||
} else if (rdev->family >= CHIP_R600) {
|
||||
if (free_blocks[0])
|
||||
return R600_HDMI_BLOCK1;
|
||||
else if (free_blocks[1])
|
||||
return R600_HDMI_BLOCK2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void r600_hdmi_assign_block(struct drm_encoder *encoder)
|
||||
{
|
||||
struct drm_device *dev = encoder->dev;
|
||||
|
@ -437,6 +470,8 @@ static void r600_hdmi_assign_block(struct drm_encoder *encoder)
|
|||
if (ASIC_IS_DCE32(rdev))
|
||||
radeon_encoder->hdmi_config_offset = dig->dig_encoder ?
|
||||
R600_HDMI_CONFIG2 : R600_HDMI_CONFIG1;
|
||||
} else if (rdev->family >= CHIP_R600) {
|
||||
radeon_encoder->hdmi_offset = r600_hdmi_find_free_block(dev);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -458,8 +493,24 @@ void r600_hdmi_enable(struct drm_encoder *encoder)
|
|||
}
|
||||
}
|
||||
|
||||
if (ASIC_IS_DCE32(rdev) && !ASIC_IS_DCE4(rdev))
|
||||
if (ASIC_IS_DCE32(rdev) && !ASIC_IS_DCE4(rdev)) {
|
||||
WREG32_P(radeon_encoder->hdmi_config_offset + 0x4, 0x1, ~0x1);
|
||||
} else if (rdev->family >= CHIP_R600 && !ASIC_IS_DCE3(rdev)) {
|
||||
int offset = radeon_encoder->hdmi_offset;
|
||||
switch (radeon_encoder->encoder_id) {
|
||||
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
|
||||
WREG32_P(AVIVO_TMDSA_CNTL, 0x4, ~0x4);
|
||||
WREG32(offset + R600_HDMI_ENABLE, 0x101);
|
||||
break;
|
||||
case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
|
||||
WREG32_P(AVIVO_LVTMA_CNTL, 0x4, ~0x4);
|
||||
WREG32(offset + R600_HDMI_ENABLE, 0x105);
|
||||
break;
|
||||
default:
|
||||
dev_err(rdev->dev, "Unknown HDMI output type\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DRM_DEBUG("Enabling HDMI interface @ 0x%04X for encoder 0x%x\n",
|
||||
radeon_encoder->hdmi_offset, radeon_encoder->encoder_id);
|
||||
|
@ -482,8 +533,24 @@ void r600_hdmi_disable(struct drm_encoder *encoder)
|
|||
DRM_DEBUG("Disabling HDMI interface @ 0x%04X for encoder 0x%x\n",
|
||||
radeon_encoder->hdmi_offset, radeon_encoder->encoder_id);
|
||||
|
||||
if (ASIC_IS_DCE32(rdev) && !ASIC_IS_DCE4(rdev))
|
||||
if (ASIC_IS_DCE32(rdev) && !ASIC_IS_DCE4(rdev)) {
|
||||
WREG32_P(radeon_encoder->hdmi_config_offset + 0x4, 0, ~0x1);
|
||||
} else if (rdev->family >= CHIP_R600 && !ASIC_IS_DCE3(rdev)) {
|
||||
int offset = radeon_encoder->hdmi_offset;
|
||||
switch (radeon_encoder->encoder_id) {
|
||||
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
|
||||
WREG32_P(AVIVO_TMDSA_CNTL, 0, ~0x4);
|
||||
WREG32(offset + R600_HDMI_ENABLE, 0);
|
||||
break;
|
||||
case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
|
||||
WREG32_P(AVIVO_LVTMA_CNTL, 0, ~0x4);
|
||||
WREG32(offset + R600_HDMI_ENABLE, 0);
|
||||
break;
|
||||
default:
|
||||
dev_err(rdev->dev, "Unknown HDMI output type\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
radeon_encoder->hdmi_offset = 0;
|
||||
radeon_encoder->hdmi_config_offset = 0;
|
||||
|
|
Loading…
Reference in a new issue