2011/12/7 Rafał Miłecki <zajec5@xxxxxxxxx>: > > Signed-off-by: Rafał Miłecki <zajec5@xxxxxxxxx> > --- > drivers/gpu/drm/radeon/evergreen_reg.h | 10 +++++++ > drivers/gpu/drm/radeon/r600_hdmi.c | 44 ++++++++++++++++++++++++++------ > 2 files changed, 46 insertions(+), 8 deletions(-) > > diff --git a/drivers/gpu/drm/radeon/evergreen_reg.h b/drivers/gpu/drm/radeon/evergreen_reg.h > index 01cff84..ce4414d 100644 > --- a/drivers/gpu/drm/radeon/evergreen_reg.h > +++ b/drivers/gpu/drm/radeon/evergreen_reg.h > @@ -199,4 +199,14 @@ > #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_BLOCK0 0x7030 > +#define EVERGREEN_HDMI_BLOCK1 0x7c30 > +#define EVERGREEN_HDMI_BLOCK2 0x10830 > +#define EVERGREEN_HDMI_BLOCK3 0x11430 > +#define EVERGREEN_HDMI_BLOCK4 0x12030 > +#define EVERGREEN_HDMI_BLOCK5 0x12c30 > + > +#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 06f923e..9612080 100644 > --- a/drivers/gpu/drm/radeon/r600_hdmi.c > +++ b/drivers/gpu/drm/radeon/r600_hdmi.c > @@ -313,7 +313,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) > @@ -463,7 +463,31 @@ static void r600_hdmi_assign_block(struct drm_encoder *encoder) > if (ASIC_IS_DCE5(rdev)) { > /* TODO */ > } else if (ASIC_IS_DCE4(rdev)) { > - /* TODO */ > + switch (dig->dig_encoder) { > + case 0: > + radeon_encoder->hdmi_offset = EVERGREEN_HDMI_BLOCK0; > + break; > + case 1: > + radeon_encoder->hdmi_offset = EVERGREEN_HDMI_BLOCK1; > + break; > + case 2: > + radeon_encoder->hdmi_offset = EVERGREEN_HDMI_BLOCK2; > + break; > + case 3: > + radeon_encoder->hdmi_offset = EVERGREEN_HDMI_BLOCK3; > + break; > + case 4: > + radeon_encoder->hdmi_offset = EVERGREEN_HDMI_BLOCK4; > + break; > + case 5: > + radeon_encoder->hdmi_offset = EVERGREEN_HDMI_BLOCK5; > + break; > + default: > + dev_err(rdev->dev, "Enabling HDMI on unknown dig\n"); > + return; > + } > + 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; > @@ -486,7 +510,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) { > @@ -502,7 +526,10 @@ void r600_hdmi_enable(struct drm_encoder *encoder) > if (ASIC_IS_DCE5(rdev)) { > /* TODO */ > } else if (ASIC_IS_DCE4(rdev)) { > - /* TODO */ > + /* This -= 0x30 looks a little tricky, but it's just touching > + * dig encoder register that lies a little before HDMI block. */ > + WREG32_P(radeon_encoder->hdmi_offset - 0x30, 0x1000, ~0x1000); You shouldn't program 0x7000 (DIG_CNTL) here. It's already programmed via the atom atombios_dig_encoder_setup() when action=ATOM_ENCODER_CMD_SETUP based on how you set the ucEncoderMode parameter (DP, LVDS, DVI, HDMI -- set by atombios_get_encoder_mode()). DIG_CNTL.DIG_MODE is a 3 bit field and changing just 1 bit change the encoder type which may cause problems depending on how the dig encoder is set up. > + 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)) { > @@ -526,8 +553,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); > @@ -552,7 +579,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; > @@ -574,7 +601,8 @@ void r600_hdmi_disable(struct drm_encoder *encoder) > if (ASIC_IS_DCE5(rdev)) { > /* TODO */ > } else if (ASIC_IS_DCE4(rdev)) { > - /* TODO */ > + WREG32_P(radeon_encoder->hdmi_offset - 0x30, 0, ~0x1000); Remove the write to 0x7000 here as well. See my comment above. > + 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 (ASIC_IS_DCE3(rdev)) { > -- > 1.7.3.4 > > _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel