|
@@ -142,14 +142,26 @@ void r600_hdmi_update_ACR(struct drm_encoder *encoder, uint32_t clock)
|
|
|
struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
|
|
|
uint32_t offset = dig->afmt->offset;
|
|
|
|
|
|
- WREG32(HDMI0_ACR_32_0 + offset, HDMI0_ACR_CTS_32(acr.cts_32khz));
|
|
|
- WREG32(HDMI0_ACR_32_1 + offset, acr.n_32khz);
|
|
|
-
|
|
|
- WREG32(HDMI0_ACR_44_0 + offset, HDMI0_ACR_CTS_44(acr.cts_44_1khz));
|
|
|
- WREG32(HDMI0_ACR_44_1 + offset, acr.n_44_1khz);
|
|
|
-
|
|
|
- WREG32(HDMI0_ACR_48_0 + offset, HDMI0_ACR_CTS_48(acr.cts_48khz));
|
|
|
- WREG32(HDMI0_ACR_48_1 + offset, acr.n_48khz);
|
|
|
+ WREG32_P(HDMI0_ACR_32_0 + offset,
|
|
|
+ HDMI0_ACR_CTS_32(acr.cts_32khz),
|
|
|
+ ~HDMI0_ACR_CTS_32_MASK);
|
|
|
+ WREG32_P(HDMI0_ACR_32_1 + offset,
|
|
|
+ HDMI0_ACR_N_32(acr.n_32khz),
|
|
|
+ ~HDMI0_ACR_N_32_MASK);
|
|
|
+
|
|
|
+ WREG32_P(HDMI0_ACR_44_0 + offset,
|
|
|
+ HDMI0_ACR_CTS_44(acr.cts_44_1khz),
|
|
|
+ ~HDMI0_ACR_CTS_44_MASK);
|
|
|
+ WREG32_P(HDMI0_ACR_44_1 + offset,
|
|
|
+ HDMI0_ACR_N_44(acr.n_44_1khz),
|
|
|
+ ~HDMI0_ACR_N_44_MASK);
|
|
|
+
|
|
|
+ WREG32_P(HDMI0_ACR_48_0 + offset,
|
|
|
+ HDMI0_ACR_CTS_48(acr.cts_48khz),
|
|
|
+ ~HDMI0_ACR_CTS_48_MASK);
|
|
|
+ WREG32_P(HDMI0_ACR_48_1 + offset,
|
|
|
+ HDMI0_ACR_N_48(acr.n_48khz),
|
|
|
+ ~HDMI0_ACR_N_48_MASK);
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -349,39 +361,44 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod
|
|
|
|
|
|
r600_audio_set_dto(encoder, mode->clock);
|
|
|
|
|
|
- WREG32(HDMI0_VBI_PACKET_CONTROL + offset,
|
|
|
- HDMI0_NULL_SEND); /* send null packets when required */
|
|
|
-
|
|
|
- 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_P(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 */
|
|
|
+ ~(HDMI0_AUDIO_SAMPLE_SEND |
|
|
|
+ HDMI0_AUDIO_DELAY_EN_MASK |
|
|
|
+ HDMI0_AUDIO_PACKETS_PER_LINE_MASK |
|
|
|
+ HDMI0_60958_CS_UPDATE));
|
|
|
|
|
|
/* DCE 3.0 uses register that's normally for CRC_CONTROL */
|
|
|
acr_ctl = ASIC_IS_DCE3(rdev) ? DCE3_HDMI0_ACR_PACKET_CONTROL :
|
|
|
HDMI0_ACR_PACKET_CONTROL;
|
|
|
- WREG32(acr_ctl + 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 */
|
|
|
+ WREG32_P(acr_ctl + 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 */
|
|
|
+ ~(HDMI0_ACR_SOURCE |
|
|
|
+ HDMI0_ACR_AUTO_SEND));
|
|
|
+
|
|
|
+ WREG32_OR(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 */
|
|
|
+
|
|
|
+ WREG32_OR(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_UPDATE); /* required for audio info values to be updated */
|
|
|
+
|
|
|
+ WREG32_P(HDMI0_INFOFRAME_CONTROL1 + offset,
|
|
|
+ HDMI0_AVI_INFO_LINE(2) | /* anything other than 0 */
|
|
|
+ HDMI0_AUDIO_INFO_LINE(2), /* anything other than 0 */
|
|
|
+ ~(HDMI0_AVI_INFO_LINE_MASK |
|
|
|
+ HDMI0_AUDIO_INFO_LINE_MASK));
|
|
|
+
|
|
|
+ WREG32_AND(HDMI0_GC + offset,
|
|
|
+ ~HDMI0_GC_AVMUTE); /* unset HDMI0_GC_AVMUTE */
|
|
|
|
|
|
err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode);
|
|
|
if (err < 0) {
|
|
@@ -396,8 +413,29 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod
|
|
|
}
|
|
|
|
|
|
r600_hdmi_update_avi_infoframe(encoder, buffer, sizeof(buffer));
|
|
|
+
|
|
|
+ /* fglrx duplicates INFOFRAME_CONTROL0 & INFOFRAME_CONTROL1 ops here */
|
|
|
+
|
|
|
+ WREG32_AND(HDMI0_GENERIC_PACKET_CONTROL + offset,
|
|
|
+ ~(HDMI0_GENERIC0_SEND |
|
|
|
+ HDMI0_GENERIC0_CONT |
|
|
|
+ HDMI0_GENERIC0_UPDATE |
|
|
|
+ HDMI0_GENERIC1_SEND |
|
|
|
+ HDMI0_GENERIC1_CONT |
|
|
|
+ HDMI0_GENERIC0_LINE_MASK |
|
|
|
+ HDMI0_GENERIC1_LINE_MASK));
|
|
|
+
|
|
|
r600_hdmi_update_ACR(encoder, mode->clock);
|
|
|
|
|
|
+ WREG32_P(HDMI0_60958_0 + offset,
|
|
|
+ HDMI0_60958_CS_CHANNEL_NUMBER_L(1),
|
|
|
+ ~(HDMI0_60958_CS_CHANNEL_NUMBER_L_MASK |
|
|
|
+ HDMI0_60958_CS_CLOCK_ACCURACY_MASK));
|
|
|
+
|
|
|
+ WREG32_P(HDMI0_60958_1 + offset,
|
|
|
+ HDMI0_60958_CS_CHANNEL_NUMBER_R(2),
|
|
|
+ ~HDMI0_60958_CS_CHANNEL_NUMBER_R_MASK);
|
|
|
+
|
|
|
/* 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);
|