diff --git a/src/rhd_audio.c b/src/rhd_audio.c
index 8d8a7d1..7223f83 100644
--- a/src/rhd_audio.c
+++ b/src/rhd_audio.c
@@ -241,28 +241,22 @@ RHDAudioSetClock(RHDPtr rhdPtr, struct rhdOutput* Output, CARD32 Clock)
 	    break;
 
 	default:
+	    xf86DrvMsg(Audio->scrnIndex, X_ERROR, "%s: unsupported output type\n", __func__);
 	    break;
     }
 
-    switch(Output->Id) {
-	case RHD_OUTPUT_TMDSA:
-	case RHD_OUTPUT_UNIPHYA:
+    switch(RHDOutputTmdsIndex(Output)) {
+	case 0:
 	    RHDRegWrite(Audio, AUDIO_PLL1_MUL, Rate*50);
 	    RHDRegWrite(Audio, AUDIO_PLL1_DIV, Clock*100);
 	    RHDRegWrite(Audio, AUDIO_CLK_SRCSEL, 0);
 	    break;
 
-	case RHD_OUTPUT_LVTMA:
-	case RHD_OUTPUT_UNIPHYB:
-	case RHD_OUTPUT_KLDSKP_LVTMA:
+	case 1:
 	    RHDRegWrite(Audio, AUDIO_PLL2_MUL, Rate*50);
 	    RHDRegWrite(Audio, AUDIO_PLL2_DIV, Clock*100);
 	    RHDRegWrite(Audio, AUDIO_CLK_SRCSEL, 1);
 	    break;
-
-	default:
-	    xf86DrvMsg(Audio->scrnIndex, X_ERROR, "%s: unsupported output type\n", __func__);
-	    break;
     }
 }
 
@@ -375,7 +369,9 @@ RHDAudioRestore(RHDPtr rhdPtr)
         return;
     }
 
-    /* shoutdown the audio engine before doing anything else */
+    /* 
+     * Shutdown the audio engine before doing anything else.
+     */
     RHDAudioSetEnable(rhdPtr, FALSE);
 
     RHDRegWrite(Audio, AUDIO_TIMING, Audio->StoreTiming);
diff --git a/src/rhd_hdmi.c b/src/rhd_hdmi.c
index 9a52536..eb71ed7 100644
--- a/src/rhd_hdmi.c
+++ b/src/rhd_hdmi.c
@@ -234,9 +234,13 @@ HdmiAudioInfoFrame(
 static void
 HdmiAudioDebugWorkaround(struct rhdHdmi* hdmi, Bool Enable)
 {
+    RHDRegWrite(hdmi, hdmi->Offset+HDMI_AUDIO_DEBUG_0, 0x00FFFFFF);
+    RHDRegWrite(hdmi, hdmi->Offset+HDMI_AUDIO_DEBUG_1, 0x007FFFFF);
+    RHDRegWrite(hdmi, hdmi->Offset+HDMI_AUDIO_DEBUG_2, 0x00000001);
+    RHDRegWrite(hdmi, hdmi->Offset+HDMI_AUDIO_DEBUG_3, 0x00000001);
+
     if(Enable) {
 	RHDRegMask(hdmi, hdmi->Offset+HDMI_CNTL, 0x1000, 0x1000);
-	RHDRegWrite(hdmi, hdmi->Offset+HDMI_AUDIO_DEBUG, 0xffffff);
     } else {
 	RHDRegMask(hdmi, hdmi->Offset+HDMI_CNTL, 0, 0x1000);
     }
@@ -253,17 +257,21 @@ RHDHdmiInit(RHDPtr rhdPtr, struct rhdOutput* Output)
     struct rhdHdmi *hdmi;
     RHDFUNC(rhdPtr);
 
-    if(rhdPtr->ChipSet >= RHD_R600) {
+    if(rhdPtr->ChipSet >= RHD_RS600) {
 	hdmi = (struct rhdHdmi *) xnfcalloc(sizeof(struct rhdHdmi), 1);
 	hdmi->scrnIndex = rhdPtr->scrnIndex;
 	hdmi->Output = Output;
+
 	switch(Output->Id) {
 	    case RHD_OUTPUT_TMDSA:
 		hdmi->Offset = HDMI_TMDS;
 		break;
 
 	    case RHD_OUTPUT_LVTMA:
-		hdmi->Offset = HDMI_LVTMA;
+		if(RHDOutputTmdsIndex(Output) == 0)
+		    hdmi->Offset = HDMI_TMDS;
+		else
+		    hdmi->Offset = HDMI_LVTMA;
 		break;
 
 	    case RHD_OUTPUT_UNIPHYA:
@@ -303,17 +311,24 @@ RHDHdmiSetMode(struct rhdHdmi *hdmi, DisplayModePtr Mode)
     HdmiAudioDebugWorkaround(hdmi, FALSE);
 
     RHDRegWrite(hdmi, hdmi->Offset+HDMI_UNKNOWN_0, 0x1000);
+    /* RHDRegMask(hdmi, hdmi->Offset+HDMI_UNKNOWN_1, 0x00000000, 0x00000001); */
     RHDRegWrite(hdmi, hdmi->Offset+HDMI_UNKNOWN_1, 0x0);
+    /* RHDRegMask(hdmi, hdmi->Offset+HDMI_UNKNOWN_2, 0x00001100, 0x00001100); */
     RHDRegWrite(hdmi, hdmi->Offset+HDMI_UNKNOWN_2, 0x1000);
 
     HdmiAudioClockRegeneration(hdmi, Mode->Clock);
 
+    /* RHDRegMask(hdmi, hdmi->Offset+HDMI_VIDEOCNTL, 0x000000B3, 0x000000B3); */
+    /* RHDRegMask(hdmi, hdmi->Offset+HDMI_VIDEOCNTL, 0xC0, 0xC0); */
     RHDRegWrite(hdmi, hdmi->Offset+HDMI_VIDEOCNTL, 0x13);
+
+    /* RHDRegMask(hdmi, hdmi->Offset+HDMI_VERSION,   0x00000202, 0x00003F3F); */
     RHDRegWrite(hdmi, hdmi->Offset+HDMI_VERSION, 0x202);
 
     HdmiVideoInfoFrame(hdmi, RGB, FALSE, 0, 0, 0,
 	0, 0, FALSE, 0, 0, 0, 0, 0, 0, 0, 0, 0);
 
+    /* RHDRegMask(hdmi, hdmi->Offset+HDMI_CNTL,      0x04020011, 0x04070111); */
     /* audio packets per line, does anyone know how to calc this ? */
     RHDRegMask(hdmi, hdmi->Offset+HDMI_CNTL, 0x020000, 0x1F0000);
 
@@ -322,7 +337,7 @@ RHDHdmiSetMode(struct rhdHdmi *hdmi, DisplayModePtr Mode)
 }
 
 /*
- * update settings whith current parameters from audio engine
+ * update settings with current parameters from audio engine
  */
 void
 RHDHdmiUpdateAudioSettings(
@@ -382,9 +397,11 @@ RHDHdmiUpdateAudioSettings(
 
     RHDRegMask(hdmi, hdmi->Offset+HDMI_IEC60958_2, iec, 0x5000f);
 
+    /* 0x021 or 0x031 sets the audio frame length */
     RHDRegWrite(hdmi, hdmi->Offset+HDMI_AUDIOCNTL, 0x31);
     HdmiAudioInfoFrame(hdmi, channels-1, 0, 0, 0, 0, 0, 0, FALSE);
 
+    /* RHDRegMask(hdmi, hdmi->Offset+HDMI_CNTL, 0x4000000, 0x4000000); */
     RHDRegMask(hdmi, hdmi->Offset+HDMI_CNTL, 0x400000, 0x400000);
 }
 
@@ -401,18 +418,19 @@ RHDHdmiEnable(struct rhdHdmi *hdmi, Bool Enable)
      * so enabling/disabling HDMI was moved here for TMDSA and LVTMA */
     switch(hdmi->Output->Id) {
 	case RHD_OUTPUT_TMDSA:
-	     RHDRegMask(hdmi, TMDSA_CNTL, Enable ? 0x4 : 0x0, 0x4);
-	     RHDRegWrite(hdmi, hdmi->Offset+HDMI_ENABLE, Enable ? 0x101 : 0x0);
-	     break;
+	    RHDRegMask(hdmi, TMDSA_CNTL, Enable ? 0x4 : 0x0, 0x4);
+	    RHDRegWrite(hdmi, hdmi->Offset+HDMI_ENABLE, Enable ? 0x101 : 0x0);
+	    break;
 
 	case RHD_OUTPUT_LVTMA:
-	     RHDRegMask(hdmi, LVTMA_CNTL, Enable ? 0x4 : 0x0, 0x4);
-	     RHDRegWrite(hdmi, hdmi->Offset+HDMI_ENABLE, Enable ? 0x105 : 0x0);
-	     break;
+	    RHDRegMask(hdmi, LVTMA_CNTL, Enable ? 0x4 : 0x0, 0x4);
+	    RHDRegWrite(hdmi, hdmi->Offset+HDMI_ENABLE, Enable ? 0x105 : 0x0);
+	    break;
 
 	case RHD_OUTPUT_UNIPHYA:
 	case RHD_OUTPUT_UNIPHYB:
 	case RHD_OUTPUT_KLDSKP_LVTMA:
+	    /* This part is doubtfull in my opinion */
 	    RHDRegWrite(hdmi, hdmi->Offset+HDMI_ENABLE, Enable ? 0x110 : 0x0);
 	    break;
 
@@ -433,7 +451,10 @@ RHDHdmiSave(struct rhdHdmi *hdmi)
 
     hdmi->StoreEnable = RHDRegRead(hdmi, hdmi->Offset+HDMI_ENABLE);
     hdmi->StoreControl = RHDRegRead(hdmi, hdmi->Offset+HDMI_CNTL);
-    hdmi->StoredAudioDebugWorkaround = RHDRegRead(hdmi, hdmi->Offset+HDMI_AUDIO_DEBUG);
+    hdmi->StoredAudioDebugWorkaround[0x0] = RHDRegRead(hdmi, hdmi->Offset+HDMI_AUDIO_DEBUG_0);
+    hdmi->StoredAudioDebugWorkaround[0x1] = RHDRegRead(hdmi, hdmi->Offset+HDMI_AUDIO_DEBUG_1);
+    hdmi->StoredAudioDebugWorkaround[0x2] = RHDRegRead(hdmi, hdmi->Offset+HDMI_AUDIO_DEBUG_2);
+    hdmi->StoredAudioDebugWorkaround[0x3] = RHDRegRead(hdmi, hdmi->Offset+HDMI_AUDIO_DEBUG_3);
 
     hdmi->StoredFrameVersion = RHDRegRead(hdmi, hdmi->Offset+HDMI_VERSION);
 
@@ -483,7 +504,10 @@ RHDHdmiRestore(struct rhdHdmi *hdmi)
 
     RHDRegWrite(hdmi, hdmi->Offset+HDMI_ENABLE, hdmi->StoreEnable);
     RHDRegWrite(hdmi, hdmi->Offset+HDMI_CNTL, hdmi->StoreControl);
-    RHDRegWrite(hdmi, hdmi->Offset+HDMI_AUDIO_DEBUG, hdmi->StoredAudioDebugWorkaround);
+    RHDRegWrite(hdmi, hdmi->Offset+HDMI_AUDIO_DEBUG_0, hdmi->StoredAudioDebugWorkaround[0x0]);
+    RHDRegWrite(hdmi, hdmi->Offset+HDMI_AUDIO_DEBUG_1, hdmi->StoredAudioDebugWorkaround[0x1]);
+    RHDRegWrite(hdmi, hdmi->Offset+HDMI_AUDIO_DEBUG_2, hdmi->StoredAudioDebugWorkaround[0x2]);
+    RHDRegWrite(hdmi, hdmi->Offset+HDMI_AUDIO_DEBUG_3, hdmi->StoredAudioDebugWorkaround[0x3]);
 
     RHDRegWrite(hdmi, hdmi->Offset+HDMI_VERSION, hdmi->StoredFrameVersion);
 
diff --git a/src/rhd_hdmi.h b/src/rhd_hdmi.h
index 4229417..5b1e8f0 100644
--- a/src/rhd_hdmi.h
+++ b/src/rhd_hdmi.h
@@ -39,7 +39,7 @@ struct rhdHdmi {
 	CARD32 StoreEnable;
 	CARD32 StoreControl;
 	CARD32 StoreUnknown[0x3];
-	CARD32 StoredAudioDebugWorkaround;
+	CARD32 StoredAudioDebugWorkaround[0x4];
 
 	CARD32 StoredFrameVersion;
 	CARD32 StoredVideoControl;
diff --git a/src/rhd_output.c b/src/rhd_output.c
index 7fe2ee9..d1fbde4 100644
--- a/src/rhd_output.c
+++ b/src/rhd_output.c
@@ -261,3 +261,41 @@ RHDOutputAttachConnector(struct rhdOutput *Output, struct rhdConnector *Connecto
 	    xf86DrvMsg(rhdPtr->scrnIndex, X_WARNING, "Failed to %s HDMI on %s\n", val.Bool ? "disable" : "enable", Output->Name);
     }
 }
+
+/*
+ * Returns the TMDS index of the given output, important for HDMI/Audio setup
+ */
+int
+RHDOutputTmdsIndex(struct rhdOutput *Output)
+{
+    struct rhdOutput *i = RHDPTRI(Output)->Outputs;
+    int index;
+
+    switch(Output->Id) {
+	case RHD_OUTPUT_TMDSA:
+	case RHD_OUTPUT_UNIPHYA:
+	    index=0;
+	    break;
+
+	case RHD_OUTPUT_LVTMA:
+	    /* special case check if an TMDSA is present */
+	    index=0;
+	    while(i) {
+		if(i->Id==RHD_OUTPUT_TMDSA)
+		    index++;
+		i = i->Next;
+	    }
+	    break;
+
+	case RHD_OUTPUT_UNIPHYB:
+	case RHD_OUTPUT_KLDSKP_LVTMA:
+	    index=1;
+	    break;
+
+	default:
+	    xf86DrvMsg(Output->scrnIndex, X_ERROR, "%s: unsupported output type\n", __func__);
+            index=-1;
+	    break;
+    }
+    return index;
+}
diff --git a/src/rhd_output.h b/src/rhd_output.h
index 22edfe9..21a49d2 100644
--- a/src/rhd_output.h
+++ b/src/rhd_output.h
@@ -115,6 +115,7 @@ void RHDOutputsRestore(RHDPtr rhdPtr);
 void RHDOutputsDestroy(RHDPtr rhdPtr);
 void RHDOutputPrintSensedType(struct rhdOutput *Output);
 void RHDOutputAttachConnector(struct rhdOutput *Output, struct rhdConnector *Connector);
+int RHDOutputTmdsIndex(struct rhdOutput *Output);
 
 /* output local functions. */
 struct rhdOutput *RHDDACAInit(RHDPtr rhdPtr);
diff --git a/src/rhd_regs.h b/src/rhd_regs.h
index bf74dd3..2209817 100644
--- a/src/rhd_regs.h
+++ b/src/rhd_regs.h
@@ -1113,7 +1113,10 @@ enum {
     HDMI_IEC60958_1       = 0xd4,
     HDMI_IEC60958_2       = 0xd8,
     HDMI_UNKNOWN_2        = 0xdc,
-    HDMI_AUDIO_DEBUG      = 0xe0
+    HDMI_AUDIO_DEBUG_0    = 0xe0,
+    HDMI_AUDIO_DEBUG_1    = 0xe4,
+    HDMI_AUDIO_DEBUG_2    = 0xe8,
+    HDMI_AUDIO_DEBUG_3    = 0xec
 };
 
 #endif /* _RHD_REGS_H */
