]> Pileus Git - ~andy/linux/blobdiff - drivers/gpu/drm/radeon/evergreen_hdmi.c
drm/radeon/evergreen: write default channel numbers
[~andy/linux] / drivers / gpu / drm / radeon / evergreen_hdmi.c
index 4fdecc2b40402345a4db04c1dae7eb89d2626897..380933bc1782f9d934ac7225a507a9f9e9143f93 100644 (file)
@@ -111,26 +111,12 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode
 
        WREG32(AFMT_AUDIO_CRC_CONTROL + offset, 0x1000);
 
-       WREG32(HDMI_AUDIO_PACKET_CONTROL + offset,
-              HDMI_AUDIO_DELAY_EN(1) | /* set the default audio delay */
-              HDMI_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 */
-
-       WREG32(HDMI_ACR_PACKET_CONTROL + offset,
-              HDMI_ACR_AUTO_SEND | /* allow hw to sent ACR packets when required */
-              HDMI_ACR_SOURCE); /* select SW CTS value */
-
        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 */
 
        WREG32(HDMI_INFOFRAME_CONTROL0 + offset,
-              HDMI_AVI_INFO_SEND | /* enable AVI info frames */
-              HDMI_AVI_INFO_CONT | /* send AVI info frames every frame/field */
               HDMI_AUDIO_INFO_SEND | /* enable audio info frames (frames won't be set until audio is enabled) */
               HDMI_AUDIO_INFO_CONT); /* required for audio info values to be updated */
 
@@ -138,11 +124,46 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode
               AFMT_AUDIO_INFO_UPDATE); /* required for audio info values to be updated */
 
        WREG32(HDMI_INFOFRAME_CONTROL1 + offset,
-              HDMI_AVI_INFO_LINE(2) | /* anything other than 0 */
               HDMI_AUDIO_INFO_LINE(2)); /* anything other than 0 */
 
        WREG32(HDMI_GC + offset, 0); /* unset HDMI_GC_AVMUTE */
 
+       WREG32(HDMI_AUDIO_PACKET_CONTROL + offset,
+              HDMI_AUDIO_DELAY_EN(1) | /* set the default audio delay */
+              HDMI_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_60958_CS_UPDATE); /* allow 60958 channel status fields to be updated */
+
+       /* fglrx clears sth in AFMT_AUDIO_PACKET_CONTROL2 here */
+
+       WREG32(HDMI_ACR_PACKET_CONTROL + offset,
+              HDMI_ACR_AUTO_SEND | /* allow hw to sent ACR packets when required */
+              HDMI_ACR_SOURCE); /* select SW CTS value */
+
+       evergreen_hdmi_update_ACR(encoder, mode->clock);
+
+       WREG32(AFMT_60958_0 + offset,
+              AFMT_60958_CS_CHANNEL_NUMBER_L(1));
+
+       WREG32(AFMT_60958_1 + offset,
+              AFMT_60958_CS_CHANNEL_NUMBER_R(2));
+
+       WREG32(AFMT_60958_2 + offset,
+              AFMT_60958_CS_CHANNEL_NUMBER_2(3) |
+              AFMT_60958_CS_CHANNEL_NUMBER_3(4) |
+              AFMT_60958_CS_CHANNEL_NUMBER_4(5) |
+              AFMT_60958_CS_CHANNEL_NUMBER_5(6) |
+              AFMT_60958_CS_CHANNEL_NUMBER_6(7) |
+              AFMT_60958_CS_CHANNEL_NUMBER_7(8));
+
+       /* fglrx sets 0x0001005f | (x & 0x00fc0000) in 0x5f78 here */
+
+       WREG32(AFMT_AUDIO_PACKET_CONTROL2 + offset,
+              AFMT_AUDIO_CHANNEL_ENABLE(0xff));
+
+       /* fglrx sets 0x40 in 0x5f80 here */
+
        err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode);
        if (err < 0) {
                DRM_ERROR("failed to setup AVI infoframe: %zd\n", err);
@@ -156,7 +177,17 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode
        }
 
        evergreen_hdmi_update_avi_infoframe(encoder, buffer, sizeof(buffer));
-       evergreen_hdmi_update_ACR(encoder, mode->clock);
+
+       WREG32_OR(HDMI_INFOFRAME_CONTROL0 + offset,
+                 HDMI_AVI_INFO_SEND | /* enable AVI info frames */
+                 HDMI_AVI_INFO_CONT); /* required for audio info values to be updated */
+
+       WREG32_P(HDMI_INFOFRAME_CONTROL1 + offset,
+                HDMI_AVI_INFO_LINE(2), /* anything other than 0 */
+                ~HDMI_AVI_INFO_LINE_MASK);
+
+       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);