Signed-off-by: Rafał Miłecki <zajec5@xxxxxxxxx> --- V3: the earlier V2 wasn't applied, so I resend it with some changes. I've switched HDMI block calculation to use register offsets known from CRCT. This should match better the rest of Evergreen code. Dave: this is on top of drm-radeon-testing containing few earlier patches Merry Christmas :) --- drivers/gpu/drm/radeon/evergreen_reg.h | 5 ++++ drivers/gpu/drm/radeon/r600_hdmi.c | 36 ++++++++++++++++++++++++------- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/radeon/evergreen_reg.h b/drivers/gpu/drm/radeon/evergreen_reg.h index 01cff84..fd38ba4 100644 --- a/drivers/gpu/drm/radeon/evergreen_reg.h +++ b/drivers/gpu/drm/radeon/evergreen_reg.h @@ -199,4 +199,9 @@ #define EVERGREEN_DC_GPIO_HPD_EN 0x64b8 #define EVERGREEN_DC_GPIO_HPD_Y 0x64bc +/* HDMI blocks at 0x7030, 0x7c30, 0x10830, 0x11430, 0x12030, 0x12c30 */ +#define EVERGREEN_HDMI_BASE 0x7030 + +#define EVERGREEN_HDMI_CONFIG_OFFSET 0xf0 + #endif diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index 3db76ac..2c70a85 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c @@ -320,7 +320,7 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod struct radeon_device *rdev = dev->dev_private; uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset; - if (ASIC_IS_DCE4(rdev)) + if (ASIC_IS_DCE5(rdev)) return; if (!offset) @@ -462,6 +462,15 @@ static void r600_hdmi_assign_block(struct drm_encoder *encoder) struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; + u16 eg_offsets[] = { + EVERGREEN_CRTC0_REGISTER_OFFSET, + EVERGREEN_CRTC1_REGISTER_OFFSET, + EVERGREEN_CRTC2_REGISTER_OFFSET, + EVERGREEN_CRTC3_REGISTER_OFFSET, + EVERGREEN_CRTC4_REGISTER_OFFSET, + EVERGREEN_CRTC5_REGISTER_OFFSET, + }; + if (!dig) { dev_err(rdev->dev, "Enabling HDMI on non-dig encoder\n"); return; @@ -470,7 +479,14 @@ static void r600_hdmi_assign_block(struct drm_encoder *encoder) if (ASIC_IS_DCE5(rdev)) { /* TODO */ } else if (ASIC_IS_DCE4(rdev)) { - /* TODO */ + if (dig->dig_encoder >= ARRAY_SIZE(eg_offsets)) { + dev_err(rdev->dev, "Enabling HDMI on unknown dig\n"); + return; + } + radeon_encoder->hdmi_offset = EVERGREEN_HDMI_BASE + + eg_offsets[dig->dig_encoder]; + radeon_encoder->hdmi_config_offset = radeon_encoder->hdmi_offset + + EVERGREEN_HDMI_CONFIG_OFFSET; } else if (ASIC_IS_DCE3(rdev)) { radeon_encoder->hdmi_offset = dig->dig_encoder ? R600_HDMI_BLOCK3 : R600_HDMI_BLOCK1; @@ -493,7 +509,7 @@ void r600_hdmi_enable(struct drm_encoder *encoder) struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); uint32_t offset; - if (ASIC_IS_DCE4(rdev)) + if (ASIC_IS_DCE5(rdev)) return; if (!radeon_encoder->hdmi_offset) { @@ -509,7 +525,7 @@ void r600_hdmi_enable(struct drm_encoder *encoder) if (ASIC_IS_DCE5(rdev)) { /* TODO */ } else if (ASIC_IS_DCE4(rdev)) { - /* TODO */ + WREG32_P(radeon_encoder->hdmi_config_offset + 0xc, 0x1, ~0x1); } else if (ASIC_IS_DCE32(rdev)) { WREG32_P(radeon_encoder->hdmi_config_offset + 0x4, 0x1, ~0x1); } else if (ASIC_IS_DCE3(rdev)) { @@ -533,8 +549,8 @@ void r600_hdmi_enable(struct drm_encoder *encoder) if (rdev->irq.installed && rdev->family != CHIP_RS600 && rdev->family != CHIP_RS690 - && rdev->family != CHIP_RS740) { - + && rdev->family != CHIP_RS740 + && !ASIC_IS_DCE4(rdev)) { /* if irq is available use it */ rdev->irq.hdmi[offset == R600_HDMI_BLOCK1 ? 0 : 1] = true; radeon_irq_set(rdev); @@ -559,7 +575,7 @@ void r600_hdmi_disable(struct drm_encoder *encoder) struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); uint32_t offset; - if (ASIC_IS_DCE4(rdev)) + if (ASIC_IS_DCE5(rdev)) return; offset = radeon_encoder->hdmi_offset; @@ -578,7 +594,11 @@ void r600_hdmi_disable(struct drm_encoder *encoder) /* disable polling */ r600_audio_disable_polling(encoder); - if (ASIC_IS_DCE32(rdev) && !ASIC_IS_DCE4(rdev)) { + if (ASIC_IS_DCE5(rdev)) { + /* TODO */ + } else if (ASIC_IS_DCE4(rdev)) { + WREG32_P(radeon_encoder->hdmi_config_offset + 0xc, 0, ~0x1); + } else if (ASIC_IS_DCE32(rdev)) { WREG32_P(radeon_encoder->hdmi_config_offset + 0x4, 0, ~0x1); } else if (rdev->family >= CHIP_R600 && !ASIC_IS_DCE3(rdev)) { switch (radeon_encoder->encoder_id) { -- 1.7.7 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel