2010/3/8 Rafał Miłecki <zaj...@gmail.com>: > We almost always used first HDMI block for first encoder and second for > sencod. > Exception was KLDSCP_LVTMA. Analyzing code picking DIG encoder shows the same > behaviour. It shows HDMI block are related to DIGs, which relation we now use. > > Signed-off-by: Rafał Miłecki <zaj...@gmail.com> > --- > V2: drop unnecessary check for dig, we set audio on HDMI connectors only > --- > drivers/gpu/drm/radeon/r600_audio.c | 7 ++- > drivers/gpu/drm/radeon/r600_hdmi.c | 114 > +++++++++++++----------------- > drivers/gpu/drm/radeon/radeon.h | 3 +- > drivers/gpu/drm/radeon/radeon_encoders.c | 10 ++-- > 4 files changed, 62 insertions(+), 72 deletions(-) > > diff --git a/drivers/gpu/drm/radeon/r600_audio.c > b/drivers/gpu/drm/radeon/r600_audio.c > index db92801..baf222f 100644 > --- a/drivers/gpu/drm/radeon/r600_audio.c > +++ b/drivers/gpu/drm/radeon/r600_audio.c > @@ -224,6 +224,7 @@ void r600_audio_set_clock(struct drm_encoder *encoder, > int clock) > struct drm_device *dev = encoder->dev; > struct radeon_device *rdev = dev->dev_private; > struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); > + struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; > int base_rate = 48000; > > switch (radeon_encoder->encoder_id) { > @@ -245,7 +246,7 @@ void r600_audio_set_clock(struct drm_encoder *encoder, > int clock) > return; > } > > - switch (r600_audio_tmds_index(encoder)) { > + switch (dig->dig_encoder) { > case 0: > WREG32(R600_AUDIO_PLL1_MUL, base_rate*50); > WREG32(R600_AUDIO_PLL1_DIV, clock*100); > @@ -257,6 +258,10 @@ void r600_audio_set_clock(struct drm_encoder *encoder, > int clock) > WREG32(R600_AUDIO_PLL2_DIV, clock*100); > WREG32(R600_AUDIO_CLK_SRCSEL, 1); > break; > + default: > + dev_err(rdev->dev, "Unsupported DIG on encoder 0x%02X\n", > + radeon_encoder->encoder_id); > + return; > } > } > > diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c > b/drivers/gpu/drm/radeon/r600_hdmi.c > index 4d09973..5275a81 100644 > --- a/drivers/gpu/drm/radeon/r600_hdmi.c > +++ b/drivers/gpu/drm/radeon/r600_hdmi.c > @@ -417,90 +417,74 @@ void r600_hdmi_update_audio_settings(struct drm_encoder > *encoder, > WREG32_P(offset+R600_HDMI_CNTL, 0x04000000, ~0x04000000); > } > > -/* > - * enable/disable the HDMI engine > - */ > -void r600_hdmi_enable(struct drm_encoder *encoder, int enable) > +static void r600_hdmi_assign_block(struct drm_encoder *encoder) > { > struct drm_device *dev = encoder->dev; > struct radeon_device *rdev = dev->dev_private; > struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); > - uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset; > + struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; > > - if (!offset) > + if (!dig) { > + dev_err(rdev->dev, "Enabling HDMI on non-dig encoder\n"); > return; > + } > > - DRM_DEBUG("%s HDMI interface @ 0x%04X\n", enable ? "Enabling" : > "Disabling", offset); > - > - /* some version of atombios ignore the enable HDMI flag > - * so enabling/disabling HDMI was moved here for TMDS1+2 */ > - switch (radeon_encoder->encoder_id) { > - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: > - WREG32_P(AVIVO_TMDSA_CNTL, enable ? 0x4 : 0x0, ~0x4); > - WREG32(offset+R600_HDMI_ENABLE, enable ? 0x101 : 0x0); > - break; > - > - case ENCODER_OBJECT_ID_INTERNAL_LVTM1: > - WREG32_P(AVIVO_LVTMA_CNTL, enable ? 0x4 : 0x0, ~0x4); > - WREG32(offset+R600_HDMI_ENABLE, enable ? 0x105 : 0x0); > - break; > - > - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: > - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: > - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: > - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: > - /* This part is doubtfull in my opinion */ > - WREG32(offset+R600_HDMI_ENABLE, enable ? 0x110 : 0x0); > - break; > - > - default: > - DRM_ERROR("unknown HDMI output type\n"); > - break; > + if (ASIC_IS_DCE4(rdev)) { > + /* TODO */ > + } else if (ASIC_IS_DCE3(rdev)) { > + radeon_encoder->hdmi_offset = dig->dig_encoder ? > + R600_HDMI_BLOCK3 : R600_HDMI_BLOCK1; > + if (ASIC_IS_DCE32(rdev)) > + radeon_encoder->hdmi_config_offset = dig->dig_encoder > ? > + R600_HDMI_CONFIG2 : R600_HDMI_CONFIG1; > } > } > > /* > - * determin at which register offset the HDMI encoder is > + * enable the HDMI engine > */ > -void r600_hdmi_init(struct drm_encoder *encoder) > +void r600_hdmi_enable(struct drm_encoder *encoder) > { > + struct drm_device *dev = encoder->dev; > + struct radeon_device *rdev = dev->dev_private; > struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); > > - switch (radeon_encoder->encoder_id) { > - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: > - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: > - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: > - radeon_encoder->hdmi_offset = R600_HDMI_BLOCK1; > - break; > - > - case ENCODER_OBJECT_ID_INTERNAL_LVTM1: > - switch (r600_audio_tmds_index(encoder)) { > - case 0: > - radeon_encoder->hdmi_offset = R600_HDMI_BLOCK1; > - break; > - case 1: > - radeon_encoder->hdmi_offset = R600_HDMI_BLOCK2; > - break; > - default: > - radeon_encoder->hdmi_offset = 0; > - break; > + if (!radeon_encoder->hdmi_offset) { > + r600_hdmi_assign_block(encoder); > + if (!radeon_encoder->hdmi_offset) { > + dev_warn(rdev->dev, "Could not find HDMI block for " > + "0x%x encoder\n", radeon_encoder->encoder_id); > + return; > } > - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: > - radeon_encoder->hdmi_offset = R600_HDMI_BLOCK2; > - break; > + } > > - case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: > - radeon_encoder->hdmi_offset = R600_HDMI_BLOCK3; > - break; > + if (ASIC_IS_DCE32(rdev) && !ASIC_IS_DCE4(rdev)) > + WREG32_P(radeon_encoder->hdmi_config_offset + 0x4, 0x1, ~0x1); > + > + DRM_DEBUG("Enabling HDMI interface @ 0x%04X for encoder 0x%x\n", > + radeon_encoder->hdmi_offset, radeon_encoder->encoder_id); > +} > > - default: > - radeon_encoder->hdmi_offset = 0; > - break; > +/* > + * disable the HDMI engine > + */ > +void r600_hdmi_disable(struct drm_encoder *encoder) > +{ > + struct drm_device *dev = encoder->dev; > + struct radeon_device *rdev = dev->dev_private; > + struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); > + > + if (!radeon_encoder->hdmi_offset) { > + dev_err(rdev->dev, "Disabling not enabled HDMI\n"); > + return; > } > > - DRM_DEBUG("using HDMI engine at offset 0x%04X for encoder 0x%x\n", > - radeon_encoder->hdmi_offset, radeon_encoder->encoder_id); > + 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)) > + WREG32_P(radeon_encoder->hdmi_config_offset + 0x4, 0, ~0x1); > > - /* TODO: make this configureable */ > - radeon_encoder->hdmi_audio_workaround = 0; > + radeon_encoder->hdmi_offset = 0; > + radeon_encoder->hdmi_config_offset = 0; > } > diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h > index 0d7caee..b54d4f3 100644 > --- a/drivers/gpu/drm/radeon/radeon.h > +++ b/drivers/gpu/drm/radeon/radeon.h > @@ -1323,7 +1323,8 @@ extern int r600_audio_tmds_index(struct drm_encoder > *encoder); > extern void r600_audio_set_clock(struct drm_encoder *encoder, int clock); > extern void r600_audio_fini(struct radeon_device *rdev); > extern void r600_hdmi_init(struct drm_encoder *encoder); > -extern void r600_hdmi_enable(struct drm_encoder *encoder, int enable); > +extern void r600_hdmi_enable(struct drm_encoder *encoder); > +extern void r600_hdmi_disable(struct drm_encoder *encoder); > extern void r600_hdmi_setmode(struct drm_encoder *encoder, struct > drm_display_mode *mode); > extern int r600_hdmi_buffer_status_changed(struct drm_encoder *encoder); > extern void r600_hdmi_update_audio_settings(struct drm_encoder *encoder, > diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c > b/drivers/gpu/drm/radeon/radeon_encoders.c > index bc926ea..7f43476 100644 > --- a/drivers/gpu/drm/radeon/radeon_encoders.c > +++ b/drivers/gpu/drm/radeon/radeon_encoders.c > @@ -593,7 +593,6 @@ atombios_digital_setup(struct drm_encoder *encoder, int > action) > } > > atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t > *)&args); > - r600_hdmi_enable(encoder, hdmi_detected); > } > > int > @@ -1396,9 +1395,10 @@ radeon_atom_encoder_mode_set(struct drm_encoder > *encoder, > } > atombios_apply_encoder_quirks(encoder, adjusted_mode); > > - /* XXX */ > - if (!ASIC_IS_DCE4(rdev)) > + if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) { > + r600_hdmi_enable(encoder); > r600_hdmi_setmode(encoder, adjusted_mode); > + } > } > > static bool > @@ -1509,6 +1509,8 @@ static void radeon_atom_encoder_disable(struct > drm_encoder *encoder) > radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); > > if (radeon_encoder_is_digital(encoder)) { > + if (atombios_get_encoder_mode(encoder) == > ATOM_ENCODER_MODE_HDMI) > + r600_hdmi_disable(encoder); > dig = radeon_encoder->enc_priv; > dig->dig_encoder = -1; > } > @@ -1659,6 +1661,4 @@ radeon_add_atom_encoder(struct drm_device *dev, > uint32_t encoder_id, uint32_t su > drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs); > break; > } > - > - r600_hdmi_init(encoder); > } > -- > 1.6.4.2 > > > ------------------------------------------------------------------------------ > Download Intel® Parallel Studio Eval > Try the new software tools for yourself. Speed compiling, find bugs > proactively, and fine-tune applications for parallel performance. > See why Intel Parallel Studio got high marks during beta. > http://p.sf.net/sfu/intel-sw-dev > -- > _______________________________________________ > Dri-devel mailing list > Dri-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/dri-devel >
I'll test this new patch tonight ------------------------------------------------------------------------------ Download Intel® Parallel Studio Eval Try the new software tools for yourself. Speed compiling, find bugs proactively, and fine-tune applications for parallel performance. See why Intel Parallel Studio got high marks during beta. http://p.sf.net/sfu/intel-sw-dev -- _______________________________________________ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel