Write to HDMI_VBI_PACKET_CONTROL was duplicated. Writes to AFMT_AUDIO_CRC_CONTROL and AFMT_RAMP_CONTROL[0-3] came from DCE2/3 code (copy & paste) and were never needed on DCE4+.
See https://bugzilla.kernel.org/show_bug.cgi?id=62591 for details. --- That patches weren't tested with the HW, please don't apply them yet. --- drivers/gpu/drm/radeon/evergreen_hdmi.c | 11 ----------- 1 file changed, 11 deletions(-)
diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c index f71ce39..50f6299 100644 --- a/drivers/gpu/drm/radeon/evergreen_hdmi.c +++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c @@ -257,11 +257,6 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode evergreen_audio_set_dto(encoder, mode->clock);
WREG32(HDMI_VBI_PACKET_CONTROL + offset, - HDMI_NULL_SEND); /* send null packets when required */ - - WREG32(AFMT_AUDIO_CRC_CONTROL + offset, 0x1000); - - WREG32(HDMI_VBI_PACKET_CONTROL + offset, HDMI_NULL_SEND | /* send null packets when required */ HDMI_GC_SEND | /* send general control packets */ HDMI_GC_CONT); /* send general control packets every frame */ @@ -349,12 +344,6 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode
WREG32_OR(AFMT_AUDIO_PACKET_CONTROL + offset, AFMT_AUDIO_SAMPLE_SEND); /* send audio packets */ - - /* it's unknown what these bits do excatly, but it's indeed quite useful for debugging */ - WREG32(AFMT_RAMP_CONTROL0 + offset, 0x00FFFFFF); - WREG32(AFMT_RAMP_CONTROL1 + offset, 0x007FFFFF); - WREG32(AFMT_RAMP_CONTROL2 + offset, 0x00000001); - WREG32(AFMT_RAMP_CONTROL3 + offset, 0x00000001); }
void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable)
They were verified to be used by fglrx on PALM, BARTS, CAICOS and VERDE. VERDE which is DCE6 seems to need also clearing 0x7138 register.
See https://bugzilla.kernel.org/show_bug.cgi?id=62591 for details. --- That patches weren't tested with the HW, please don't apply them yet. --- drivers/gpu/drm/radeon/dce6_afmt.c | 10 ++++++++++ drivers/gpu/drm/radeon/evergreen_hdmi.c | 20 +++++++++++++++----- drivers/gpu/drm/radeon/evergreend.h | 3 +++ 3 files changed, 28 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/radeon/dce6_afmt.c b/drivers/gpu/drm/radeon/dce6_afmt.c index 85a69d2..cb4eb3a 100644 --- a/drivers/gpu/drm/radeon/dce6_afmt.c +++ b/drivers/gpu/drm/radeon/dce6_afmt.c @@ -56,6 +56,14 @@ static void dce6_endpoint_wreg(struct radeon_device *rdev,
#define RREG32_ENDPOINT(block, reg) dce6_endpoint_rreg(rdev, (block), (reg)) #define WREG32_ENDPOINT(block, reg, v) dce6_endpoint_wreg(rdev, (block), (reg), (v)) +#define WREG32_ENDPOINT_P(block, reg, val, mask) \ + do { \ + uint32_t tmp_ = RREG32_ENDPOINT(block, reg); \ + tmp_ &= (mask); \ + tmp_ |= ((val) & ~(mask)); \ + WREG32_ENDPOINT(block, reg, tmp_); \ + } while (0) +#define WREG32_ENDPOINT_OR(block, reg, or) WREG32_ENDPOINT_P(block, reg, or, ~(or))
static void dce6_afmt_get_connected_pins(struct radeon_device *rdev) @@ -196,6 +204,8 @@ void dce6_afmt_write_sad_regs(struct drm_encoder *encoder) } BUG_ON(!sads);
+ WREG32_ENDPOINT_OR(offset, 0x25, 0x40); + for (i = 0; i < ARRAY_SIZE(eld_reg_to_type); i++) { u32 value = 0; int j; diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c index 50f6299..2935161 100644 --- a/drivers/gpu/drm/radeon/evergreen_hdmi.c +++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c @@ -137,6 +137,8 @@ static void evergreen_hdmi_write_sad_regs(struct drm_encoder *encoder) } BUG_ON(!sads);
+ WREG32_OR(0x5f80, 0x40); + for (i = 0; i < ARRAY_SIZE(eld_reg_to_type); i++) { u32 value = 0; int j; @@ -280,7 +282,8 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode WREG32(AFMT_AUDIO_PACKET_CONTROL + offset, AFMT_60958_CS_UPDATE); /* allow 60958 channel status fields to be updated */
- /* fglrx clears sth in AFMT_AUDIO_PACKET_CONTROL2 here */ + WREG32_AND(AFMT_AUDIO_PACKET_CONTROL2, + ~(AFMT_AUDIO_LAYOUT_OVRD | AFMT_60958_CS_SOURCE));
WREG32(HDMI_ACR_PACKET_CONTROL + offset, HDMI_ACR_AUTO_SEND | /* allow hw to sent ACR packets when required */ @@ -302,16 +305,18 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode AFMT_60958_CS_CHANNEL_NUMBER_6(7) | AFMT_60958_CS_CHANNEL_NUMBER_7(8));
+ if (ASIC_IS_DCE6(rdev)) + WREG32(0x7138 + offset, 0); + if (ASIC_IS_DCE6(rdev)) { dce6_afmt_write_speaker_allocation(encoder); } else { dce4_afmt_write_speaker_allocation(encoder); }
- WREG32(AFMT_AUDIO_PACKET_CONTROL2 + offset, - AFMT_AUDIO_CHANNEL_ENABLE(0xff)); - - /* fglrx sets 0x40 in 0x5f80 here */ + WREG32_P(AFMT_AUDIO_PACKET_CONTROL2 + offset, + AFMT_AUDIO_CHANNEL_ENABLE(0xff), + ~AFMT_AUDIO_CHANNEL_MASK);
if (ASIC_IS_DCE6(rdev)) { dce6_afmt_select_pin(encoder); @@ -342,6 +347,11 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode HDMI_AVI_INFO_LINE(2), /* anything other than 0 */ ~HDMI_AVI_INFO_LINE_MASK);
+ WREG32_AND(HDMI_GENERIC_PACKET_CONTROL + offset, + ~(HDMI_GENERIC0_SEND | HDMI_GENERIC0_CONT | HDMI_GENERIC0_MASK)); + WREG32_AND(HDMI_GENERIC_PACKET_CONTROL + offset, + ~(HDMI_GENERIC1_SEND | HDMI_GENERIC1_CONT | HDMI_GENERIC1_MASK)); + WREG32_OR(AFMT_AUDIO_PACKET_CONTROL + offset, AFMT_AUDIO_SAMPLE_SEND); /* send audio packets */ } diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index 8768fd6..5724ae5 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h @@ -561,7 +561,9 @@ # define HDMI_GENERIC1_SEND (1 << 4) # define HDMI_GENERIC1_CONT (1 << 5) # define HDMI_GENERIC0_LINE(x) (((x) & 0x3f) << 16) +# define HDMI_GENERIC0_MASK (0x3f << 16) # define HDMI_GENERIC1_LINE(x) (((x) & 0x3f) << 24) +# define HDMI_GENERIC1_MASK (0x3f << 24) #define HDMI_GC 0x7058 # define HDMI_GC_AVMUTE (1 << 0) # define HDMI_GC_AVMUTE_CONT (1 << 2) @@ -570,6 +572,7 @@ # define AFMT_AUDIO_LAYOUT_SELECT (1 << 1) # define AFMT_60958_CS_SOURCE (1 << 4) # define AFMT_AUDIO_CHANNEL_ENABLE(x) (((x) & 0xff) << 8) +# define AFMT_AUDIO_CHANNEL_MASK (0xff << 8) # define AFMT_DP_AUDIO_STREAM_ID(x) (((x) & 0xff) << 16) #define AFMT_AVI_INFO0 0x7084 # define AFMT_AVI_INFO_CHECKSUM(x) (((x) & 0xff) << 0)
On Sun, Oct 6, 2013 at 4:46 PM, Rafał Miłecki zajec5@gmail.com wrote:
Write to HDMI_VBI_PACKET_CONTROL was duplicated. Writes to AFMT_AUDIO_CRC_CONTROL and AFMT_RAMP_CONTROL[0-3] came from DCE2/3 code (copy & paste) and were never needed on DCE4+.
See https://bugzilla.kernel.org/show_bug.cgi?id=62591 for details.
I think in general it would be better to do a read/modify/write sequences for all hdmi register updates rather than just writing. That's generally what the hw team recommends and what the catalyst driver does.
Alex
That patches weren't tested with the HW, please don't apply them yet.
drivers/gpu/drm/radeon/evergreen_hdmi.c | 11 ----------- 1 file changed, 11 deletions(-)
diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c index f71ce39..50f6299 100644 --- a/drivers/gpu/drm/radeon/evergreen_hdmi.c +++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c @@ -257,11 +257,6 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode evergreen_audio_set_dto(encoder, mode->clock);
WREG32(HDMI_VBI_PACKET_CONTROL + offset,
HDMI_NULL_SEND); /* send null packets when required */
WREG32(AFMT_AUDIO_CRC_CONTROL + offset, 0x1000);
WREG32(HDMI_VBI_PACKET_CONTROL + offset, HDMI_NULL_SEND | /* send null packets when required */ HDMI_GC_SEND | /* send general control packets */ HDMI_GC_CONT); /* send general control packets every frame */
@@ -349,12 +344,6 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode
WREG32_OR(AFMT_AUDIO_PACKET_CONTROL + offset, AFMT_AUDIO_SAMPLE_SEND); /* send audio packets */
/* it's unknown what these bits do excatly, but it's indeed quite useful for debugging */
WREG32(AFMT_RAMP_CONTROL0 + offset, 0x00FFFFFF);
WREG32(AFMT_RAMP_CONTROL1 + offset, 0x007FFFFF);
WREG32(AFMT_RAMP_CONTROL2 + offset, 0x00000001);
WREG32(AFMT_RAMP_CONTROL3 + offset, 0x00000001);
}
void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable)
1.7.10.4
2013/10/7 Alex Deucher alexdeucher@gmail.com:
On Sun, Oct 6, 2013 at 4:46 PM, Rafał Miłecki zajec5@gmail.com wrote:
Write to HDMI_VBI_PACKET_CONTROL was duplicated. Writes to AFMT_AUDIO_CRC_CONTROL and AFMT_RAMP_CONTROL[0-3] came from DCE2/3 code (copy & paste) and were never needed on DCE4+.
See https://bugzilla.kernel.org/show_bug.cgi?id=62591 for details.
I think in general it would be better to do a read/modify/write sequences for all hdmi register updates rather than just writing. That's generally what the hw team recommends and what the catalyst driver does.
See my patch 3/2 for that :) I agree with you.
On Mon, Oct 7, 2013 at 12:47 PM, Rafał Miłecki zajec5@gmail.com wrote:
2013/10/7 Alex Deucher alexdeucher@gmail.com:
On Sun, Oct 6, 2013 at 4:46 PM, Rafał Miłecki zajec5@gmail.com wrote:
Write to HDMI_VBI_PACKET_CONTROL was duplicated. Writes to AFMT_AUDIO_CRC_CONTROL and AFMT_RAMP_CONTROL[0-3] came from DCE2/3 code (copy & paste) and were never needed on DCE4+.
See https://bugzilla.kernel.org/show_bug.cgi?id=62591 for details.
I think in general it would be better to do a read/modify/write sequences for all hdmi register updates rather than just writing. That's generally what the hw team recommends and what the catalyst driver does.
See my patch 3/2 for that :) I agree with you.
Patch set looks good. Let me know if you have any further questions about the registers.
Alex
dri-devel@lists.freedesktop.org