summaryrefslogtreecommitdiff
path: root/driver/xf86-video-radeonhd/src/rhd_atomout.c
diff options
context:
space:
mode:
Diffstat (limited to 'driver/xf86-video-radeonhd/src/rhd_atomout.c')
-rw-r--r--driver/xf86-video-radeonhd/src/rhd_atomout.c75
1 files changed, 58 insertions, 17 deletions
diff --git a/driver/xf86-video-radeonhd/src/rhd_atomout.c b/driver/xf86-video-radeonhd/src/rhd_atomout.c
index 1d1662ac9..9d50ade9f 100644
--- a/driver/xf86-video-radeonhd/src/rhd_atomout.c
+++ b/driver/xf86-video-radeonhd/src/rhd_atomout.c
@@ -1,7 +1,7 @@
/*
- * Copyright 2007, 2008 Luc Verhaegen <libv@exsuse.de>
- * Copyright 2007, 2008 Matthias Hopf <mhopf@novell.com>
- * Copyright 2007, 2008 Egbert Eich <eich@novell.com>
+ * Copyright 2007 - 2009 Luc Verhaegen <libv@exsuse.de>
+ * Copyright 2007 - 2009 Matthias Hopf <mhopf@novell.com>
+ * Copyright 2007 - 2009 Egbert Eich <eich@novell.com>
* Copyright 2007, 2008 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -46,6 +46,7 @@
#include "rhd_atomout.h"
#include "rhd_biosscratch.h"
#include "rhd_hdmi.h"
+#include "rhd_acpi.h"
#if defined (ATOM_BIOS) && defined (ATOM_BIOS_PARSER)
struct rhdAtomOutputPrivate {
@@ -81,6 +82,8 @@ struct rhdAtomOutputPrivate {
struct rhdHdmi *Hdmi;
int BlLevel;
+ void (*SetBacklight)(struct rhdOutput *Output, int val);
+ int (*GetBacklight)(struct rhdOutput *Output);
};
#define ERROR_MSG(x) xf86DrvMsg(Output->scrnIndex, X_ERROR, "%s: %s failed.\n", __func__, x)
@@ -278,14 +281,12 @@ atomSetBacklightFromBIOSScratch(struct rhdOutput *Output)
*
*/
static void
-atomSetBacklight(struct rhdOutput *Output)
+atomSetBacklight(struct rhdOutput *Output, int val)
{
RHDPtr rhdPtr = RHDPTRI(Output);
- struct rhdAtomOutputPrivate *Private = (struct rhdAtomOutputPrivate *) Output->Private;
-
RHDFUNC(Output);
- RHDAtomBIOSScratchBlLevel(rhdPtr, rhdBIOSScratchBlSet, &Private->BlLevel);
+ RHDAtomBIOSScratchBlLevel(rhdPtr, rhdBIOSScratchBlSet, &val);
atomSetBacklightFromBIOSScratch(Output);
}
@@ -532,6 +533,7 @@ rhdAtomOutputRestore(struct rhdOutput *Output)
data.Address = &Private->Save;
RHDAtomBiosFunc(Output->scrnIndex, rhdPtr->atomBIOS, ATOM_RESTORE_REGISTERS, &data);
+ /* ??? */
if (Output->Connector && Output->Connector->Type == RHD_CONNECTOR_PANEL)
atomSetBacklightFromBIOSScratch(Output);
RHDHdmiRestore(Private->Hdmi);
@@ -566,13 +568,33 @@ rhdAtomOutputModeValid(struct rhdOutput *Output, DisplayModePtr Mode)
return MODE_OK;
}
+/*
+ *
+ */
+static int
+atomGetBacklight(struct rhdOutput *Output)
+{
+ RHDPtr rhdPtr = RHDPTRI(Output);
+ struct rhdAtomOutputPrivate *Private = (struct rhdAtomOutputPrivate *) Output->Private;
+ int level;
+
+ RHDFUNC(Output);
+
+ if (Private->BlLevel == -1) return -1;
+
+ RHDAtomBIOSScratchBlLevel(rhdPtr, rhdBIOSScratchBlSet, &level);
+
+ return level;
+}
+
/*
*
*/
static Bool
-LVDSInfoRetrieve(RHDPtr rhdPtr, struct rhdAtomOutputPrivate *Private)
+LVDSInfoRetrieve(struct rhdOutput *Output, struct rhdAtomOutputPrivate *Private)
{
+ RHDPtr rhdPtr = RHDPTRI(Output);
AtomBiosArgRec data;
if (RHDAtomBiosFunc(rhdPtr->scrnIndex, rhdPtr->atomBIOS,
@@ -625,7 +647,14 @@ LVDSInfoRetrieve(RHDPtr rhdPtr, struct rhdAtomOutputPrivate *Private)
}
Private->Coherent = FALSE;
- RHDAtomBIOSScratchBlLevel(rhdPtr, rhdBIOSScratchBlGet, &Private->BlLevel);
+ if ((Private->BlLevel = RhdACPIGetBacklightControl(Output)) >= 0) {
+ Private->SetBacklight = RhdACPISetBacklightControl;
+ Private->GetBacklight = RhdACPIGetBacklightControl;
+ } else {
+ RHDAtomBIOSScratchBlLevel(rhdPtr, rhdBIOSScratchBlGet, &Private->BlLevel);
+ Private->SetBacklight = atomSetBacklight;
+ Private->GetBacklight = atomGetBacklight;
+ }
return TRUE;
}
@@ -666,6 +695,7 @@ atomLVDSPropertyControl(struct rhdOutput *Output,
return FALSE;
}
case rhdPropertyGet:
+ Private->BlLevel = Private->GetBacklight(Output);
if (Private->BlLevel < 0)
return FALSE;
switch (Property) {
@@ -690,7 +720,7 @@ atomLVDSPropertyControl(struct rhdOutput *Output,
case rhdPropertyCommit:
switch (Property) {
case RHD_OUTPUT_BACKLIGHT:
- atomSetBacklight(Output);
+ Private->SetBacklight(Output,Private->BlLevel);
return TRUE;
default:
return FALSE;
@@ -715,6 +745,7 @@ atomTMDSPropertyControl(struct rhdOutput *Output,
switch (Property) {
case RHD_OUTPUT_COHERENT:
case RHD_OUTPUT_HDMI:
+ case RHD_OUTPUT_AUDIO_WORKAROUND:
return TRUE;
default:
return FALSE;
@@ -727,6 +758,9 @@ atomTMDSPropertyControl(struct rhdOutput *Output,
case RHD_OUTPUT_HDMI:
val->Bool = atomIsHdmiEnabled(Output);
return TRUE;
+ case RHD_OUTPUT_AUDIO_WORKAROUND:
+ val->Bool = RHDHdmiGetAudioWorkaround(Private->Hdmi);
+ return TRUE;
default:
return FALSE;
}
@@ -739,6 +773,9 @@ atomTMDSPropertyControl(struct rhdOutput *Output,
case RHD_OUTPUT_HDMI:
atomSetHdmiEnabled(Output, val->Bool);
break;
+ case RHD_OUTPUT_AUDIO_WORKAROUND:
+ RHDHdmiSetAudioWorkaround(Private->Hdmi, val->Bool);
+ break;
default:
return FALSE;
}
@@ -750,6 +787,9 @@ atomTMDSPropertyControl(struct rhdOutput *Output,
Output->Mode(Output, Private->Mode);
Output->Power(Output, RHD_POWER_ON);
break;
+ case RHD_OUTPUT_AUDIO_WORKAROUND:
+ RHDHdmiCommitAudioWorkaround(Private->Hdmi);
+ break;
default:
return FALSE;
}
@@ -946,7 +986,7 @@ RHDAtomOutputInit(RHDPtr rhdPtr, rhdConnectorType ConnectorType,
if (OutputType == RHD_OUTPUT_LVTMA) {
if (ConnectorType == RHD_CONNECTOR_PANEL) {
Private->OutputControlId = atomLCDOutput;
- LVDSInfoRetrieve(rhdPtr, Private);
+ LVDSInfoRetrieve(Output, Private);
Private->RunDualLink = Private->DualLink;
Private->EncoderId = atomEncoderLVDS;
} else {
@@ -1051,7 +1091,7 @@ RHDAtomOutputInit(RHDPtr rhdPtr, rhdConnectorType ConnectorType,
if (ConnectorType == RHD_CONNECTOR_PANEL) {
TransmitterConfig->Mode = EncoderConfig->u.dig.EncoderMode = atomLVDS;
- LVDSInfoRetrieve(rhdPtr, Private);
+ LVDSInfoRetrieve(Output, Private);
Private->Hdmi = NULL;
} else {
TransmitterConfig->Mode = EncoderConfig->u.dig.EncoderMode = atomDVI;
@@ -1125,7 +1165,7 @@ RHDAtomOutputInit(RHDPtr rhdPtr, rhdConnectorType ConnectorType,
}
if (ConnectorType == RHD_CONNECTOR_PANEL)
- LVDSInfoRetrieve(rhdPtr, Private);
+ LVDSInfoRetrieve(Output, Private);
else
TMDSInfoRetrieve(rhdPtr, Private);
@@ -1163,7 +1203,7 @@ RHDAtomOutputInit(RHDPtr rhdPtr, rhdConnectorType ConnectorType,
}
if (ConnectorType == RHD_CONNECTOR_PANEL) {
Output->Property = atomLVDSPropertyControl;
- LVDSInfoRetrieve(rhdPtr, Private);
+ LVDSInfoRetrieve(Output, Private);
} else {
Output->Property = atomTMDSPropertyControl;
TMDSInfoRetrieve(rhdPtr, Private);
@@ -1200,13 +1240,13 @@ RhdAtomSetupBacklightControlProperty(struct rhdOutput *Output,
RHDFUNC(Output);
Private = xnfcalloc(sizeof(struct rhdAtomOutputPrivate), 1);
+ TransmitterConfig = &Private->TransmitterConfig;
switch (Output->Id) {
case RHD_OUTPUT_KLDSKP_LVTMA:
case RHD_OUTPUT_UNIPHYE:
case RHD_OUTPUT_UNIPHYF:
/* We set up a those parameters although they may never be needed for BL control */
- TransmitterConfig = &Private->TransmitterConfig;
switch (Output->Id) {
case RHD_OUTPUT_KLDSKP_LVTMA:
Private->TransmitterId = atomTransmitterLVTMA;
@@ -1222,7 +1262,6 @@ RhdAtomSetupBacklightControlProperty(struct rhdOutput *Output,
default:
return 0; /* never get here */
}
- TransmitterConfig = &Private->TransmitterConfig;
TransmitterConfig->Mode = atomLVDS;
if (rhdPtr->DigEncoderOutput[0] == Output)
TransmitterConfig->Encoder = Private->EncoderId = atomEncoderDIG1;
@@ -1230,7 +1269,7 @@ RhdAtomSetupBacklightControlProperty(struct rhdOutput *Output,
TransmitterConfig->Encoder = Private->EncoderId = atomEncoderDIG2;
else
TransmitterConfig->Encoder = Private->EncoderId = atomEncoderNone;
- LVDSInfoRetrieve(rhdPtr, Private);
+ LVDSInfoRetrieve(Output, Private);
Private->PixelClock = 0;
Private->Hdmi = NULL;
break;
@@ -1244,6 +1283,8 @@ RhdAtomSetupBacklightControlProperty(struct rhdOutput *Output,
*PropertyFunc = atomLVDSPropertyControl;
*PrivatePtr = Private;
RHDAtomBIOSScratchBlLevel(rhdPtr, rhdBIOSScratchBlGet, &BlLevel);
+ Private->SetBacklight = atomSetBacklight;
+ Private->GetBacklight = atomGetBacklight;
return BlLevel;
}