[Galaxy S I9000 Android Development] newmail:
[EDIT: Feel free to jump to comment #9]

[EDIT2: last version of the patch to apply to the kernel is in comment #25, applying the patch to the kernel source is all you need to test]

[EDIT3: changed name to deep cpuidle, I figured "deep sleep" is usually meant as "suspend-to-ram" and this has nothing to do with suspend, suspend is entered at fixed SLEEP_FREQ and the cpu frequency is irrelevant during suspend because CPU power is cut-off]

On my galaxy S I've been monitoring my cpufreq stats and the stats/total_trans keeps increasing every second or so with default cpufreq values and ondemand governor, when the screen is off and the cellphone is idle. This means the cpu spends some time spent at the high frequency even if the cellphone is idle and screen off.

I noticed if I increase the ondemand/sampling_rate from the default 40000 (on i9000) to 80000 the total_trans go down to one every 10 or 20 sec. But I want to decrease the sampling_rate to 20000 so it takes only 20msec to jump to 1ghz. 40msec (the default) is too much. 40msec means 25hz but the first image frame would get lost because it'd be rendered at 100mhz instead of 1ghz. at 20msec of sampling_rate the frequency is 50hz so if the first frame is lost we're still down to 25hz which is less noticeable to the eye. I think 20000 is the max that sampling_rate should be set for decent responsiveness.

However if I drop the sampling_rate to 20000 as I prefer, when the screen is off the stats/total_trans increases even faster at a couple per second, than with the default of 40000, so sampling_rate 20000 is ideal for responsiveness but it will waste power when the screen is off.

So my solution is to force the max frequency allowed by the cpu policy to the min frequency when the screen is off. After that I can easily set sampling_rate to 20000 and io_is_busy to 1, by adding this the init.rc of the initramfs. I prefer io_is_busy to be 1, because 100mhz is really slow and the I/O will take some significant percentage of CPU too if set at 100mhz, and especially because after the I/O is complete I'll avoid losing one frame.

write /sys/devices/system/cpu/cpufreq/ondemand/io_is_busy 1

write /sys/devices/system/cpu/cpufreq/ondemand/sampling_rate 20000

I'm also testing with up_threshold 80 but I'm not sure if it is better or worse... need to do more tests on the below one, could be a bad idea.

write /sys/devices/system/cpu/cpufreq/ondemand/up_threshold 80

This way I can tune the ondemand as aggressive as I need without sacrificing the powersaving when the screen is off. In fact it should use less power now when the screen is off than before.

The patch is for the ginger update2 kernel, running 2.3.4 XXJVR using the kernel modules of XXJVS (I rolled back the userland and initramfs to JVR because JVS disconnects wifi for me).

I've noticed there's a smartass2 governor which I didn't try, it may work better than this, but I tend to trust the ondemand governor to be the best for responsiveness, and my approach is much simpler than the smartass2 governor, I'm not in a mood of doing beta testing or risking instability for a feature that can be achieved so simply. If ondemand isn't aggressive enough I prefer ondemand to be improved to be more aggressive. Ondemand is what runs on most laptops/workstations so we can't afford it not to be as fast as it can.... The problem is not specific to cellphones. And when screen is off there is not point to ever increase the frequency over 100mhz on i9000 (and unfortunately it happens and it's not fair to pretend some background service to call usleep(1) just to avoid the frequency jump).

Note, you may want to remove the two printk from the patch, they shouldn't flood but they're only for debug...