diff options
author | Matthias Hopf <mhopf@suse.de> | 2009-10-08 19:19:30 +0200 |
---|---|---|
committer | Matthias Hopf <mhopf@suse.de> | 2009-10-09 18:41:24 +0200 |
commit | 42a81085042606cd812732a13b66527d37fc625c (patch) | |
tree | 2c30c38918891272f2a08788e98d56fa669a25b9 | |
parent | 8cbff7bfa1201faa1e5dbf7019f17c2f4b1d2b7f (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.c | 76 | ||||
-rw-r--r-- | src/rhd_i2c.h | 3 | ||||
-rw-r--r-- | src/rhd_pm.c | 8 |
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 */ |