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.