On Fri, May 16, 2014 at 5:36 AM, Rafał Miłecki <zajec5@xxxxxxxxx> wrote: > DCE 3.1 and 3.2 should be programmed in a different way than DCE 2 and > DCE 3. The order of setting registers and sets of registers are > different. > It's still unsure how we will handle DCE 3.1 vs. DCE 3.2, since they > have few differences as well. > For now separate DCE 2 and DCE 3 path, so we can work on it without a > risk of breaking DCE 3.1+. > > This has been tested for possible regressions on DCE32 HD4550 (RV710). > > Signed-off-by: Rafał Miłecki <zajec5@xxxxxxxxx> Added the series to my 3.16 queue. Alex > --- > V4: Add Copyright header. Alex is an author of > dce3_2_afmt_write_speaker_allocation > dce3_2_afmt_write_sad_regs > and I'm pretty much an author of > dce3_1_hdmi_setmode > --- > drivers/gpu/drm/radeon/Makefile | 2 +- > drivers/gpu/drm/radeon/dce3_1_afmt.c | 244 +++++++++++++++++++++++++++++++++++ > drivers/gpu/drm/radeon/r600_hdmi.c | 149 ++------------------- > drivers/gpu/drm/radeon/radeon_asic.c | 2 +- > drivers/gpu/drm/radeon/radeon_asic.h | 7 + > 5 files changed, 263 insertions(+), 141 deletions(-) > create mode 100644 drivers/gpu/drm/radeon/dce3_1_afmt.c > > diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile > index 0943353..dbcbfe8 100644 > --- a/drivers/gpu/drm/radeon/Makefile > +++ b/drivers/gpu/drm/radeon/Makefile > @@ -72,7 +72,7 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \ > radeon_cs.o radeon_bios.o radeon_benchmark.o r100.o r300.o r420.o \ > rs400.o rs600.o rs690.o rv515.o r520.o r600.o rv770.o radeon_test.o \ > r200.o radeon_legacy_tv.o r600_cs.o r600_blit_shaders.o \ > - radeon_pm.o atombios_dp.o r600_audio.o r600_hdmi.o \ > + radeon_pm.o atombios_dp.o r600_audio.o r600_hdmi.o dce3_1_afmt.o \ > evergreen.o evergreen_cs.o evergreen_blit_shaders.o \ > evergreen_hdmi.o radeon_trace_points.o ni.o cayman_blit_shaders.o \ > atombios_encoders.o radeon_semaphore.o radeon_sa.o atombios_i2c.o si.o \ > diff --git a/drivers/gpu/drm/radeon/dce3_1_afmt.c b/drivers/gpu/drm/radeon/dce3_1_afmt.c > new file mode 100644 > index 0000000..51800e3 > --- /dev/null > +++ b/drivers/gpu/drm/radeon/dce3_1_afmt.c > @@ -0,0 +1,244 @@ > +/* > + * Copyright 2013 Advanced Micro Devices, Inc. > + * Copyright 2014 Rafał Miłecki > + * > + * Permission is hereby granted, free of charge, to any person obtaining a > + * copy of this software and associated documentation files (the "Software"), > + * to deal in the Software without restriction, including without limitation > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > + * and/or sell copies of the Software, and to permit persons to whom the > + * Software is furnished to do so, subject to the following conditions: > + * > + * The above copyright notice and this permission notice shall be included in > + * all copies or substantial portions of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR > + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > + * OTHER DEALINGS IN THE SOFTWARE. > + */ > +#include <linux/hdmi.h> > +#include <drm/drmP.h> > +#include "radeon.h" > +#include "radeon_asic.h" > +#include "r600d.h" > + > +static void dce3_2_afmt_write_speaker_allocation(struct drm_encoder *encoder) > +{ > + struct radeon_device *rdev = encoder->dev->dev_private; > + struct drm_connector *connector; > + struct radeon_connector *radeon_connector = NULL; > + u32 tmp; > + u8 *sadb; > + int sad_count; > + > + list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) { > + if (connector->encoder == encoder) { > + radeon_connector = to_radeon_connector(connector); > + break; > + } > + } > + > + if (!radeon_connector) { > + DRM_ERROR("Couldn't find encoder's connector\n"); > + return; > + } > + > + sad_count = drm_edid_to_speaker_allocation(radeon_connector->edid, &sadb); > + if (sad_count < 0) { > + DRM_ERROR("Couldn't read Speaker Allocation Data Block: %d\n", sad_count); > + return; > + } > + > + /* program the speaker allocation */ > + tmp = RREG32(AZ_F0_CODEC_PIN0_CONTROL_CHANNEL_SPEAKER); > + tmp &= ~(DP_CONNECTION | SPEAKER_ALLOCATION_MASK); > + /* set HDMI mode */ > + tmp |= HDMI_CONNECTION; > + if (sad_count) > + tmp |= SPEAKER_ALLOCATION(sadb[0]); > + else > + tmp |= SPEAKER_ALLOCATION(5); /* stereo */ > + WREG32(AZ_F0_CODEC_PIN0_CONTROL_CHANNEL_SPEAKER, tmp); > + > + kfree(sadb); > +} > + > +static void dce3_2_afmt_write_sad_regs(struct drm_encoder *encoder) > +{ > + struct radeon_device *rdev = encoder->dev->dev_private; > + struct drm_connector *connector; > + struct radeon_connector *radeon_connector = NULL; > + struct cea_sad *sads; > + int i, sad_count; > + > + static const u16 eld_reg_to_type[][2] = { > + { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR0, HDMI_AUDIO_CODING_TYPE_PCM }, > + { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR1, HDMI_AUDIO_CODING_TYPE_AC3 }, > + { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR2, HDMI_AUDIO_CODING_TYPE_MPEG1 }, > + { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR3, HDMI_AUDIO_CODING_TYPE_MP3 }, > + { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR4, HDMI_AUDIO_CODING_TYPE_MPEG2 }, > + { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR5, HDMI_AUDIO_CODING_TYPE_AAC_LC }, > + { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR6, HDMI_AUDIO_CODING_TYPE_DTS }, > + { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR7, HDMI_AUDIO_CODING_TYPE_ATRAC }, > + { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR9, HDMI_AUDIO_CODING_TYPE_EAC3 }, > + { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR10, HDMI_AUDIO_CODING_TYPE_DTS_HD }, > + { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR11, HDMI_AUDIO_CODING_TYPE_MLP }, > + { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR13, HDMI_AUDIO_CODING_TYPE_WMA_PRO }, > + }; > + > + list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) { > + if (connector->encoder == encoder) { > + radeon_connector = to_radeon_connector(connector); > + break; > + } > + } > + > + if (!radeon_connector) { > + DRM_ERROR("Couldn't find encoder's connector\n"); > + return; > + } > + > + sad_count = drm_edid_to_sad(radeon_connector->edid, &sads); > + if (sad_count < 0) { > + DRM_ERROR("Couldn't read SADs: %d\n", sad_count); > + return; > + } > + BUG_ON(!sads); > + > + for (i = 0; i < ARRAY_SIZE(eld_reg_to_type); i++) { > + u32 value = 0; > + u8 stereo_freqs = 0; > + int max_channels = -1; > + int j; > + > + for (j = 0; j < sad_count; j++) { > + struct cea_sad *sad = &sads[j]; > + > + if (sad->format == eld_reg_to_type[i][1]) { > + if (sad->channels > max_channels) { > + value = MAX_CHANNELS(sad->channels) | > + DESCRIPTOR_BYTE_2(sad->byte2) | > + SUPPORTED_FREQUENCIES(sad->freq); > + max_channels = sad->channels; > + } > + > + if (sad->format == HDMI_AUDIO_CODING_TYPE_PCM) > + stereo_freqs |= sad->freq; > + else > + break; > + } > + } > + > + value |= SUPPORTED_FREQUENCIES_STEREO(stereo_freqs); > + > + WREG32(eld_reg_to_type[i][0], value); > + } > + > + kfree(sads); > +} > + > +/* > + * update the info frames with the data from the current display mode > + */ > +void dce3_1_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode) > +{ > + 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; > + u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE]; > + struct hdmi_avi_infoframe frame; > + uint32_t offset; > + ssize_t err; > + > + if (!dig || !dig->afmt) > + return; > + > + /* Silent, r600_hdmi_enable will raise WARN for us */ > + if (!dig->afmt->enabled) > + return; > + offset = dig->afmt->offset; > + > + /* disable audio prior to setting up hw */ > + dig->afmt->pin = r600_audio_get_pin(rdev); > + r600_audio_enable(rdev, dig->afmt->pin, false); > + > + r600_audio_set_dto(encoder, mode->clock); > + > + WREG32(HDMI0_VBI_PACKET_CONTROL + offset, > + HDMI0_NULL_SEND); /* send null packets when required */ > + > + WREG32(HDMI0_AUDIO_CRC_CONTROL + offset, 0x1000); > + > + if (ASIC_IS_DCE32(rdev)) { > + WREG32(HDMI0_AUDIO_PACKET_CONTROL + offset, > + HDMI0_AUDIO_DELAY_EN(1) | /* default audio delay */ > + HDMI0_AUDIO_PACKETS_PER_LINE(3)); /* should be suffient for all audio modes and small enough for all hblanks */ > + WREG32(AFMT_AUDIO_PACKET_CONTROL + offset, > + AFMT_AUDIO_SAMPLE_SEND | /* send audio packets */ > + AFMT_60958_CS_UPDATE); /* allow 60958 channel status fields to be updated */ > + } else { > + WREG32(HDMI0_AUDIO_PACKET_CONTROL + offset, > + HDMI0_AUDIO_SAMPLE_SEND | /* send audio packets */ > + HDMI0_AUDIO_DELAY_EN(1) | /* default audio delay */ > + HDMI0_AUDIO_PACKETS_PER_LINE(3) | /* should be suffient for all audio modes and small enough for all hblanks */ > + HDMI0_60958_CS_UPDATE); /* allow 60958 channel status fields to be updated */ > + } > + > + if (ASIC_IS_DCE32(rdev)) { > + dce3_2_afmt_write_speaker_allocation(encoder); > + dce3_2_afmt_write_sad_regs(encoder); > + } > + > + WREG32(HDMI0_ACR_PACKET_CONTROL + offset, > + HDMI0_ACR_SOURCE | /* select SW CTS value - XXX verify that hw CTS works on all families */ > + HDMI0_ACR_AUTO_SEND); /* allow hw to sent ACR packets when required */ > + > + WREG32(HDMI0_VBI_PACKET_CONTROL + offset, > + HDMI0_NULL_SEND | /* send null packets when required */ > + HDMI0_GC_SEND | /* send general control packets */ > + HDMI0_GC_CONT); /* send general control packets every frame */ > + > + /* TODO: HDMI0_AUDIO_INFO_UPDATE */ > + WREG32(HDMI0_INFOFRAME_CONTROL0 + offset, > + HDMI0_AVI_INFO_SEND | /* enable AVI info frames */ > + HDMI0_AVI_INFO_CONT | /* send AVI info frames every frame/field */ > + HDMI0_AUDIO_INFO_SEND | /* enable audio info frames (frames won't be set until audio is enabled) */ > + HDMI0_AUDIO_INFO_CONT); /* send audio info frames every frame/field */ > + > + WREG32(HDMI0_INFOFRAME_CONTROL1 + offset, > + HDMI0_AVI_INFO_LINE(2) | /* anything other than 0 */ > + HDMI0_AUDIO_INFO_LINE(2)); /* anything other than 0 */ > + > + WREG32(HDMI0_GC + offset, 0); /* unset HDMI0_GC_AVMUTE */ > + > + err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode); > + if (err < 0) { > + DRM_ERROR("failed to setup AVI infoframe: %zd\n", err); > + return; > + } > + > + err = hdmi_avi_infoframe_pack(&frame, buffer, sizeof(buffer)); > + if (err < 0) { > + DRM_ERROR("failed to pack AVI infoframe: %zd\n", err); > + return; > + } > + > + r600_hdmi_update_avi_infoframe(encoder, buffer, sizeof(buffer)); > + r600_hdmi_update_ACR(encoder, mode->clock); > + > + /* it's unknown what these bits do excatly, but it's indeed quite useful for debugging */ > + WREG32(HDMI0_RAMP_CONTROL0 + offset, 0x00FFFFFF); > + WREG32(HDMI0_RAMP_CONTROL1 + offset, 0x007FFFFF); > + WREG32(HDMI0_RAMP_CONTROL2 + offset, 0x00000001); > + WREG32(HDMI0_RAMP_CONTROL3 + offset, 0x00000001); > + > + r600_hdmi_audio_workaround(encoder); > + > + /* enable audio after to setting up hw */ > + r600_audio_enable(rdev, dig->afmt->pin, true); > +} > diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c > index 85a2bb2..b8b2efa 100644 > --- a/drivers/gpu/drm/radeon/r600_hdmi.c > +++ b/drivers/gpu/drm/radeon/r600_hdmi.c > @@ -133,7 +133,7 @@ struct radeon_hdmi_acr r600_hdmi_acr(uint32_t clock) > /* > * update the N and CTS parameters for a given pixel clock rate > */ > -static void r600_hdmi_update_ACR(struct drm_encoder *encoder, uint32_t clock) > +void r600_hdmi_update_ACR(struct drm_encoder *encoder, uint32_t clock) > { > struct drm_device *dev = encoder->dev; > struct radeon_device *rdev = dev->dev_private; > @@ -155,8 +155,8 @@ static void r600_hdmi_update_ACR(struct drm_encoder *encoder, uint32_t clock) > /* > * build a HDMI Video Info Frame > */ > -static void r600_hdmi_update_avi_infoframe(struct drm_encoder *encoder, > - void *buffer, size_t size) > +void r600_hdmi_update_avi_infoframe(struct drm_encoder *encoder, void *buffer, > + size_t size) > { > struct drm_device *dev = encoder->dev; > struct radeon_device *rdev = dev->dev_private; > @@ -231,7 +231,7 @@ int r600_hdmi_buffer_status_changed(struct drm_encoder *encoder) > /* > * write the audio workaround status to the hardware > */ > -static void r600_hdmi_audio_workaround(struct drm_encoder *encoder) > +void r600_hdmi_audio_workaround(struct drm_encoder *encoder) > { > struct drm_device *dev = encoder->dev; > struct radeon_device *rdev = dev->dev_private; > @@ -250,7 +250,7 @@ static void r600_hdmi_audio_workaround(struct drm_encoder *encoder) > value, ~HDMI0_AUDIO_TEST_EN); > } > > -static void r600_audio_set_dto(struct drm_encoder *encoder, u32 clock) > +void r600_audio_set_dto(struct drm_encoder *encoder, u32 clock) > { > struct drm_device *dev = encoder->dev; > struct radeon_device *rdev = dev->dev_private; > @@ -320,121 +320,6 @@ static void r600_audio_set_dto(struct drm_encoder *encoder, u32 clock) > } > } > > -static void dce3_2_afmt_write_speaker_allocation(struct drm_encoder *encoder) > -{ > - struct radeon_device *rdev = encoder->dev->dev_private; > - struct drm_connector *connector; > - struct radeon_connector *radeon_connector = NULL; > - u32 tmp; > - u8 *sadb; > - int sad_count; > - > - list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) { > - if (connector->encoder == encoder) { > - radeon_connector = to_radeon_connector(connector); > - break; > - } > - } > - > - if (!radeon_connector) { > - DRM_ERROR("Couldn't find encoder's connector\n"); > - return; > - } > - > - sad_count = drm_edid_to_speaker_allocation(radeon_connector->edid, &sadb); > - if (sad_count < 0) { > - DRM_ERROR("Couldn't read Speaker Allocation Data Block: %d\n", sad_count); > - return; > - } > - > - /* program the speaker allocation */ > - tmp = RREG32(AZ_F0_CODEC_PIN0_CONTROL_CHANNEL_SPEAKER); > - tmp &= ~(DP_CONNECTION | SPEAKER_ALLOCATION_MASK); > - /* set HDMI mode */ > - tmp |= HDMI_CONNECTION; > - if (sad_count) > - tmp |= SPEAKER_ALLOCATION(sadb[0]); > - else > - tmp |= SPEAKER_ALLOCATION(5); /* stereo */ > - WREG32(AZ_F0_CODEC_PIN0_CONTROL_CHANNEL_SPEAKER, tmp); > - > - kfree(sadb); > -} > - > -static void dce3_2_afmt_write_sad_regs(struct drm_encoder *encoder) > -{ > - struct radeon_device *rdev = encoder->dev->dev_private; > - struct drm_connector *connector; > - struct radeon_connector *radeon_connector = NULL; > - struct cea_sad *sads; > - int i, sad_count; > - > - static const u16 eld_reg_to_type[][2] = { > - { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR0, HDMI_AUDIO_CODING_TYPE_PCM }, > - { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR1, HDMI_AUDIO_CODING_TYPE_AC3 }, > - { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR2, HDMI_AUDIO_CODING_TYPE_MPEG1 }, > - { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR3, HDMI_AUDIO_CODING_TYPE_MP3 }, > - { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR4, HDMI_AUDIO_CODING_TYPE_MPEG2 }, > - { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR5, HDMI_AUDIO_CODING_TYPE_AAC_LC }, > - { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR6, HDMI_AUDIO_CODING_TYPE_DTS }, > - { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR7, HDMI_AUDIO_CODING_TYPE_ATRAC }, > - { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR9, HDMI_AUDIO_CODING_TYPE_EAC3 }, > - { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR10, HDMI_AUDIO_CODING_TYPE_DTS_HD }, > - { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR11, HDMI_AUDIO_CODING_TYPE_MLP }, > - { AZ_F0_CODEC_PIN0_CONTROL_AUDIO_DESCRIPTOR13, HDMI_AUDIO_CODING_TYPE_WMA_PRO }, > - }; > - > - list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) { > - if (connector->encoder == encoder) { > - radeon_connector = to_radeon_connector(connector); > - break; > - } > - } > - > - if (!radeon_connector) { > - DRM_ERROR("Couldn't find encoder's connector\n"); > - return; > - } > - > - sad_count = drm_edid_to_sad(radeon_connector->edid, &sads); > - if (sad_count < 0) { > - DRM_ERROR("Couldn't read SADs: %d\n", sad_count); > - return; > - } > - BUG_ON(!sads); > - > - for (i = 0; i < ARRAY_SIZE(eld_reg_to_type); i++) { > - u32 value = 0; > - u8 stereo_freqs = 0; > - int max_channels = -1; > - int j; > - > - for (j = 0; j < sad_count; j++) { > - struct cea_sad *sad = &sads[j]; > - > - if (sad->format == eld_reg_to_type[i][1]) { > - if (sad->channels > max_channels) { > - value = MAX_CHANNELS(sad->channels) | > - DESCRIPTOR_BYTE_2(sad->byte2) | > - SUPPORTED_FREQUENCIES(sad->freq); > - max_channels = sad->channels; > - } > - > - if (sad->format == HDMI_AUDIO_CODING_TYPE_PCM) > - stereo_freqs |= sad->freq; > - else > - break; > - } > - } > - > - value |= SUPPORTED_FREQUENCIES_STEREO(stereo_freqs); > - > - WREG32(eld_reg_to_type[i][0], value); > - } > - > - kfree(sads); > -} > - > /* > * update the info frames with the data from the current display mode > */ > @@ -468,25 +353,11 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod > > WREG32(HDMI0_AUDIO_CRC_CONTROL + offset, 0x1000); > > - if (ASIC_IS_DCE32(rdev)) { > - WREG32(HDMI0_AUDIO_PACKET_CONTROL + offset, > - HDMI0_AUDIO_DELAY_EN(1) | /* default audio delay */ > - HDMI0_AUDIO_PACKETS_PER_LINE(3)); /* should be suffient for all audio modes and small enough for all hblanks */ > - WREG32(AFMT_AUDIO_PACKET_CONTROL + offset, > - AFMT_AUDIO_SAMPLE_SEND | /* send audio packets */ > - AFMT_60958_CS_UPDATE); /* allow 60958 channel status fields to be updated */ > - } else { > - WREG32(HDMI0_AUDIO_PACKET_CONTROL + offset, > - HDMI0_AUDIO_SAMPLE_SEND | /* send audio packets */ > - HDMI0_AUDIO_DELAY_EN(1) | /* default audio delay */ > - HDMI0_AUDIO_PACKETS_PER_LINE(3) | /* should be suffient for all audio modes and small enough for all hblanks */ > - HDMI0_60958_CS_UPDATE); /* allow 60958 channel status fields to be updated */ > - } > - > - if (ASIC_IS_DCE32(rdev)) { > - dce3_2_afmt_write_speaker_allocation(encoder); > - dce3_2_afmt_write_sad_regs(encoder); > - } > + WREG32(HDMI0_AUDIO_PACKET_CONTROL + offset, > + HDMI0_AUDIO_SAMPLE_SEND | /* send audio packets */ > + HDMI0_AUDIO_DELAY_EN(1) | /* default audio delay */ > + HDMI0_AUDIO_PACKETS_PER_LINE(3) | /* should be suffient for all audio modes and small enough for all hblanks */ > + HDMI0_60958_CS_UPDATE); /* allow 60958 channel status fields to be updated */ > > WREG32(HDMI0_ACR_PACKET_CONTROL + offset, > HDMI0_ACR_SOURCE | /* select SW CTS value - XXX verify that hw CTS works on all families */ > diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c > index 59d56dc..7bc3605 100644 > --- a/drivers/gpu/drm/radeon/radeon_asic.c > +++ b/drivers/gpu/drm/radeon/radeon_asic.c > @@ -1214,7 +1214,7 @@ static struct radeon_asic rv770_asic = { > .set_backlight_level = &atombios_set_backlight_level, > .get_backlight_level = &atombios_get_backlight_level, > .hdmi_enable = &r600_hdmi_enable, > - .hdmi_setmode = &r600_hdmi_setmode, > + .hdmi_setmode = &dce3_1_hdmi_setmode, > }, > .copy = { > .blit = &r600_copy_cpdma, > diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h > index 5646f9d..deb8496 100644 > --- a/drivers/gpu/drm/radeon/radeon_asic.h > +++ b/drivers/gpu/drm/radeon/radeon_asic.h > @@ -391,6 +391,11 @@ void r600_rlc_stop(struct radeon_device *rdev); > int r600_audio_init(struct radeon_device *rdev); > struct r600_audio_pin r600_audio_status(struct radeon_device *rdev); > void r600_audio_fini(struct radeon_device *rdev); > +void r600_audio_set_dto(struct drm_encoder *encoder, u32 clock); > +void r600_hdmi_update_avi_infoframe(struct drm_encoder *encoder, void *buffer, > + size_t size); > +void r600_hdmi_update_ACR(struct drm_encoder *encoder, uint32_t clock); > +void r600_hdmi_audio_workaround(struct drm_encoder *encoder); > int r600_hdmi_buffer_status_changed(struct drm_encoder *encoder); > void r600_hdmi_update_audio_settings(struct drm_encoder *encoder); > void r600_hdmi_enable(struct drm_encoder *encoder, bool enable); > @@ -463,6 +468,8 @@ int rv770_copy_dma(struct radeon_device *rdev, > u32 rv770_get_xclk(struct radeon_device *rdev); > int rv770_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk); > int rv770_get_temp(struct radeon_device *rdev); > +/* hdmi */ > +void dce3_1_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode); > /* rv7xx pm */ > int rv770_dpm_init(struct radeon_device *rdev); > int rv770_dpm_enable(struct radeon_device *rdev); > -- > 1.8.4.5 > _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel