Rask Ingemann Lambertsen wrote:
There doesn't appear to be a way for me to post a reply on the trac, so
I'll do so here. Feel free to repost my reply on the trac.
On Thu, Jun 18, 2009 at 07:20:48AM -0000, Openmoko Public Trac wrote:
Comment(by budfive):
I did some sleuthing by peeking into /dev/mem. Here's the analysis:
Before and after the suspend, all of the UART registers seem to be set
identically. This indicates that the UART module itself is likely not the
culprit. The other likely caus is the baud clock. It is likely running at
the wrong speed, causing the UART to read garbage and to report reception
errors. Further, since cpufreq is involved, it makes this possibility all
the more likely.
I decoded the UART error to 'framing error' a couple of weeks back. Other
noticable breakage when coming out of suspend:
1) HDQ doesn't work.
2) Audio plays too slowly.
3) CPU runs slower than normally.
4) Kernel clock runs much too slowly.
Looking at the clock registers, there are 2 discrepancies:
{{{
| Address | Meaning | Value before suspend | Value after suspend |
|------------+---------+----------------------+---------------------|
| 0x4C000004 | MPLLCON | 0x0002a010 | 0x0008e071 |
| 0x4C000014 | CLKDIVN | 0x00000005 | 0x00000007 |
}}}
This means that the MPLL configuration and the HCLK divider were changed.
My patch does not touch those registers. Decoding the register values, I
get:
Before suspend After suspend
M_SDIV = 0 M_SDIV = 1
M_PDIV = 1 M_PDIV = 7
M_MDIV = 42 M_MDIV = 142
MPLLclock = 400 [1] MPLLclock = 200 [2]
FCLK = MPLLclock FCLK = MPLLclock
HCLK = FCLK / 4 = 100 HCLK = FCLK / 3 = 66.7
PCLK = HCLK / 2 = 50 PCLK = HCLK / 2 = 33.3
[1] (2 * ( 42 + 8) * 12) / ((1 + 2) * 2^0) = 400
[2] (2 * (142 + 8) * 12) / ((7 + 2) * 2^1) = 200
The changed MPLL configuration probably isn't good either, but it's not
causing this particular breakage at least.
On the contrary, it (and the HCLK change) is exactly the problem.
The MPLLCON dividers happen to be exactly those used by U-Boot. I'm using
U-Boot as the bootloader. What about you?
Looking at arch/arm/plat-s3c24xx/pm.c, I see that when CONFIG_CPU_FREQ is
defined, MPLLCON and CLKDIVN are not saved and restored across suspends. I
could find nowhere that saves and restores CAMDIVN at all.
We are looking the same files?
s3c_pm_do_save, save the array of register and so I think that it saves
the MPLLCON and CLKDIVN
Michael