diff options
author | Paulo Cesar Pereira de Andrade <pcpa@mandriva.com.br> | 2008-09-22 22:01:16 -0300 |
---|---|---|
committer | Paulo Cesar Pereira de Andrade <pcpa@mandriva.com.br> | 2008-09-22 22:01:16 -0300 |
commit | e64b3d63be2a4148c4d10ac160e2bd2f3e8c7fd3 (patch) | |
tree | 720cb11d8dcaf7c71978499933167354f8d54e4e | |
parent | 1f0af5ea50e3e3b2c9ed882f7ef2fb8871e780bd (diff) |
Correct problems in clock setting.
One clock must be changed at a time, first setting the pll value,
then waiting for 16ms (one vsync), then setting the divider/shift
values, and again waiting 16ms.
Code was working after split of SMI501_ModeInit(), because some
clocks were already using system boot default, but would most likely
cause a crash when actually changing values (currently only p2_xxx
or v2_xxx is changed, but it would cause problems on some system where
the initial values don't match the ones set by the driver).
TODO: Either don't change m2clk and mclk or ensure other values
work correctly (don't change because the kernel should already
have set those if a value other then the boot default should be
used).
-rw-r--r-- | src/smi_501.c | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/src/smi_501.c b/src/smi_501.c index f7cfbf9..53ba0a8 100644 --- a/src/smi_501.c +++ b/src/smi_501.c @@ -427,26 +427,35 @@ SMI501_ModeInit(ScrnInfoPtr pScrn, DisplayModePtr xf86mode) static void SMI501_ModeSet(ScrnInfoPtr pScrn, MSOCRegPtr mode) { + int32_t pll; MSOCClockRec clock; SMIPtr pSmi = SMIPTR(pScrn); /* Update gate first */ WRITE_SCR(pSmi, mode->current_gate, mode->gate.value); + /* Start with current value */ clock.value = READ_SCR(pSmi, mode->current_clock); + field(clock, m_select) = field(mode->clock, m_select); - SMI501_SetClock(pSmi, mode->current_clock, clock.value, mode->clock.value); + pll = clock.value; + field(clock, m_divider) = field(mode->clock, m_divider); + field(clock, m_shift) = field(mode->clock, m_shift); + SMI501_SetClock(pSmi, mode->current_clock, pll, clock.value); - clock.value = READ_SCR(pSmi, mode->current_clock); field(clock, m2_select) = field(mode->clock, m2_select); - SMI501_SetClock(pSmi, mode->current_clock, clock.value, mode->clock.value); + pll = clock.value; + field(clock, m2_divider) = field(mode->clock, m2_divider); + field(clock, m2_shift) = field(mode->clock, m2_shift); + SMI501_SetClock(pSmi, mode->current_clock, pll, clock.value); - clock.value = READ_SCR(pSmi, mode->current_clock); if (pSmi->lcd) field(clock, p2_select) = field(mode->clock, p2_select); else field(clock, v2_select) = field(mode->clock, v2_select); - SMI501_SetClock(pSmi, mode->current_clock, clock.value, mode->clock.value); + pll = clock.value; + clock.value = mode->clock.value; + SMI501_SetClock(pSmi, mode->current_clock, pll, clock.value); WRITE_SCR(pSmi, MISC_CTL, mode->misc_ctl.value); |