Adding a hotplug alternative or option to a kernel

Today was a pretty fun day. By God’s grace, I was able to add intelli_plug, a hotplug alternative made by Faux123, to my JFLTE kernel! Adding a hotplug was a lot easier than I thought it would be, and only required one trimming of the code by Faux123 to make it work on my kernel.

Some of you may wonder, well, what IS a hotplug? A hotplug is a controller that chooses how many of your cpu cores are going to be used at once. I know that sounds a lot like a governor, but a governor governs at what frequency the core(s) are used, and a hotplugger allows you to turn off cores that do not need to be utilized right now. This saves you battery life, and also helps to keep your phone or computer cool.

So, here’s what I did to make it work.

First, I added the intelli_plug.c file, which I found here:
https://github.com/antaril/AGK-OMNI/commit/635fd311f456ca5ae4690180556014b1ffd3ef79
I would recommend that you use mine however, as I had to ammend 2 lines to make it work with the JFLTE kernel.

Then, I added the appropriate lines to kconfig:

[CODE]
config INTELLI_PLUG
bool “Enable intelli-plug cpu hotplug driver”
default y
help
Generic Intelli-plug cpu hotplug driver for ARM SOCs WJH 20161222
[/CODE]
and Makefile:

[CODE]
obj-$(CONFIG_INTELLI_PLUG) += intelli_plug.o
[/CODE]
in the arch/arm/mach-msm folder.

Then I recompiled it. Note that I set the default option to “y”, so I didn’t need to add intelli_plug to my arch/arm/config/files, it simply is added by default to any kernel I build with that tree. On first run, there was an error on this line:

unsigned int avg_nr_run = avg_nr_running();

and This line:

if (avg_nr_run <= (nr_threshold << (FSHIFT – nr_fshift)))

but avg_nr_running() did not exist elsewhere in the kernel, so I commented these out with the double forward slash “//”. Normally, I would think it needs that, but in this case it still works okay. Upon rebuilding, it whent smoothly, and seems to work great!

Linux – keep it simple.

How to add an I/O Scheduler to your kernel

How to add an I/O Scheduler to your kernel:

Praise God, another succesful addition to the TBLTE kernel was that of adding the FIOPS I/O scheduler to the kernel. What is an I/O scheduler? Well it is the part of the kernel that handles, or schedules, input and output. Particularly, this has to do with writing and reading to and from media, like your hard drive, flash drive, etc.

So, how do we do that? How do we add I/O schedulers to our kernel?

Well, for the TBLTE kernel, I will show you what I did, and you can add to your kernel similarly.

Go to the block folder in your kernel source. The first thing that you need to do is add the fiops-iosched.c file. Whatever I/O scheduler you want to add will be named like this: {NAME-iosched.c} you can search Google or github for them, or take them from my source if you would like.

Once you put your fiops-iosched.c file in your kernel’s ./block/ folder, you can now edit two other files in that folder. You need to add the new scheduler to the make file, so it knows to make it, you can do that like so:

Open ./block/Makefile and add this line after the other *-iosched.o lines:

[CODE]
obj-$(CONFIG_IOSCHED_FIOPS) += fiops-iosched.o
[/CODE]

Notice that it just uses the name of the iosched file, but with an “.o” extension instead of a “.c” extension. The “.c” file you added earlier will create a “.o” (object) file that the Kernel needs to use to “make” the kernel.

Now edit the ./block/Kconfig.iosched file like so:

[CODE]
config IOSCHED_FIOPS
tristate “FIOPS I/O scheduler”
default y
—help—
The FIOPS I/O scheduler. WJH.
[/CODE]

This way, when you are moddifying your configuration, you can select to build it. Notice that it is a “default y”, essentially, I am telling the config file creator to allways assume I want to build this, unless I choose not to. You can also eddit the “—help—” portion to say anything you want. I put my initials in there so I can find it easily with the search tool.

Now open your configuration file. For the stock builds, that would be ./arch/arm/configs/ap88084_sec_defconfig, and add this line:

[CODE]
CONFIG_IOSCHED_FIOPS=y
[/CODE]

Note that you could also do this through

[CODE]$ make menuconfig [/CODE]

.
You may also note, since we gave it a “default y” in the Kconfig.iosched file, we don’t actually need to add this to our configs, as it will be built by default, but I like to declare what I am building in my configs so I remember what I am doing.

There you go! Now when you build your kernel again, the FIOPS I/O scheduler will be added in. It is remarkably simple, just the way I like it. You can read the commit here: [url]https://github.com/alaskalinuxuser/kernel_samsung_tblte/commit/f80320a895612bd1379ca789f88f1d6dfd6e68f9[/url]

Linux – keep it simple.

 

Building a kernel for an Android phone without the rom source

For the record, I do not recommend building kernels this way, I recommend that you build them within your ROM source. This method will work, but is far more labor intensive. However, here is how to build the kernel for a Samsung Galaxy Note Edge on Ubuntu 14.04.

Part 1 – The setup:
Go to

[CODE]
$ sudo apt-get install -y build-essential kernel-package libncurses5-dev bzip2 git make -y
[/CODE]

This will take a while. Then:

[CODE]
$ cd ~
$ mkdir playground
$ cd playground/
$ mkdir toolchain
$ cd toolchain
[/CODE]

Now type this for 4.9:

[CODE]
$ git clone https://android.googlesource.com/platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9
[/CODE]

OR this for 4.8, but for this I recommend 4.8.

[CODE]
$ git clone https://android.googlesource.com/platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.8
[/CODE]

The output either way should look like this:

[CODE]
Cloning into ‘arm-linux-androideabi-4.8’…
remote: Sending approximately 170.26 MiB …
remote: Counting objects: 124, done
remote: Finding sources: 100% (124/124)
………EDITED FOR SPACE………………
Resolving deltas: 100% (652/652), done.
Checking connectivity… done.
[/CODE]

That will take a few minutes. Then:

[CODE]
$ mkdir kernel
$ cd kernel
$ git clone https://github.com/alaskalinuxuser/kernel_samsung_tblte.git
Cloning into ‘kernel_samsung_tblte’…
remote: Counting objects: 49082, done.
remote: Compressing objects: 100% (32/32), done.
………EDITED FOR SPACE………………
Checking connectivity… done.
Checking out files: 100% (46422/46422), done.
[/CODE]

This will take another few minutes, maybe longer, depending on your internet connection.

Part 2 – The kernel modifications

Before going further, this is when you can edit the files of the kernel, add things, remove things from the kernel itself. See the other posts here for how to do that. When you are ready, you can move onto the build.

Part 3 – The build

Open ~/playground/toolchain/kernel/kernel_samsung_tblte/Makefile, and go to line 195, it should say ARCH, edit it as such:

[CODE]
ARCH =arm
CROSS_COMPILE =/home/{YOURUSERNAME}/playground/toolchain/arm-linux-androideabi-4.8/bin/arm-linux-androideabi-
[/CODE]

[CODE]
$ cd ~/playground/toolchain/kernel/kernel_samsung_tblte/
$ make clean
$ make mrproper
[/CODE]

You will likely see an error about TARGET, that is okay, just ignore it.

[CODE]
$ make menuconfig apq8084_sec_defconfig
[/CODE]

OR

[CODE]
$ make menuconfig apq8084_sec_tblte_eur_defconfig
[/CODE]

After some scrolling text, you will see a menu option. Use the arrow keys and the space bar to make selections. Make any changes you want. Remember, not all changes are good. With this setup, you will need to make changes to make this function.

Once you are done, select exit. Then select yes to save your config.

Now that you are back at the command line, all you have to do is type one more command:

[CODE]
$ make
[/CODE]

You will see a lot of scrolling text, like this:

[CODE]
arch/arm/kernel/return_address.c:63:2: warning: #warning “TODO: return_address should use unwind tables” [-Wcpp]
#warning “TODO: return_address should use unwind tables”
^
CC arch/arm/kernel/sched_clock.o
CC arch/arm/kernel/setup.o
CC arch/arm/kernel/signal.o
CC arch/arm/kernel/stacktrace.o
CC arch/arm/kernel/sys_arm.o
CC arch/arm/kernel/time.o
CC arch/arm/kernel/traps.o
CC arch/arm/kernel/atags_parse.o
CC arch/arm/kernel/cpuidle.o
[/CODE]

This is good. Make is making your kernel.
If you are good, or lucky, then it will compile successfully, if not, it will error. Check your changes and use Google to search for errors if you need help. Again, I recommend to build kernels within the backdrop of ROM source, as I mentioned in the other post, it is much, much easier. This method will work, but you may have to add or change a lot of options in your config to make it happen.

Linux – keep it simple.

 

Overclock an apq8084 Samsung Galaxy Note Edge!

In my continuing quest to make a better kernel for the Samsung Galaxy Note Edge (TBLTE, N915T), I decided to tackle overclocking the kernel. There are already some overclocked kernels out there, but I decided to do something slightly different with mine. The distinguishing feature of my overclocked kernel is that it doesn’t use any more power than it did before, and to God be the glory, it worked!

I also feel that when you overclock a chip, you are increasing the rate of failure, and the induced heat load. So I like to keep my overclocking light, less than 10% of the overall capacity that the chip was designed for. It is my hope that this will reduce wear and tear on the device while still providing superior performance.

Editing the tables for this chip was a lot simpler than for other chips I have worked on.

It all took place within the kernel/samsung/tblte/arch/arm/boot/dts/qcom/apq8084.dtsi file. Here is how it used to look:

[CODE]
………….EDITED FOR SPACE…………….
/* 2.7GHz RC1 */
qcom,speed2-pvs0-bin-v1 =
< 0 0 0 >,
< 300000000 810000 76 >,
< 345600000 820000 88 >,
………….EDITED FOR SPACE…………….
< 2496000000 1120000 813 >,
< 2572800000 1135000 849 >,
< 2649600000 1150000 886 >;
[/CODE]

And here was my change:

[CODE]
………….EDITED FOR SPACE…………….
/* 2.7GHz RC1 */
qcom,speed2-pvs0-bin-v1 =
< 0 0 0 >,
< 300000000 810000 76 >,
< 345600000 820000 88 >,
………….EDITED FOR SPACE…………….
< 2496000000 1120000 813 >,
< 2572800000 1135000 849 >,
< 2688000000 1150000 886 >;
[/CODE]

That’s right, I only made a 39MHz change. I feel this was appropriate to keep the device cool and continue to use the same voltages. So it is essentially a 39MHz boost with no noticable consequences. Of course, I had to do the above to each speed and pvs table in that file.

Then, I needed to edit this portion:

[CODE]
………….EDITED FOR SPACE…………….
qcom,msm-cpufreq@0 {
reg = <0 4>;
compatible = “qcom,msm-cpufreq”;
qcom,cpu-mem-ports = <1 512>;

qcom,cpufreq-table =
< 300000 300000 1144 800 >,
< 422400 422400 2288 800 >,
………….EDITED FOR SPACE…………….
< 2572800 1728000 16250 10101 >,
< 2649600 1728000 16250 10101 >;
………….EDITED FOR SPACE…………….
[/CODE]

To this:

[CODE]
………….EDITED FOR SPACE…………….
qcom,msm-cpufreq@0 {
reg = <0 4>;
compatible = “qcom,msm-cpufreq”;
qcom,cpu-mem-ports = <1 512>;

qcom,cpufreq-table =
< 300000 300000 1144 800 >,
< 422400 422400 2288 800 >,
………….EDITED FOR SPACE…………….
< 2572800 1728000 16250 10101 >,
< 2688000 1728000 16250 10101 >;
………….EDITED FOR SPACE…………….
[/CODE]

It actually was the only time I have overclocked a kernel on the second try. Don’t think too highly of me, though, I spent hours reviewing kernel edits for overclocking by various other kernel developers on GitHub. If you are looking to do the same, you should spend some time looking at working code for others, and then make your own tables.

If you were to compare my tables with everyone elses, you would see that I have done it differently than my contemporaries, even though we reached similar, or in some cases, identical results. I like to keep the code clean, short, and sweet. Often when overclocking, most kernel developers will add more lines to the tables. I have found that while that may be the best to maximize use, my method is much simpler and easy to implement, as well as follow, and that is what Linux should be all about, keeping it simple.

Linux – keep it simple.

 

Adding a kernel governor can be a Nightmare!

Okay, so a little play on words, especially since I am adding the Nightmare governor to the tblte (Samsung Galaxy Note Edge) kernel, but it did turn out to be a bit of a problem child, fortunately, it was quickly corrected. As you can see, I did the standard additions, as well as adding the cpufreq_nightmare.c file:

Added to Makefile:

[CODE]
………….EDITED FOR SPACE…………………..
obj-$(CONFIG_CPU_FREQ_GOV_NIGHTMARE) += cpufreq_nightmare.o
………….EDITED FOR SPACE…………………..
[/CODE]

Added to Kconfig:

[CODE]
………….EDITED FOR SPACE…………………..
config CPU_FREQ_DEFAULT_GOV_NIGHTMARE
bool “nightmare”
select CPU_FREQ_GOV_NIGHTMARE
help
Use the CPUFreq governor ‘nightmare’ as default. -WJH
………….EDITED FOR SPACE…………………..
config CPU_FREQ_GOV_NIGHTMARE
tristate “‘nightmare’ cpufreq policy governor”
help
‘nightmare’ – This driver is a modified PegasusQ.

To compile this driver as a module, choose M here: the
module will be called cpufreq_nightmare.

For details, take a look at linux/Documentation/cpu-freq.

If in doubt, say N. -WJH
………….EDITED FOR SPACE…………………..
[/CODE]

Added to cpufreq.h:

[CODE]
………….EDITED FOR SPACE…………………..
#elif defined(CONFIG_CPU_FREQ_DEFAULT_GOV_NIGHTMARE)
extern struct cpufreq_governor cpufreq_gov_nightmare;
#define CPUFREQ_DEFAULT_GOVERNOR (&cpufreq_gov_nightmare)
………….EDITED FOR SPACE…………………..
[/CODE]

Added to config:

[CODE]
………….EDITED FOR SPACE…………………..
CONFIG_CPU_FREQ_GOV_NIGHTMARE=y
………….EDITED FOR SPACE…………………..
[/CODE]

But, when I ran the compiler, I got this output:

[CODE]
/home/alaskalinuxuser/Documents/projects/phones/compile/build_slim6/kernel/samsung/tblte/drivers/cpufreq/cpufreq_nightmare.c: In function ‘nightmare_check_cpu’:
/home/alaskalinuxuser/Documents/projects/phones/compile/build_slim6/kernel/samsung/tblte/drivers/cpufreq/cpufreq_nightmare.c:540:2: error: implicit declaration of function ‘cpufreq_notify_utilization’ [-Werror=implicit-function-declaration]
cpufreq_notify_utilization(policy, max_load);
[/CODE]

So I edited that line out in build_slim6/kernel/samsung/tblte/drivers/cpufreq/cpufreq_nightmare.c:

[CODE]
// WJH cpufreq_notify_utilization(policy, max_load);
[/CODE]

And viola! By God’s grace it even worked! That usually doesn’t get fixed so easily, so I guess that wasn’t so bad.

Linux – keep it simple.

 

Resurrection Remix 5.7.4 for the JFLTETMO

In my continuing quest to provide more roms and kernels for the Samsung Galaxy S4, T-Mobile variant, God has graciously blessed, allowing me to complete the latest addition of Resurrection Remix 5.7.4! Below you can see a link for the Rom and Kernel.

Resurrection Remix 5.7.4 JFLTETMO only.

http://www.mediafire.com/file/l5z861s1z0l46xy/ResurrectionRemix-M-v5.7.4-20161004-jfltetmo.zip

AKLU-mm-jf-ResurrectionRemix5.7.4 kernel!
A kernel specifically built for RR 5.7.4! Can be flashed to any jf variant phone. Good for JFLTETMO, JFLTEXX, and possibly others!
Download: http://www.mediafire.com/file/9cl559str0hlsih/rr574_aklu_kernel.zip

Features:
-Lionheart and many other governors
-CPU overclocked to 1998MHz
-GPU overclocked to 487Mhz
-GPU/CPU voltage control
-Fast charge
-Psudo file system encryption support
-Fauxsound 2.1

Adding a new I/O scheduler to your Kernel

In my continuing effort to learn about kernel modification, I was blessed to be able to add a new I/O scheduler to my kernel. To be honest, the ArcTeam kernel that I started with was already well equiped in the I/O scheduler department, but as this is a learning experience, I just had to add one more!

The kernel already included noop, deadline, row, cfq, fiops, sio, and bfq. There really were not many options left of what to add, and of the few that remained there was some ambiguity of quality. However, I chose the VR I/O scheduler, and got to work.

First, I added the new I/O scheduler to block/Kconfig.iosched, like so:

[CODE]
config IOSCHED_VR
tristate “VR I/O scheduler”
default y
—help—
The VR I/O scheduler gives the best benchmark readings, but is
somewhat unstable/unreliable for daily use.
[/CODE]

This makes it an option that can be selected when you are compiling the kernel, such as when using

[CODE]$ make menuconfig[/CODE]

.

Next on the agenda was adding it into the block/Makefile:

[CODE]
+obj-$(CONFIG_IOSCHED_VR) += vr-iosched.o
[/CODE]

Note that the file here is an .o (object file) but the actual file we will add is the block/vr-iosched.c file. That is because the makefile needs the object made FROM the c file, not the c file itself.

Finally, we copy our block/vr-iosched.c file into the block directory. It is over 400 lines long, or I would post it here. Surprisingly simple! I like to keep things simple!

You can even check it out on my github at: https://github.com/alaskalinuxuser/kernel_samsung_jf/commit/904abfe90be7e27908dc0ac8f03d5f8bbfd37714

Linux – keep it simple.

 

Overclocking the GPU on a Samsung Galaxy S4

We talked about overclocking the CPU of the S4 (SGH-M919) before, but today I wanted to point out some great work by Faux123 that showed me exactly what to do to overclock the Graphics Processor Unit (GPU) of my S4. Faux123’s work was far more impressive then my own, with if/then statements and options to compile with and without it. However, for a simpleton like myself, I just put it straight in, without all the options. I put it in without options because I want it to be in there! Here is a link to Faux123’s commit:

https://github.com/f1vefour/mako/commit/ce53045d110088dca52bcad6ffa6f94bd06f0a70

I am including it here so that you can review it and see a true master at work, as well as to give credit where it is due. Below is my adaptation of that work.

Faux123 started by making some edits and changes to the kconfig file. This allowed the option of compiling a kernel with, or without the GPU overclocking. However, as I stated earlier, I want to compile it with the GPU overclocked every time, so I didn’t add that in. Because of this, I didn’t need all of the if/then statements that were seen in the rest of the work. Also, Faux123 was working with a board-mako, but I am working with an S4, so I used differnt files. Here is what I did change, though:

kernel_samsung_jf/arch/arm/mach-msm/board-8064-gpu.c

[CODE]
static struct msm_bus_vectors grp3d_max_vectors[] = {
{
.src = MSM_BUS_MASTER_GRAPHICS_3D,
.dst = MSM_BUS_SLAVE_EBI_CH0,
.ab = 0,
.ib = KGSL_CONVERT_TO_MBPS(5920),
},
{
.src = MSM_BUS_MASTER_GRAPHICS_3D_PORT1,
.dst = MSM_BUS_SLAVE_EBI_CH0,
.ab = 0,
.ib = KGSL_CONVERT_TO_MBPS(5920),
},
};
…………EDITED FOR SPACE………….
static struct kgsl_device_platform_data kgsl_3d0_pdata = {
.pwrlevel = {
{
.gpu_freq = 487500000,
.bus_freq = 4,
.io_fraction = 0,
},
{
.gpu_freq = 320000000,
.bus_freq = 3,
.io_fraction = 33,
},
[/CODE]

That line:

[CODE].ib = KGSL_CONVERT_TO_MBPS(5920),[/CODE]

used to say a lower number:

[CODE].ib = KGSL_CONVERT_TO_MBPS(4264),[/CODE]

, and the

[CODE].gpu_freq = 487500000,[/CODE]

used to say

[CODE].gpu_freq = 450000000,[/CODE]

.

Then I simply added a line to kernel_samsung_jf/arch/arm/mach-msm/clock-8960.c:

[CODE]
/*Shared by 8064, 8930, and 8960ab*/
static struct clk_freq_tbl clk_tbl_gfx3d[] = {
F_GFX3D( 0, gnd, 0, 0),
F_GFX3D( 1800000, pxo, 1, 15),
F_GFX3D( 27000000, pxo, 0, 0),
F_GFX3D( 48000000, pll8, 1, 8),
F_GFX3D( 54857000, pll8, 1, 7),
F_GFX3D( 64000000, pll8, 1, 6),
F_GFX3D( 76800000, pll8, 1, 5),
F_GFX3D( 96000000, pll8, 1, 4),
F_GFX3D(128000000, pll8, 1, 3),
F_GFX3D(145455000, pll2, 2, 11),
F_GFX3D(160000000, pll2, 1, 5),
F_GFX3D(177778000, pll2, 2, 9),
F_GFX3D(192000000, pll8, 1, 2),
F_GFX3D(200000000, pll2, 1, 4),
F_GFX3D(228571000, pll2, 2, 7),
F_GFX3D(266667000, pll2, 1, 3),
F_GFX3D(320000000, pll2, 2, 5),
F_GFX3D(400000000, pll2, 1, 2),
F_GFX3D(450000000, pll15, 1, 2),
F_GFX3D(487500000, pll15, 1, 2),
F_END
};
[/CODE]

This line added the 487MHz frequency as an option in the GPU table. Then I changed the old “high” from 450000000 to 487500000, like so:

[CODE]
static unsigned long fmax_gfx3d_8064[VDD_DIG_NUM] = {
[VDD_DIG_LOW] = 128000000,
[VDD_DIG_NOMINAL] = 325000000,
[VDD_DIG_HIGH] = 487500000
};
[/CODE]

That was all there was to it! Faux123 has several more additions/subtractions, but I didn’t need to specify different tables and such, because I just edited the original table, rather than make new tables specific for overclocking the GPU. Praise God! After compiling, it worked!

Linux – keep it simple.

The easy guide to understanding CPU and GPU governors

There are a lot of guides out there about CPU and GPU governors. They are all very informative, and usually somewhat technical. The other day, however, I needed to explain CPU and GPU governors to a non-technical person, and I realized that a lot of big verbiage and vague terms get thrown around which help the technical, but cloud the issue for some. So, I decided to share my non-technical explanation here, in hopes that it will help others also. This is not a perfect analogy, nor a technical one, but I think it gets the job done.
Consider driving your car in the rain.
The more it rains, the less you can see. Hence the slower you should drive. Each swipe of the windshield wiper clears the window. The rain is like the CPU/GPU load, or how much work the CPU/GPU needs to do to clear the windshield.

Sometimes it is raining very hard. Sometimes it is a sprinkle. But in this make believe world, it is always raining.

As the driver of the car, you get to pick the speed at which the wipers swipe. It is entirely up to you, you are the governor, or the one in charge of the windshield wipers. You can’t control how much it rains, but you can control how fast your wipers swipe the windshield clear.

There are many types of drivers out there, just like there are many governors. However, they all fall into several basic categories.

The Performance type governors are like a driver who gets into the car, and he turns on the wipers full speed. Even if it is barely raining. No matter how much rain does, or does not fall on the windshield, he keeps the wipers going full blast. This works very well to keep the windshield clear. However it also makes the wiper blades get pretty hot when it is just a sprinkle. All the friction from swiping back and forth will eventually wear out his wiper blades, and he will replace them a lot sooner if he does this, but his windshield will stay clear!

The Powersave type of governors are like a driver who gets into her car and turns the wipers on at the lowest possible speed, with the longest delay between swipes. This works great if it is just sprinkling, but anytime she gets into a down pour, she has to practically come to a stop, because she can’t see where she is going through all that rain on her windshield.

The On Demand type governors, are the drivers who are always adjusting by wild amounts. “Oh, it’s raining harder, I will turn the wipers all the way up!” He says. “Oh, I guess that was too much. I’ll turn them down now.” Back and forth this driver goes, always pushing up to maximum wiper speed, only to find that he should probably turn the wiper speed down. Often, this guy is over-adjusting for the actual amount of rain, but his windshield stays pretty clear. Essentially, he has become his own delay module, waiting for rain on the windshield, he then turns on the wipers to clear it, then practically turns the wipers off. Then repeat, over and over again.

The Conservative type governors, however, take a more methodical approach. When she sees that it is raining harder, she turns her wiper speed up one notch. Then she waits a few seconds to see how well that works. Not enough wiper speed to keep the window clear? Then she will turn up the wiper speed another notch. Still not enough? Then she turns the wiper speed up another notch. One notch at a time, with a moment to check the results before making another correction. Then, if the wipers are too fast, she turns them down one notch. The process continues, constantly adjusting, one notch at a time. This can work very well. It can also be problematic if there is a huge change in the amount of rain. If it was sprinkling, and then starts to pour, it may be a while before she gets her wiper blades to “catch up” with the amount of rain.

Of course, there are Ideal frequency governors. This man has already determined that if it is raining, he will use a particular delay or speed setting for his wipers. He may adjust them slightly if it is raining more or less, but he will always strive to keep his wipers at the setting that he already determined was the one that he thought was best. Usually this setting is somewhere in the middle. Not really performance, not quite powersave, just somewhere in the middle that he thinks is best. This can work good for average use, but can be taxing your battery while “coasting” and can be less able to handle heavy rains (high work loads).

Then there are the dependent type of governors. This person gets into her car and begins to drive through the rain. Rather than setting her wipers based on her view out the window, this lady sets her wiper speed based on some other variable. For instance, the Intellidemand governor sets the CPU frequency based on GPU speed. This would be like a woman who sets her wiper speed based on her car’s speedometer. If she is driving faster, then she turns up the wiper speed. If she is driving slower, then she turns down her wiper speed. It makes sense, but works only as good as the thing controlling it. It seems like a good idea, if you drive faster, you need a clearer windshield, so you should wipe the rain away faster. The only issue here is that it may not be raining very hard, yet, because you are driving faster, you must set your wipers to swipe faster. Generally this works very well, but may not work in every condition. Some of these governors have other variables, such as “touch poke” where the CPU frequency, or wiper speed, goes up when you touch the screen. Much like turning up the wiper speed when the hi-beam headlights get turned on.

Essentially, all governors are like one or more, or some combination of, the above. Most simply fine tune the variables or combine some functions of the above to get the results they want. Some are designed for power saving, others for performance.
So, which one is the best?

Well, that depends. Is it raining really hard all the time? Does it barely rain at all? Is there just a good gully-wash once a day, and other than that it is just a sprinkle?

Lots of people argue over which one is the best, but it is really hard to quantify. The reality of it is not which governor is the “best” but which governor is the “best for you”. Only you know what your daily “rainfall” is like. Perhaps you are okay with driving a little slower in the rain. You might even enjoy it. Maybe you have ADD and need that windshield spotless all the time. I don’t know.

A few thoughts for you to consider though:

Do you need your phone to be battery friendly?
I get up at 4:30 AM every morning for work. I put my phone back on the charger every night around 8-9 PM. My battery only has to last 16-17 hours. Typically, based on my choices and daily use, I average about 50% battery life left when I put it on the charger. Based on my usage, I could choose a more performance driven governor, and not have to worry too much about battery usage. If you are always out and about, in the wild, hiking, camping, fishing, you may want to consider a more battery friendly option to extend your use for longer trips between chargers. My point being that it does you little good to choose so many battery friendly options that your phone lasts 6 days on a charge, but you plug it in every night.

Do you need your phone to out perform anybody?
I don’t play video games. I rarely watch youtube/hulu/netflix/vudu/(name your video streaming service here) on my phone. Do I need a performance based governor? Sure, the benchmarks are impressive, but does it really mater that you are clocking max speeds to check you email?

You don’t have to choose just one setting.
Many people get “stuck in a rut” (back to our car analogy) when it comes to settings like governors. With apps such as Kernel Adiutor, Device Control, and others, you can set profiles, or make backup configurations that you can quickly implement when you want to. If you hardly use your phone when you are at work, but become a gaming fiend at home. Maybe it is the opposite, at work you use your phone for serious number crunching with some math apps, and at home it just becomes your telephone. Choose a different option that suits your needs in each instance.

What do I use?
Well, again, it really depends on what you do day to day. For me, I play chess on my phone, read a Bible app, I check my emails (work and home), I browse the internet, Github, WordPress and XDA, take a few pictures of the kids, make a few phone calls, and send a few texts. That’s it. So for me, I use the Lionheart governor for my CPU. The vote is still out on GPU, but I have been testing the Simple GPU governor, and I think that it works pretty well.

Linux – keep it simple.

Overclocking the CPU on a Samsung Galaxy S4

I have been trying to follow every guide out there to overclock my Samsung Galaxy S4 (SGH-M919), and until now I have had absolutely no luck! It wasn’t until I saw some work on a kernel by Faux123 that I realized the difference in kernel setups. Once I tried it, by God’s grace, it worked! Granted, I couldn’t straight up implement Faux123’s work, because that was for a slightly different kernel and setup, but the overall ideas and information helped tremendously! Knowing that I had so much trouble makes me want to share it here, so others can use this information.

The reason I was having so much trouble, is the guides I was reviewing had a different structure for thier chips controls that that of the S4. Overall it works the same, but the syntax and setup were different, causing me to create never ending bootloop kernels that couldn’t do anything, let alone be faster versions of thier predecessor!

Ultimately, overclocking your cpu, for the S4 at least, comes down to these 2 files:

kernel_samsung_jf/arch/arm/mach-msm/acpuclock-8064.c
kernel_samsung_jf/arch/arm/mach-msm/cpufreq.c

Granted, I am still new at this, and there are probably better and fine tune ways to do this, but here is how I did it. In the acpuclock-8064.c file, there were many tables of cpu frequencies for different levels and conditions. Here is the pre-overclocked version:

[CODE]
static struct acpu_level tbl_PVS6_2000MHz[] __initdata = {
{ 1, { 384000, PLL_8, 0, 0x00 }, L2(0), 875000 },
{ 1, { 486000, HFPLL, 2, 0x24 }, L2(5), 875000 },
{ 1, { 594000, HFPLL, 1, 0x16 }, L2(5), 875000 },
{ 1, { 702000, HFPLL, 1, 0x1A }, L2(5), 875000 },
{ 1, { 810000, HFPLL, 1, 0x1E }, L2(5), 887500 },
{ 1, { 918000, HFPLL, 1, 0x22 }, L2(5), 900000 },
{ 1, { 1026000, HFPLL, 1, 0x26 }, L2(5), 925000 },
{ 1, { 1134000, HFPLL, 1, 0x2A }, L2(14), 937500 },
{ 1, { 1242000, HFPLL, 1, 0x2E }, L2(14), 950000 },
{ 1, { 1350000, HFPLL, 1, 0x32 }, L2(14), 962500 },
{ 1, { 1458000, HFPLL, 1, 0x36 }, L2(14), 975000 },
{ 1, { 1566000, HFPLL, 1, 0x3A }, L2(14), 1000000 },
{ 1, { 1674000, HFPLL, 1, 0x3E }, L2(14), 1025000 },
{ 1, { 1782000, HFPLL, 1, 0x42 }, L2(14), 1062500 },
{ 1, { 1890000, HFPLL, 1, 0x46 }, L2(14), 1100000 },
[/CODE]

The second column lists the frequency that is available, and the last column tells the cpu how much voltage to use to make it work. Here is where I did some basic math. I wanted to overclock the last variable to be more than 1890000, but how much was too much, and what numbers were appropriate? Faux123’s work didn’t tell me that, but looking over the work that Faux123 did showed me where to make the edits. Essentially, I decided that these must be based on some sort of mathmatical principle. Turns out that I must be right.

1890000-1789000=108000
1789000-1674000=108000
1674000-1566000=108000
etc….

So, I concluded that the frequency changes *should* be made in 108MHz jumps. So, by extrapolation:

1890000+108000=1998000

This then, gave me the new target frequency of 1998000!

Then there was a question of voltage. Maximum and minimum voltage is set at the beginning of the file, like so:

[CODE]
[CPU0] = {
.hfpll_phys_base = 0x00903200,
.aux_clk_sel_phys = 0x02088014,
.aux_clk_sel = 3,
.sec_clk_sel = 2,
.l2cpmr_iaddr = 0x4501,
.vreg[VREG_CORE] = { “krait0”, 1300000 },
.vreg[VREG_MEM] = { “krait0_mem”, 1150000 },
.vreg[VREG_DIG] = { “krait0_dig”, 1150000 },
.vreg[VREG_HFPLL_A] = { “krait0_hfpll”, 1800000 },
},
[/CODE]

I am not going to lie to you and tell you that I understand what all of that means, but what I can tell you is that VREG_CORE seems to be the maximum voltage you can apply to that core. In the case of my overclocking expirement, I twiddled with several variations, but eventually decided to leave the max where it was.

Back to our example, I decided to go with this:

[CODE]
static struct acpu_level tbl_PVS6_2000MHz[] __initdata = {
{ 1, { 384000, PLL_8, 0, 0x00 }, L2(0), 875000 },
{ 1, { 486000, HFPLL, 2, 0x24 }, L2(5), 875000 },
{ 1, { 594000, HFPLL, 1, 0x16 }, L2(5), 875000 },
{ 1, { 702000, HFPLL, 1, 0x1A }, L2(5), 875000 },
{ 1, { 810000, HFPLL, 1, 0x1E }, L2(5), 887500 },
{ 1, { 918000, HFPLL, 1, 0x22 }, L2(5), 900000 },
{ 1, { 1026000, HFPLL, 1, 0x26 }, L2(5), 925000 },
{ 1, { 1134000, HFPLL, 1, 0x2A }, L2(14), 937500 },
{ 1, { 1242000, HFPLL, 1, 0x2E }, L2(14), 950000 },
{ 1, { 1350000, HFPLL, 1, 0x32 }, L2(14), 962500 },
{ 1, { 1458000, HFPLL, 1, 0x36 }, L2(14), 975000 },
{ 1, { 1566000, HFPLL, 1, 0x3A }, L2(14), 1000000 },
{ 1, { 1674000, HFPLL, 1, 0x3E }, L2(14), 1025000 },
{ 1, { 1782000, HFPLL, 1, 0x42 }, L2(14), 1062500 },
{ 1, { 1998000, HFPLL, 1, 0x46 }, L2(14), 1100000 },
{ 0, { 0 } }
[/CODE]

Notice that I didn’t increase the voltage at all. Actually, after several tests, I found that I could do more with less! In this case (probably not every case), I could increase the frequency, and esentially undervolt it to use the same voltage to do more work. Before finding this, however, I had worked out a voltage system:

1100000-1062500=37500
1062500-1025000=37500
1025000-1000000=25000
1000000-975000=25000
975000-962500=12500
etc….

It would appear that the voltages increment upwards as the frequency increases. Using this theory and table, I presumed that the next voltage would be +50000. It seems to go 2 steps at the same increase, and then incrementally increase by 12500. So, either the next step was a continuation of +37500, or an additional +37500+12500, which would be +50000. If I was increasing the voltage, these would be some safe steps, provided that the accumulative answer did not progress above my max limit of 1300000, defined earlier. If it does need to exceed that, then I need to also increase max voltages. In either event, I must be wrong about something, or this is a great undervoltage example, because without increasing the voltage, the kernel did overclock by 108MHz.

Now there is another step to do. We still have to edit the cpufreq.c file. Fortunately, Faux123’s work pointed me right to this, and it was a simple change. All one has to do, is write in the new upper_limit_freq, which is the new maximum frequency:

[CODE]
static unsigned int upper_limit_freq = 1566000;
#else
static unsigned int upper_limit_freq = 1998000;
#endif
[/CODE]

Pretty slick, huh! I am really glad people like Faux123 and Github exist, so people who need help (like me) can review their code and find where one has to make changes to do things like overclocking. All I did after editing these two files was compile the new kernel. Granted, I did play around a bit with some other voltages/frequencies, but this was realitively simple and worked great compared to the other failed attempts to follow the overclocking guides on the web!

Linux – keep it simple.