forked from KolibriOS/kolibrios
move old ddx driver
git-svn-id: svn://kolibrios.org@1407 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
529
drivers/old/radeonhd/rhd_hdmi.c
Normal file
529
drivers/old/radeonhd/rhd_hdmi.c
Normal file
@@ -0,0 +1,529 @@
|
||||
/*
|
||||
* Copyright 2008 Christian König <deathsimple@vodafone.de>
|
||||
* Copyright 2007 Luc Verhaegen <lverhaegen@novell.com>
|
||||
* Copyright 2007 Matthias Hopf <mhopf@novell.com>
|
||||
* Copyright 2007 Egbert Eich <eich@novell.com>
|
||||
* Copyright 2007 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "xf86.h"
|
||||
|
||||
#include "rhd.h"
|
||||
#include "rhd_audio.h"
|
||||
#include "rhd_connector.h"
|
||||
#include "rhd_output.h"
|
||||
#include "rhd_hdmi.h"
|
||||
#include "rhd_regs.h"
|
||||
|
||||
enum HdmiColorFormat {
|
||||
RGB = 0,
|
||||
YCC_422 = 1,
|
||||
YCC_444 = 2
|
||||
};
|
||||
|
||||
struct {
|
||||
CARD32 Clock;
|
||||
|
||||
int N_32kHz;
|
||||
int CTS_32kHz;
|
||||
|
||||
int N_44_1kHz;
|
||||
int CTS_44_1kHz;
|
||||
|
||||
int N_48kHz;
|
||||
int CTS_48kHz;
|
||||
|
||||
} AudioClockRegeneration[] = {
|
||||
/* 32kHz 44.1kHz 48kHz */
|
||||
/* Clock N CTS N CTS N CTS */
|
||||
{ 25174, 4576, 28125, 7007, 31250, 6864, 28125 }, /* 25,20/1.001 MHz */
|
||||
{ 25200, 4096, 25200, 6272, 28000, 6144, 25200 }, /* 25.20 MHz */
|
||||
{ 27000, 4096, 27000, 6272, 30000, 6144, 27000 }, /* 27.00 MHz */
|
||||
{ 27027, 4096, 27027, 6272, 30030, 6144, 27027 }, /* 27.00*1.001 MHz */
|
||||
{ 54000, 4096, 54000, 6272, 60000, 6144, 54000 }, /* 54.00 MHz */
|
||||
{ 54054, 4096, 54054, 6272, 60060, 6144, 54054 }, /* 54.00*1.001 MHz */
|
||||
{ 74175, 11648, 210937, 17836, 234375, 11648, 140625 }, /* 74.25/1.001 MHz */
|
||||
{ 74250, 4096, 74250, 6272, 82500, 6144, 74250 }, /* 74.25 MHz */
|
||||
{ 148351, 11648, 421875, 8918, 234375, 5824, 140625 }, /* 148.50/1.001 MHz */
|
||||
{ 148500, 4096, 148500, 6272, 165000, 6144, 148500 }, /* 148.50 MHz */
|
||||
{ 0, 4096, 0, 6272, 0, 6144, 0 } /* Other */
|
||||
};
|
||||
|
||||
/*
|
||||
* calculate CTS value if it's not found in the table
|
||||
*/
|
||||
static void
|
||||
HdmiCalcCTS(struct rhdHdmi *hdmi, CARD32 Clock, int* CTS, int N, int freq)
|
||||
{
|
||||
if(*CTS == 0) *CTS = Clock*1000*N/(128*freq);
|
||||
xf86DrvMsg(hdmi->scrnIndex, X_INFO, "Using ACR timing N=%d CTS=%d for frequency %d\n",N,*CTS,freq);
|
||||
}
|
||||
|
||||
/*
|
||||
* update the N and CTS parameters for a given clock rate
|
||||
*/
|
||||
static void
|
||||
HdmiAudioClockRegeneration(struct rhdHdmi *hdmi, CARD32 Clock)
|
||||
{
|
||||
int CTS;
|
||||
int N;
|
||||
int i;
|
||||
for(i=0; AudioClockRegeneration[i].Clock != Clock && AudioClockRegeneration[i].Clock != 0; i++);
|
||||
|
||||
CTS = AudioClockRegeneration[i].CTS_32kHz;
|
||||
N = AudioClockRegeneration[i].N_32kHz;
|
||||
HdmiCalcCTS(hdmi, Clock, &CTS, N, 32000);
|
||||
RHDRegWrite(hdmi, hdmi->Offset+HDMI_32kHz_CTS, CTS << 12);
|
||||
RHDRegWrite(hdmi, hdmi->Offset+HDMI_32kHz_N, N);
|
||||
|
||||
CTS = AudioClockRegeneration[i].CTS_44_1kHz;
|
||||
N = AudioClockRegeneration[i].N_44_1kHz;
|
||||
HdmiCalcCTS(hdmi, Clock, &CTS, N, 44100);
|
||||
RHDRegWrite(hdmi, hdmi->Offset+HDMI_44_1kHz_CTS, CTS << 12);
|
||||
RHDRegWrite(hdmi, hdmi->Offset+HDMI_44_1kHz_N, N);
|
||||
|
||||
CTS = AudioClockRegeneration[i].CTS_48kHz;
|
||||
N = AudioClockRegeneration[i].N_48kHz;
|
||||
HdmiCalcCTS(hdmi, Clock, &CTS, N, 48000);
|
||||
RHDRegWrite(hdmi, hdmi->Offset+HDMI_48kHz_CTS, CTS << 12);
|
||||
RHDRegWrite(hdmi, hdmi->Offset+HDMI_48kHz_N, N);
|
||||
}
|
||||
|
||||
/*
|
||||
* calculate the crc for a given info frame
|
||||
*/
|
||||
static void
|
||||
HdmiInfoFrameChecksum(CARD8 packetType, CARD8 versionNumber, CARD8 length, CARD8* frame)
|
||||
{
|
||||
int i;
|
||||
frame[0] = packetType + versionNumber + length;
|
||||
for(i=1;i<=length;i++)
|
||||
frame[0] += frame[i];
|
||||
frame[0] = 0x100 - frame[0];
|
||||
}
|
||||
|
||||
/*
|
||||
* build a HDMI Video Info Frame
|
||||
*/
|
||||
static void
|
||||
HdmiVideoInfoFrame(
|
||||
struct rhdHdmi *hdmi,
|
||||
enum HdmiColorFormat ColorFormat,
|
||||
Bool ActiveInformationPresent,
|
||||
CARD8 ActiveFormatAspectRatio,
|
||||
CARD8 ScanInformation,
|
||||
CARD8 Colorimetry,
|
||||
CARD8 ExColorimetry,
|
||||
CARD8 Quantization,
|
||||
Bool ITC,
|
||||
CARD8 PictureAspectRatio,
|
||||
CARD8 VideoFormatIdentification,
|
||||
CARD8 PixelRepetition,
|
||||
CARD8 NonUniformPictureScaling,
|
||||
CARD8 BarInfoDataValid,
|
||||
CARD16 TopBar,
|
||||
CARD16 BottomBar,
|
||||
CARD16 LeftBar,
|
||||
CARD16 RightBar
|
||||
)
|
||||
{
|
||||
CARD8 frame[14];
|
||||
|
||||
frame[0x0] = 0;
|
||||
frame[0x1] =
|
||||
(ScanInformation & 0x3) |
|
||||
((BarInfoDataValid & 0x3) << 2) |
|
||||
((ActiveInformationPresent & 0x1) << 4) |
|
||||
((ColorFormat & 0x3) << 5);
|
||||
frame[0x2] =
|
||||
(ActiveFormatAspectRatio & 0xF) |
|
||||
((PictureAspectRatio & 0x3) << 4) |
|
||||
((Colorimetry & 0x3) << 6);
|
||||
frame[0x3] =
|
||||
(NonUniformPictureScaling & 0x3) |
|
||||
((Quantization & 0x3) << 2) |
|
||||
((ExColorimetry & 0x7) << 4) |
|
||||
((ITC & 0x1) << 7);
|
||||
frame[0x4] = (VideoFormatIdentification & 0x7F);
|
||||
frame[0x5] = (PixelRepetition & 0xF);
|
||||
frame[0x6] = (TopBar & 0xFF);
|
||||
frame[0x7] = (TopBar >> 8);
|
||||
frame[0x8] = (BottomBar & 0xFF);
|
||||
frame[0x9] = (BottomBar >> 8);
|
||||
frame[0xA] = (LeftBar & 0xFF);
|
||||
frame[0xB] = (LeftBar >> 8);
|
||||
frame[0xC] = (RightBar & 0xFF);
|
||||
frame[0xD] = (RightBar >> 8);
|
||||
|
||||
HdmiInfoFrameChecksum(0x82, 0x02, 0x0D, frame);
|
||||
|
||||
|
||||
RHDRegWrite(hdmi, hdmi->Offset+HDMI_VIDEOINFOFRAME_0,
|
||||
frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24));
|
||||
RHDRegWrite(hdmi, hdmi->Offset+HDMI_VIDEOINFOFRAME_1,
|
||||
frame[0x4] | (frame[0x5] << 8) | (frame[0x6] << 16) | (frame[0x7] << 24));
|
||||
RHDRegWrite(hdmi, hdmi->Offset+HDMI_VIDEOINFOFRAME_2,
|
||||
frame[0x8] | (frame[0x9] << 8) | (frame[0xA] << 16) | (frame[0xB] << 24));
|
||||
RHDRegWrite(hdmi, hdmi->Offset+HDMI_VIDEOINFOFRAME_3,
|
||||
frame[0xC] | (frame[0xD] << 8));
|
||||
}
|
||||
|
||||
/*
|
||||
* build a Audio Info Frame
|
||||
*/
|
||||
static void
|
||||
HdmiAudioInfoFrame(
|
||||
struct rhdHdmi *hdmi,
|
||||
CARD8 ChannelCount,
|
||||
CARD8 CodingType,
|
||||
CARD8 SampleSize,
|
||||
CARD8 SampleFrequency,
|
||||
CARD8 Format,
|
||||
CARD8 ChannelAllocation,
|
||||
CARD8 LevelShift,
|
||||
Bool DownmixInhibit
|
||||
)
|
||||
{
|
||||
CARD8 frame[11];
|
||||
|
||||
frame[0x0] = 0;
|
||||
frame[0x1] = (ChannelCount & 0x7) | ((CodingType & 0xF) << 4);
|
||||
frame[0x2] = (SampleSize & 0x3) | ((SampleFrequency & 0x7) << 2);
|
||||
frame[0x3] = Format;
|
||||
frame[0x4] = ChannelAllocation;
|
||||
frame[0x5] = ((LevelShift & 0xF) << 3) | ((DownmixInhibit & 0x1) << 7);
|
||||
frame[0x6] = 0;
|
||||
frame[0x7] = 0;
|
||||
frame[0x8] = 0;
|
||||
frame[0x9] = 0;
|
||||
frame[0xA] = 0;
|
||||
|
||||
HdmiInfoFrameChecksum(0x84, 0x01, 0x0A, frame);
|
||||
|
||||
RHDRegWrite(hdmi, hdmi->Offset+HDMI_AUDIOINFOFRAME_0,
|
||||
frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24));
|
||||
RHDRegWrite(hdmi, hdmi->Offset+HDMI_AUDIOINFOFRAME_1,
|
||||
frame[0x4] | (frame[0x5] << 8) | (frame[0x6] << 16) | (frame[0x8] << 24));
|
||||
}
|
||||
|
||||
/*
|
||||
* it's unknown what these bits do excatly, but it's indeed quite usefull for debugging
|
||||
*/
|
||||
static void
|
||||
HdmiAudioDebugWorkaround(struct rhdHdmi* hdmi, Bool Enable)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* allocate/initialize the HDMI structure
|
||||
* and register with audio engine
|
||||
* output selects which engine is used
|
||||
*/
|
||||
struct rhdHdmi*
|
||||
RHDHdmiInit(RHDPtr rhdPtr, struct rhdOutput* Output)
|
||||
{
|
||||
struct rhdHdmi *hdmi;
|
||||
RHDFUNC(rhdPtr);
|
||||
|
||||
if(rhdPtr->ChipSet >= RHD_R600) {
|
||||
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;
|
||||
break;
|
||||
|
||||
case RHD_OUTPUT_UNIPHYA:
|
||||
hdmi->Offset = HDMI_TMDS;
|
||||
break;
|
||||
|
||||
case RHD_OUTPUT_KLDSKP_LVTMA:
|
||||
hdmi->Offset = HDMI_DIG;
|
||||
break;
|
||||
|
||||
/*case RHD_OUTPUT_UNIPHYB: */
|
||||
|
||||
default:
|
||||
xf86DrvMsg(hdmi->scrnIndex, X_ERROR, "%s: unknown HDMI output type\n", __func__);
|
||||
xfree(hdmi);
|
||||
return NULL;
|
||||
break;
|
||||
}
|
||||
hdmi->Stored = FALSE;
|
||||
// RHDAudioRegisterHdmi(rhdPtr, hdmi);
|
||||
return hdmi;
|
||||
} else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* update the info frames with the data from the current display mode
|
||||
*/
|
||||
void
|
||||
RHDHdmiSetMode(struct rhdHdmi *hdmi, DisplayModePtr Mode)
|
||||
{
|
||||
if(!hdmi) return;
|
||||
RHDFUNC(hdmi);
|
||||
|
||||
// RHDAudioSetClock(RHDPTRI(hdmi), hdmi->Output, Mode->Clock);
|
||||
|
||||
HdmiAudioDebugWorkaround(hdmi, FALSE);
|
||||
|
||||
RHDRegWrite(hdmi, hdmi->Offset+HDMI_UNKNOWN_0, 0x1000);
|
||||
RHDRegWrite(hdmi, hdmi->Offset+HDMI_UNKNOWN_1, 0x0);
|
||||
RHDRegWrite(hdmi, hdmi->Offset+HDMI_UNKNOWN_2, 0x1000);
|
||||
|
||||
HdmiAudioClockRegeneration(hdmi, Mode->Clock);
|
||||
|
||||
RHDRegWrite(hdmi, hdmi->Offset+HDMI_VIDEOCNTL, 0x13);
|
||||
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);
|
||||
|
||||
/* audio packets per line, does anyone know how to calc this ? */
|
||||
RHDRegMask(hdmi, hdmi->Offset+HDMI_CNTL, 0x020000, 0x1F0000);
|
||||
|
||||
/* update? reset? don't realy know */
|
||||
RHDRegMask(hdmi, hdmi->Offset+HDMI_CNTL, 0x14000000, 0x14000000);
|
||||
}
|
||||
|
||||
/*
|
||||
* update settings whith current parameters from audio engine
|
||||
*/
|
||||
void
|
||||
RHDHdmiUpdateAudioSettings(
|
||||
struct rhdHdmi* hdmi,
|
||||
Bool playing,
|
||||
int channels,
|
||||
int rate,
|
||||
int bps,
|
||||
CARD8 status_bits,
|
||||
CARD8 category_code
|
||||
)
|
||||
{
|
||||
CARD32 iec;
|
||||
|
||||
if(!hdmi) return;
|
||||
RHDFUNC(hdmi);
|
||||
|
||||
xf86DrvMsg(hdmi->scrnIndex, X_INFO, "%s: %s with "
|
||||
"%d channels, %d Hz sampling rate, %d bits per sample,\n",
|
||||
__func__, playing ? "playing" : "stoped", channels, rate, bps);
|
||||
xf86DrvMsg(hdmi->scrnIndex, X_INFO, "%s: "
|
||||
"0x%02x IEC60958 status bits and 0x%02x category code\n",
|
||||
__func__, (int)status_bits, (int)category_code);
|
||||
|
||||
/* start delivering audio frames */
|
||||
RHDRegMask(hdmi, hdmi->Offset+HDMI_CNTL, playing ? 1 : 0, 0x1);
|
||||
|
||||
iec = 0;
|
||||
if(status_bits & AUDIO_STATUS_PROFESSIONAL) iec |= 1 << 0;
|
||||
if(status_bits & AUDIO_STATUS_NONAUDIO) iec |= 1 << 1;
|
||||
if(status_bits & AUDIO_STATUS_COPYRIGHT) iec |= 1 << 2;
|
||||
if(status_bits & AUDIO_STATUS_EMPHASIS) iec |= 1 << 3;
|
||||
|
||||
iec |= category_code << 8;
|
||||
|
||||
switch(rate)
|
||||
{
|
||||
case 32000: iec |= 0x3 << 24; break;
|
||||
case 44100: iec |= 0x0 << 24; break;
|
||||
case 88200: iec |= 0x8 << 24; break;
|
||||
case 176400: iec |= 0xc << 24; break;
|
||||
case 48000: iec |= 0x2 << 24; break;
|
||||
case 96000: iec |= 0xa << 24; break;
|
||||
case 192000: iec |= 0xe << 24; break;
|
||||
}
|
||||
|
||||
RHDRegWrite(hdmi, hdmi->Offset+HDMI_IEC60958_1, iec);
|
||||
|
||||
iec = 0;
|
||||
switch(bps)
|
||||
{
|
||||
case 16: iec |= 0x2; break;
|
||||
case 20: iec |= 0x3; break;
|
||||
case 24: iec |= 0xb; break;
|
||||
}
|
||||
if(status_bits & AUDIO_STATUS_V) iec |= 0x5 << 16;
|
||||
|
||||
RHDRegMask(hdmi, hdmi->Offset+HDMI_IEC60958_2, iec, 0x5000f);
|
||||
|
||||
RHDRegWrite(hdmi, hdmi->Offset+HDMI_AUDIOCNTL, 0x31);
|
||||
HdmiAudioInfoFrame(hdmi, channels-1, 0, 0, 0, 0, 0, 0, FALSE);
|
||||
|
||||
RHDRegMask(hdmi, hdmi->Offset+HDMI_CNTL, 0x400000, 0x400000);
|
||||
}
|
||||
|
||||
/*
|
||||
* enable/disable the HDMI engine
|
||||
*/
|
||||
void
|
||||
RHDHdmiEnable(struct rhdHdmi *hdmi, Bool Enable)
|
||||
{
|
||||
if(!hdmi) return;
|
||||
RHDFUNC(hdmi);
|
||||
|
||||
/* some version of atombios ignore the enable HDMI flag
|
||||
* 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;
|
||||
|
||||
case RHD_OUTPUT_LVTMA:
|
||||
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:
|
||||
RHDRegWrite(hdmi, hdmi->Offset+HDMI_ENABLE, Enable ? 0x110 : 0x0);
|
||||
break;
|
||||
|
||||
default:
|
||||
xf86DrvMsg(hdmi->scrnIndex, X_ERROR, "%s: unknown HDMI output type\n", __func__);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* save the current config of HDMI engine
|
||||
*/
|
||||
void
|
||||
RHDHdmiSave(struct rhdHdmi *hdmi)
|
||||
{
|
||||
if(!hdmi) return;
|
||||
RHDFUNC(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->StoredFrameVersion = RHDRegRead(hdmi, hdmi->Offset+HDMI_VERSION);
|
||||
|
||||
hdmi->StoredVideoControl = RHDRegRead(hdmi, hdmi->Offset+HDMI_VIDEOCNTL);
|
||||
hdmi->StoreVideoInfoFrame[0x0] = RHDRegRead(hdmi, hdmi->Offset+HDMI_VIDEOINFOFRAME_0);
|
||||
hdmi->StoreVideoInfoFrame[0x1] = RHDRegRead(hdmi, hdmi->Offset+HDMI_VIDEOINFOFRAME_1);
|
||||
hdmi->StoreVideoInfoFrame[0x2] = RHDRegRead(hdmi, hdmi->Offset+HDMI_VIDEOINFOFRAME_2);
|
||||
hdmi->StoreVideoInfoFrame[0x3] = RHDRegRead(hdmi, hdmi->Offset+HDMI_VIDEOINFOFRAME_3);
|
||||
|
||||
hdmi->StoredAudioControl = RHDRegRead(hdmi, hdmi->Offset+HDMI_AUDIOCNTL);
|
||||
hdmi->StoreAudioInfoFrame[0x0] = RHDRegRead(hdmi, hdmi->Offset+HDMI_AUDIOINFOFRAME_0);
|
||||
hdmi->StoreAudioInfoFrame[0x1] = RHDRegRead(hdmi, hdmi->Offset+HDMI_AUDIOINFOFRAME_1);
|
||||
|
||||
hdmi->Store_32kHz_N = RHDRegRead(hdmi, hdmi->Offset+HDMI_32kHz_N);
|
||||
hdmi->Store_32kHz_CTS = RHDRegRead(hdmi, hdmi->Offset+HDMI_32kHz_CTS);
|
||||
|
||||
hdmi->Store_44_1kHz_N = RHDRegRead(hdmi, hdmi->Offset+HDMI_44_1kHz_N);
|
||||
hdmi->Store_44_1kHz_CTS = RHDRegRead(hdmi, hdmi->Offset+HDMI_44_1kHz_CTS);
|
||||
|
||||
hdmi->Store_48kHz_N = RHDRegRead(hdmi, hdmi->Offset+HDMI_48kHz_N);
|
||||
hdmi->Store_48kHz_CTS = RHDRegRead(hdmi, hdmi->Offset+HDMI_48kHz_CTS);
|
||||
|
||||
hdmi->StoreIEC60958[0] = RHDRegRead(hdmi, hdmi->Offset+HDMI_IEC60958_1);
|
||||
hdmi->StoreIEC60958[1] = RHDRegRead(hdmi, hdmi->Offset+HDMI_IEC60958_2);
|
||||
|
||||
hdmi->StoreUnknown[0x0] = RHDRegRead(hdmi, hdmi->Offset+HDMI_UNKNOWN_0);
|
||||
hdmi->StoreUnknown[0x1] = RHDRegRead(hdmi, hdmi->Offset+HDMI_UNKNOWN_1);
|
||||
hdmi->StoreUnknown[0x2] = RHDRegRead(hdmi, hdmi->Offset+HDMI_UNKNOWN_2);
|
||||
|
||||
hdmi->Stored = TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* restore the saved config of HDMI engine
|
||||
*/
|
||||
void
|
||||
RHDHdmiRestore(struct rhdHdmi *hdmi)
|
||||
{
|
||||
if(!hdmi) return;
|
||||
RHDFUNC(hdmi);
|
||||
|
||||
if (!hdmi->Stored) {
|
||||
xf86DrvMsg(hdmi->scrnIndex, X_ERROR, "%s: trying to restore "
|
||||
"uninitialized values.\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
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_VERSION, hdmi->StoredFrameVersion);
|
||||
|
||||
RHDRegWrite(hdmi, hdmi->Offset+HDMI_VIDEOCNTL, hdmi->StoredVideoControl);
|
||||
RHDRegWrite(hdmi, hdmi->Offset+HDMI_VIDEOINFOFRAME_0, hdmi->StoreVideoInfoFrame[0x0]);
|
||||
RHDRegWrite(hdmi, hdmi->Offset+HDMI_VIDEOINFOFRAME_1, hdmi->StoreVideoInfoFrame[0x1]);
|
||||
RHDRegWrite(hdmi, hdmi->Offset+HDMI_VIDEOINFOFRAME_2, hdmi->StoreVideoInfoFrame[0x2]);
|
||||
RHDRegWrite(hdmi, hdmi->Offset+HDMI_VIDEOINFOFRAME_3, hdmi->StoreVideoInfoFrame[0x3]);
|
||||
|
||||
RHDRegWrite(hdmi, hdmi->Offset+HDMI_AUDIOCNTL, hdmi->StoredAudioControl);
|
||||
RHDRegWrite(hdmi, hdmi->Offset+HDMI_AUDIOINFOFRAME_0, hdmi->StoreAudioInfoFrame[0x0]);
|
||||
RHDRegWrite(hdmi, hdmi->Offset+HDMI_AUDIOINFOFRAME_1, hdmi->StoreAudioInfoFrame[0x1]);
|
||||
|
||||
RHDRegWrite(hdmi, hdmi->Offset+HDMI_32kHz_N, hdmi->Store_32kHz_N);
|
||||
RHDRegWrite(hdmi, hdmi->Offset+HDMI_32kHz_CTS, hdmi->Store_32kHz_CTS);
|
||||
|
||||
RHDRegWrite(hdmi, hdmi->Offset+HDMI_44_1kHz_N, hdmi->Store_44_1kHz_N);
|
||||
RHDRegWrite(hdmi, hdmi->Offset+HDMI_44_1kHz_CTS, hdmi->Store_44_1kHz_CTS);
|
||||
|
||||
RHDRegWrite(hdmi, hdmi->Offset+HDMI_48kHz_N, hdmi->Store_48kHz_N);
|
||||
RHDRegWrite(hdmi, hdmi->Offset+HDMI_48kHz_CTS, hdmi->Store_48kHz_CTS);
|
||||
|
||||
RHDRegWrite(hdmi, hdmi->Offset+HDMI_IEC60958_1, hdmi->StoreIEC60958[0]);
|
||||
RHDRegWrite(hdmi, hdmi->Offset+HDMI_IEC60958_2, hdmi->StoreIEC60958[1]);
|
||||
|
||||
RHDRegWrite(hdmi, hdmi->Offset+HDMI_UNKNOWN_0, hdmi->StoreUnknown[0x0]);
|
||||
RHDRegWrite(hdmi, hdmi->Offset+HDMI_UNKNOWN_1, hdmi->StoreUnknown[0x1]);
|
||||
RHDRegWrite(hdmi, hdmi->Offset+HDMI_UNKNOWN_2, hdmi->StoreUnknown[0x2]);
|
||||
}
|
||||
|
||||
/*
|
||||
* unregister with audio engine and release memory
|
||||
*/
|
||||
void
|
||||
RHDHdmiDestroy(struct rhdHdmi *hdmi)
|
||||
{
|
||||
if(!hdmi) return;
|
||||
RHDFUNC(hdmi);
|
||||
|
||||
// RHDAudioUnregisterHdmi(RHDPTRI(hdmi), hdmi);
|
||||
|
||||
xfree(hdmi);
|
||||
}
|
Reference in New Issue
Block a user