Mailinglist Archive: radeonhd (312 mails)
| < Previous | Next > |
Re: [radeonhd] RS690 HDMI audio patch
- From: Christian König <deathsimple@xxxxxxxxxxx>
- Date: Sun, 26 Apr 2009 15:41:17 +0200
- Message-id: <1240753277.6579.43.camel@zweiundvierzig>
Hi,
Rafał Miłecki wrote:
Attached is the patch i send Christiaan for testing. It's just a
stripped down version to only the most necessary. Could you test it and
make sure that this patch doesn't make any changes on other chipset
types?
encoder->DTS/AC3 decoder->speaker is quite long it's hard to tell were
the problem is.
Does the frequency of those drop outs change with different display
resolutions (or more specific with the pixel clock)? If no then i am
pretty sure that you are right and this is a problem somewhere in the
alsa driver. If yes this could also be a glitch in the audio clock
recovery code.
Bye, Christian.
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 */
Rafał Miłecki wrote:
Any news on that?sorry forgot to put you/the list on cc.
Attached is the patch i send Christiaan for testing. It's just a
stripped down version to only the most necessary. Could you test it and
make sure that this patch doesn't make any changes on other chipset
types?
My setup still suffers from occasional audio drop outs. This does notSince the audio pipeline from application->alsa->audio codec->hdmi
seem to be caused by the radeonhd driver but somewhere in the ALSA part.
Dropouts are very frequent in AC3 passthrough. Have to try some of the
options for the hda-intel module to see if this helps, any thoughts
would be welcome here.
encoder->DTS/AC3 decoder->speaker is quite long it's hard to tell were
the problem is.
Does the frequency of those drop outs change with different display
resolutions (or more specific with the pixel clock)? If no then i am
pretty sure that you are right and this is a problem somewhere in the
alsa driver. If yes this could also be a glitch in the audio clock
recovery code.
Bye, Christian.
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 */
| < Previous | Next > |