2011/12/7 Rafa? Mi?ecki <zajec5 at gmail.com>: > > Signed-off-by: Rafa? Mi?ecki <zajec5 at gmail.com> > --- > ?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 > >