diff options
-rw-r--r-- | src/rhd_atomout.c | 39 | ||||
-rw-r--r-- | src/rhd_audio.c | 12 | ||||
-rw-r--r-- | src/rhd_dig.c | 29 | ||||
-rw-r--r-- | src/rhd_hdmi.c | 37 | ||||
-rw-r--r-- | src/rhd_output.c | 16 | ||||
-rw-r--r-- | src/rhd_regs.h | 2 |
6 files changed, 90 insertions, 45 deletions
diff --git a/src/rhd_atomout.c b/src/rhd_atomout.c index 5f3db26..9f879a8 100644 --- a/src/rhd_atomout.c +++ b/src/rhd_atomout.c @@ -808,7 +808,6 @@ rhdAtomOutputDestroy(struct rhdOutput *Output) RHDFUNC(Output); if (Private->Save) xfree(Private->Save); - RHDHdmiDestroy(Private->Hdmi); if (Private) xfree(Private); @@ -864,30 +863,38 @@ RHDAtomOutputAllocFree(struct rhdOutput *Output, enum rhdOutputAllocation Alloc) */ if (Private->EncoderId != atomEncoderNone) return TRUE; + if (Output->Id != RHD_OUTPUT_KLDSKP_LVTMA && !rhdPtr->DigEncoderOutput[0]) { rhdPtr->DigEncoderOutput[0] = Output; TransmitterConfig->Encoder = Private->EncoderId = atomEncoderDIG1; xf86DrvMsg(Output->scrnIndex, X_INFO, "Mapping DIG1 encoder to %s\n",TransmitterName); - return TRUE; } else if (!rhdPtr->DigEncoderOutput[1]) { rhdPtr->DigEncoderOutput[1] = Output; TransmitterConfig->Encoder = Private->EncoderId = atomEncoderDIG2; xf86DrvMsg(Output->scrnIndex, X_INFO, "Mapping DIG2 encoder to %s\n",TransmitterName); - return TRUE; } else return FALSE; + + Private->Hdmi = RHDHdmiInit(rhdPtr, Output); + RHDHdmiSave(Private->Hdmi); + RHDHdmiCommitAudioWorkaround(Private->Hdmi); + return TRUE; + case RHD_OUTPUT_FREE: - TransmitterConfig->Encoder = Private->EncoderId = atomEncoderNone; - if (rhdPtr->DigEncoderOutput[0] == Output) { + TransmitterConfig->Encoder = Private->EncoderId = atomEncoderNone; + if (rhdPtr->DigEncoderOutput[0] == Output) rhdPtr->DigEncoderOutput[0] = NULL; - return TRUE; - } else if (rhdPtr->DigEncoderOutput[1] == Output) { + else if (rhdPtr->DigEncoderOutput[1] == Output) rhdPtr->DigEncoderOutput[1] = NULL; - return TRUE; - } else + else return FALSE; - break; + + RHDHdmiRestore(Private->Hdmi); + RHDHdmiDestroy(Private->Hdmi); + Private->Hdmi = NULL; + return TRUE; + default: return FALSE; } @@ -963,6 +970,7 @@ RHDAtomOutputInit(RHDPtr rhdPtr, rhdConnectorType ConnectorType, EncoderConfig = &Private->EncoderConfig; Private->PixelClock = 0; + Private->Hdmi = NULL; switch (OutputType) { case RHD_OUTPUT_NONE: @@ -973,13 +981,11 @@ RHDAtomOutputInit(RHDPtr rhdPtr, rhdConnectorType ConnectorType, Output->Sense = RHDBIOSScratchDACSense; Private->EncoderId = atomEncoderDACA; Private->OutputControlId = atomDAC1Output; - Private->Hdmi = NULL; break; case RHD_OUTPUT_DACB: Output->Sense = RHDBIOSScratchDACSense; Private->EncoderId = atomEncoderDACB; Private->OutputControlId = atomDAC2Output; - Private->Hdmi = NULL; break; case RHD_OUTPUT_TMDSA: case RHD_OUTPUT_LVTMA: @@ -1005,11 +1011,6 @@ RHDAtomOutputInit(RHDPtr rhdPtr, rhdConnectorType ConnectorType, else Private->DualLink = FALSE; - if (ConnectorType != RHD_CONNECTOR_PANEL) - Private->Hdmi = RHDHdmiInit(rhdPtr, Output); - else - Private->Hdmi = NULL; - Private->EncoderVersion = rhdAtomEncoderControlVersion(rhdPtr->atomBIOS, Private->EncoderId); switch (Private->EncoderVersion.cref) { case 1: @@ -1092,12 +1093,10 @@ RHDAtomOutputInit(RHDPtr rhdPtr, rhdConnectorType ConnectorType, if (ConnectorType == RHD_CONNECTOR_PANEL) { TransmitterConfig->Mode = EncoderConfig->u.dig.EncoderMode = atomLVDS; LVDSInfoRetrieve(Output, Private); - Private->Hdmi = NULL; } else { TransmitterConfig->Mode = EncoderConfig->u.dig.EncoderMode = atomDVI; TMDSInfoRetrieve(rhdPtr, Private); Private->Coherent = FALSE; - Private->Hdmi = RHDHdmiInit(rhdPtr, Output); } break; @@ -1173,7 +1172,6 @@ RHDAtomOutputInit(RHDPtr rhdPtr, rhdConnectorType ConnectorType, case RHD_CONNECTOR_DVI: case RHD_CONNECTOR_DVI_SINGLE: TransmitterConfig->Mode = EncoderConfig->u.dig.EncoderMode = atomDVI; - Private->Hdmi = RHDHdmiInit(rhdPtr, Output); break; case RHD_CONNECTOR_PANEL: TransmitterConfig->Mode = EncoderConfig->u.dig.EncoderMode = atomLVDS; @@ -1271,7 +1269,6 @@ RhdAtomSetupBacklightControlProperty(struct rhdOutput *Output, TransmitterConfig->Encoder = Private->EncoderId = atomEncoderNone; LVDSInfoRetrieve(Output, Private); Private->PixelClock = 0; - Private->Hdmi = NULL; break; case RHD_OUTPUT_LVTMA: Private->OutputControlId = atomLCDOutput; diff --git a/src/rhd_audio.c b/src/rhd_audio.c index 5e3c4e2..aac7d62 100644 --- a/src/rhd_audio.c +++ b/src/rhd_audio.c @@ -210,6 +210,14 @@ RHDAudioSetEnable(RHDPtr rhdPtr, Bool Enable) AUDIO_BPS_16|AUDIO_BPS_20, AUDIO_CODEC_PCM ); + + + if(RHDPTRI(Audio)->ChipSet >= RHD_R700) + { + /* another bit which use is unknown, but is needed at least on RV710 and RV730 to get audio working */ + RHDRegMask(Audio, R700_AUDIO_UNKNOWN, 0x00000001, 0x00000001); + } + } else { TimerFree(Audio->Timer); Audio->Timer = NULL; @@ -239,6 +247,10 @@ RHDAudioSetClock(RHDPtr rhdPtr, struct rhdOutput* Output, CARD32 Clock) case RHD_OUTPUT_UNIPHYA: case RHD_OUTPUT_UNIPHYB: + case RHD_OUTPUT_UNIPHYC: + case RHD_OUTPUT_UNIPHYD: + case RHD_OUTPUT_UNIPHYE: + case RHD_OUTPUT_UNIPHYF: case RHD_OUTPUT_KLDSKP_LVTMA: RHDRegMask(Audio, AUDIO_TIMING, 0x100, 0x301); break; diff --git a/src/rhd_dig.c b/src/rhd_dig.c index 3458d4b..3156c37 100644 --- a/src/rhd_dig.c +++ b/src/rhd_dig.c @@ -1571,7 +1571,6 @@ DigDestroy(struct rhdOutput *Output) Encoder->Destroy(Output); Transmitter->Destroy(Output); - RHDHdmiDestroy(Private->Hdmi); if (Transmitter->PropertyPrivate) RhdAtomDestroyBacklightControlProperty(Output, Transmitter->PropertyPrivate); xfree(Private); @@ -1620,7 +1619,6 @@ DigAllocFree(struct rhdOutput *Output, enum rhdOutputAllocation Alloc) Private->EncoderID = ENCODER_DIG2; xf86DrvMsg(Output->scrnIndex, X_INFO, "Mapping DIG2 encoder to %s\n",TransmitterName); - return TRUE; } else return FALSE; } else @@ -1635,30 +1633,37 @@ DigAllocFree(struct rhdOutput *Output, enum rhdOutputAllocation Alloc) atc->Encoder = atomEncoderDIG1; xf86DrvMsg(Output->scrnIndex, X_INFO, "Mapping DIG1 encoder to %s\n",TransmitterName); - return TRUE; } else if (!rhdPtr->DigEncoderOutput[1]) { rhdPtr->DigEncoderOutput[1] = Output; Private->EncoderID = ENCODER_DIG2; atc->Encoder = atomEncoderDIG2; xf86DrvMsg(Output->scrnIndex, X_INFO, "Mapping DIG2 encoder to %s\n",TransmitterName); - return TRUE; } else return FALSE; } #else return FALSE; #endif + if(Private->EncoderMode == TMDS_DVI || Private->EncoderMode == TMDS_HDMI) { + Private->Hdmi = RHDHdmiInit(rhdPtr, Output); + RHDHdmiSave(Private->Hdmi); + RHDHdmiCommitAudioWorkaround(Private->Hdmi); + } + case RHD_OUTPUT_FREE: - Private->EncoderID = ENCODER_NONE; - if (rhdPtr->DigEncoderOutput[0] == Output) { + Private->EncoderID = ENCODER_NONE; + if (rhdPtr->DigEncoderOutput[0] == Output) rhdPtr->DigEncoderOutput[0] = NULL; - return TRUE; - } else if (rhdPtr->DigEncoderOutput[1] == Output) { + else if (rhdPtr->DigEncoderOutput[1] == Output) rhdPtr->DigEncoderOutput[1] = NULL; - return TRUE; - } else + else return FALSE; + + RHDHdmiRestore(Private->Hdmi); + RHDHdmiDestroy(Private->Hdmi); + Private->Hdmi = NULL; + return TRUE; break; default: return FALSE; @@ -1718,6 +1723,7 @@ RHDDIGInit(RHDPtr rhdPtr, enum rhdOutputType outputType, CARD8 ConnectorType) Output->Private = Private; Private->EncoderID = ENCODER_NONE; + Private->Hdmi = NULL; switch (outputType) { case RHD_OUTPUT_UNIPHYA: @@ -1880,17 +1886,14 @@ RHDDIGInit(RHDPtr rhdPtr, enum rhdOutputType outputType, CARD8 ConnectorType) #endif } - Private->Hdmi = NULL; break; case RHD_CONNECTOR_DVI: Private->RunDualLink = FALSE; /* will be set later acc to pxclk */ Private->EncoderMode = TMDS_DVI; - Private->Hdmi = RHDHdmiInit(rhdPtr, Output); break; case RHD_CONNECTOR_DVI_SINGLE: Private->RunDualLink = FALSE; Private->EncoderMode = TMDS_DVI; /* changed later to HDMI if aplicateable */ - Private->Hdmi = RHDHdmiInit(rhdPtr, Output); break; } diff --git a/src/rhd_hdmi.c b/src/rhd_hdmi.c index c786fcd..bafbc9d 100644 --- a/src/rhd_hdmi.c +++ b/src/rhd_hdmi.c @@ -258,22 +258,39 @@ RHDHdmiInit(RHDPtr rhdPtr, struct rhdOutput* Output) break; case RHD_OUTPUT_LVTMA: - if(RHDOutputTmdsIndex(Output) == 0) + switch(RHDOutputTmdsIndex(Output)) { + case 0: hdmi->Offset = HDMI_TMDS; - else + break; + case 1: hdmi->Offset = HDMI_LVTMA; + break; + default: + xfree(hdmi); + return NULL; + } break; case RHD_OUTPUT_UNIPHYA: - hdmi->Offset = HDMI_TMDS; - break; - + case RHD_OUTPUT_UNIPHYB: + case RHD_OUTPUT_UNIPHYC: + case RHD_OUTPUT_UNIPHYD: + case RHD_OUTPUT_UNIPHYE: + case RHD_OUTPUT_UNIPHYF: case RHD_OUTPUT_KLDSKP_LVTMA: - hdmi->Offset = HDMI_DIG; + switch(RHDOutputTmdsIndex(Output)) { + case 0: + hdmi->Offset = HDMI_TMDS; + break; + case 1: + hdmi->Offset = HDMI_DIG; + break; + default: + xfree(hdmi); + return NULL; + } break; - /*case RHD_OUTPUT_UNIPHYB: */ - default: xf86DrvMsg(hdmi->scrnIndex, X_ERROR, "%s: unknown HDMI output type\n", __func__); xfree(hdmi); @@ -436,6 +453,10 @@ RHDHdmiEnable(struct rhdHdmi *hdmi, Bool Enable) case RHD_OUTPUT_UNIPHYA: case RHD_OUTPUT_UNIPHYB: + case RHD_OUTPUT_UNIPHYC: + case RHD_OUTPUT_UNIPHYD: + case RHD_OUTPUT_UNIPHYE: + case RHD_OUTPUT_UNIPHYF: case RHD_OUTPUT_KLDSKP_LVTMA: /* This part is doubtfull in my opinion */ RHDRegWrite(hdmi, hdmi->Offset+HDMI_ENABLE, Enable ? 0x110 : 0x0); diff --git a/src/rhd_output.c b/src/rhd_output.c index 0e33d4e..4a767aa 100644 --- a/src/rhd_output.c +++ b/src/rhd_output.c @@ -287,12 +287,12 @@ RHDOutputAttachConnector(struct rhdOutput *Output, struct rhdConnector *Connecto int RHDOutputTmdsIndex(struct rhdOutput *Output) { - struct rhdOutput *i = RHDPTRI(Output)->Outputs; + RHDPtr rhdPtr = RHDPTRI(Output); + struct rhdOutput *i = rhdPtr->Outputs; int index; switch(Output->Id) { case RHD_OUTPUT_TMDSA: - case RHD_OUTPUT_UNIPHYA: index=0; break; @@ -306,9 +306,19 @@ RHDOutputTmdsIndex(struct rhdOutput *Output) } break; + case RHD_OUTPUT_UNIPHYA: case RHD_OUTPUT_UNIPHYB: + case RHD_OUTPUT_UNIPHYC: + case RHD_OUTPUT_UNIPHYD: + case RHD_OUTPUT_UNIPHYE: + case RHD_OUTPUT_UNIPHYF: case RHD_OUTPUT_KLDSKP_LVTMA: - index=1; + for(index=0; index<2; index++) + if(rhdPtr->DigEncoderOutput[index] == Output) + return index; + + xf86DrvMsg(Output->scrnIndex, X_ERROR, "%s: output not assigned to encoder\n", __func__); + index=-1; break; default: diff --git a/src/rhd_regs.h b/src/rhd_regs.h index a233153..ba474df 100644 --- a/src/rhd_regs.h +++ b/src/rhd_regs.h @@ -305,6 +305,8 @@ enum { AUDIO_PIN_WIDGET_CNTL = 0x73d4, /* RO */ AUDIO_STATUS_BITS = 0x73d8, /* RO */ + R700_AUDIO_UNKNOWN = 0x7604, + /* HDMI */ HDMI_TMDS = 0x7400, HDMI_LVTMA = 0x7700, |