summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Hopf <mhopf@suse.de>2009-10-08 19:19:30 +0200
committerMatthias Hopf <mhopf@suse.de>2009-10-09 18:41:24 +0200
commit42a81085042606cd812732a13b66527d37fc625c (patch)
tree2c30c38918891272f2a08788e98d56fa669a25b9
parent8cbff7bfa1201faa1e5dbf7019f17c2f4b1d2b7f (diff)
pm: Recalculate I2C clock on engine clock setting.
On pre-R6xx the DDC clock is derived from the engine clock, thus changing the engine clock implies that the DDC clock is to be updated as well.
-rw-r--r--src/rhd_i2c.c76
-rw-r--r--src/rhd_i2c.h3
-rw-r--r--src/rhd_pm.c8
3 files changed, 55 insertions, 32 deletions
diff --git a/src/rhd_i2c.c b/src/rhd_i2c.c
index d5b698a..b59f3d4 100644
--- a/src/rhd_i2c.c
+++ b/src/rhd_i2c.c
@@ -39,6 +39,7 @@
#include "rhd.h"
#include "rhd_i2c.h"
+#include "rhd_pm.h"
#include "rhd_regs.h"
#ifdef ATOM_BIOS
@@ -1157,43 +1158,40 @@ rhdTearDownI2C(I2CBusPtr *I2C)
static CARD32
rhdGetI2CPrescale(RHDPtr rhdPtr)
{
-#ifdef ATOM_BIOS
- AtomBiosArgRec atomBiosArg;
RHDFUNC(rhdPtr);
if (rhdPtr->ChipSet < RHD_R600) {
- if (RHDAtomBiosFunc(rhdPtr->scrnIndex, rhdPtr->atomBIOS,
- ATOM_GET_DEFAULT_ENGINE_CLOCK, &atomBiosArg)
- == ATOM_SUCCESS)
- return (0x7f << 8)
- + (atomBiosArg.val / (4 * 0x7f * TARGET_HW_I2C_CLOCK));
- else
- return (0x7f << 8)
- + (DEFAULT_ENGINE_CLOCK / (4 * 0x7f * TARGET_HW_I2C_CLOCK));
- } else if (rhdPtr->ChipSet < RHD_RV620) {
- if (RHDAtomBiosFunc(rhdPtr->scrnIndex, rhdPtr->atomBIOS,
- ATOM_GET_REF_CLOCK, &atomBiosArg) == ATOM_SUCCESS)
- return (atomBiosArg.val / TARGET_HW_I2C_CLOCK);
- else
- return (DEFAULT_REF_CLOCK / TARGET_HW_I2C_CLOCK);
+
+ CARD32 EngineClock = DEFAULT_ENGINE_CLOCK;
+ if (rhdPtr->Pm)
+ EngineClock = rhdPtr->Pm->Current.EngineClock;
+#ifdef ATOM_BIOS
+ else {
+ AtomBiosArgRec atomBiosArg;
+ if (RHDAtomBiosFunc(rhdPtr->scrnIndex, rhdPtr->atomBIOS,
+ ATOM_GET_DEFAULT_ENGINE_CLOCK, &atomBiosArg)
+ == ATOM_SUCCESS)
+ EngineClock = atomBiosArg.val;
+ }
+#endif
+ return (0x7f << 8) + (EngineClock / (4 * 0x7f * TARGET_HW_I2C_CLOCK));
+
} else {
+
+ CARD32 RefClock = DEFAULT_REF_CLOCK;
+#ifdef ATOM_BIOS
+ AtomBiosArgRec atomBiosArg;
if (RHDAtomBiosFunc(rhdPtr->scrnIndex, rhdPtr->atomBIOS,
ATOM_GET_REF_CLOCK, &atomBiosArg) == ATOM_SUCCESS)
- return (atomBiosArg.val / (4 * TARGET_HW_I2C_CLOCK));
+ RefClock = atomBiosArg.val;
+#endif
+
+ if (rhdPtr->ChipSet < RHD_RV620)
+ return RefClock / TARGET_HW_I2C_CLOCK;
else
- return (DEFAULT_REF_CLOCK / (4 * TARGET_HW_I2C_CLOCK));
- }
-#else
- RHDFUNC(rhdPtr);
+ return RefClock / (4 * TARGET_HW_I2C_CLOCK);
- if (rhdPtr->ChipSet < RHD_R600) {
- return (0x7f << 8)
- + (DEFAULT_ENGINE_CLOCK) / (4 * 0x7f * TARGET_HW_I2C_CLOCK);
- } else if (rhdPtr->ChipSet < RHD_RV620) {
- return (DEFAULT_REF_CLOCK / TARGET_HW_I2C_CLOCK);
- } else
- return (DEFAULT_REF_CLOCK / (4 * TARGET_HW_I2C_CLOCK));
-#endif
+ }
}
static Bool
@@ -1373,6 +1371,21 @@ rhdInitI2C(int scrnIndex)
return NULL;
}
+/* If the engine clock is changed, recalculate the prescale */
+static void
+rhdI2CRecalcPrescale(int scrnIndex, I2CBusPtr *I2CList)
+{
+ RHDPtr rhdPtr = RHDPTR(xf86Screens[scrnIndex]);
+ CARD16 prescale = rhdGetI2CPrescale(rhdPtr);
+ int i;
+
+ for (i = 0; i < MAX_I2C_LINES; i++) {
+ if (!I2CList[i])
+ break;
+ ((rhdI2CPtr)(I2CList[i]->DriverPrivate.ptr))->prescale = prescale;
+ }
+}
+
RHDI2CResult
rhdI2CProbeAddress(int scrnIndex, I2CBusPtr I2CBusPtr, CARD8 slave)
{
@@ -1453,6 +1466,11 @@ RHDI2CFunc(int scrnIndex, I2CBusPtr *I2CList, RHDi2cFunc func,
rhdTearDownI2C(I2CList);
return RHD_I2C_SUCCESS;
}
+ if (func == RHD_I2C_RECALC_PRESCALE) {
+ if (I2CList)
+ rhdI2CRecalcPrescale(scrnIndex, I2CList);
+ return RHD_I2C_SUCCESS;
+ }
return RHD_I2C_FAILED;
}
diff --git a/src/rhd_i2c.h b/src/rhd_i2c.h
index cfc2747..3df8d43 100644
--- a/src/rhd_i2c.h
+++ b/src/rhd_i2c.h
@@ -34,7 +34,8 @@ typedef enum {
RHD_I2C_PROBE_ADDR_LINE,
RHD_I2C_PROBE_ADDR,
RHD_I2C_GETBUS,
- RHD_I2C_TEARDOWN
+ RHD_I2C_TEARDOWN,
+ RHD_I2C_RECALC_PRESCALE
} RHDi2cFunc;
typedef union RHDI2CDataArg
diff --git a/src/rhd_pm.c b/src/rhd_pm.c
index 26433aa..75a9bf8 100644
--- a/src/rhd_pm.c
+++ b/src/rhd_pm.c
@@ -35,6 +35,7 @@
#include "rhd.h"
#include "rhd_pm.h"
+#include "rhd_i2c.h"
#include "rhd_atombios.h"
@@ -274,9 +275,12 @@ rhdPmSetRawState (RHDPtr rhdPtr, struct rhdPowerState *state)
if (state->EngineClock && state->EngineClock != rhdPtr->Pm->Current.EngineClock) {
data.clockValue = state->EngineClock;
if (RHDAtomBiosFunc (rhdPtr->scrnIndex, rhdPtr->atomBIOS,
- ATOM_SET_ENGINE_CLOCK, &data) == ATOM_SUCCESS)
+ ATOM_SET_ENGINE_CLOCK, &data) == ATOM_SUCCESS) {
rhdPtr->Pm->Current.EngineClock = state->EngineClock;
- else
+ /* On pre-R6xx DDC clock depends on engine clock, thus recalculate */
+ if (rhdPtr->ChipSet < RHD_R600)
+ RHDI2CFunc(rhdPtr->scrnIndex, rhdPtr->I2C, RHD_I2C_RECALC_PRESCALE, NULL);
+ } else
ret = FALSE;
}
#if 0 /* don't do for the moment */