[How-To] OC/UV a kernel

Search This thread

RaymanFX

Inactive Recognized Developer
Jan 8, 2011
1,122
16,501
28
Hannover
As I cannot find any related guide while google-ing, I want to post this question on here for the purpose of learning and probably helping other people.

[Q1] How to overclock a kernel

  • which files are needed -> kernel source .. ?
  • what files need to be edited ?
  • is the cpufreq driver related ?
  • how to determine which frequencies need higher voltage and how high exactly ?

[Q2] Undervolting

  • which files are needed -> kernel source .. ?
  • what files need to be edited ?
  • is the cpufreq driver related ?
  • how to determine which frequencies can use lowered voltage and how to calculate them ?



I would be very thankful if any developer could teach me (probably others too) and I will contribute back for sure.
I am right now fixing up bugs in TeamGummy rom, and I'm nearly finished.
Only thing I lack is a custom kernel, which I want to build myself along with the rom.

*push*

Watch out guys, master guevor is going to teach us a little of his enormous knowlegde, so better keep your eyes on this one.

:)
 
Last edited by a moderator:

guevor

Senior Member
Aug 20, 2010
361
1,104
Valencia
Overclocking

I must say that all I'm going to write, is what I've gathered looking at the code and changes made by others (thanks Blades and Roach2010) (I have not had any documentation about it), so I could make mistakes or misinterpretation.
Nor do I explain everything, because if you do not have a minimal knowledge get to play this directly may be dangerous:eek:.

(Q1) Overclocking
Files to modify

  • arch/arm/mach-tegra/tegra2_clocks.c (All matters relating to the frequencies.)
The system uses a series of programmed pll clocks which in turn can be used as a basis to other clocks. Let's say for this case pll_x is used for the base of processor clock.
The frequency table are in tegra_pll_x_freq_table processor. Seeing the type definition clk_pll_freq_table in clock.h we know that has entries consisting of 6 values​​. (input_rate, output_rate, n, m, p, cpcon)
These values ​​allow tegra2_pll_clk_set_rate function to set the pll frequency.
The values ​​of interest are the frequency of input and output that indicates the input frequency base to be used and what frequency we want to set (it will use the frequency corresponding to the current base and the output frequency we want). m * p values ​​give us the divisor and n is the multiplier. For simplicity we say that n/(m*p) will give us the multiplier, which applied to the base frequency will give the target frequency.

So if we want to add new frequencies, we must add entries in this structure (tegra_pll_x_freq_table) so the system knows how to program a frequency we want to use.
Add 4 entries for each frequency we want to add (one for each base frequency: 12000000,13000000,19200000,26000000 in our case), with multipliers/dividers to calculate the frequency for which we are adding.

If we add higher frequencies than at present, we have to change the maximum (max_rate) in the tegra_clk_virtual_cpu and tegra_clk_cclk structures, otherwise the system will ignore it. Also have to change the limits for our type of processor in sku_limits. For this case the cpu, cclk y pll_x in the values ​​for our processor (0x04, 0x08, 0x0F).

Finally we modify the table of frequencies used by the processor (frequency list and their order). Is defined at cpufreq_tables and contains a list of lists where we can add a new list or not to touch anything and modify an existing list.
We can look at the existing list freq_table_1p2GHz or in my source I added the list freq_table_1p7GHz.
Contains a list of frequencies that the system can select. It uses the list whose maximum corresponds to the maximum indicated above.

  • arch/arm/mach-tegra/tegra2_dvfs.c (Everything related to the voltages and its relationship with the frequencies.)
This part is much more sensitive and therefore can affect much to the duration of the battery as to stability. I have no formula (unfortunately for me) on how to modify the values, so the task has been more trial and error.
The first thing to know is that one must distinguish between the core voltage and the cpu and should be the latter inferior to the first. In tegra2_dvfs_rel_vdd_cpu_vdd_core function establishes the relationship between the two, being the default 120mV core above the cpu.
Basically what we do if we have added frequencies higher than normal, is to increase the voltage so that they are stable (depend on each processor). I recommend (at first) increment in the same extent all the values ​​involved (maximum voltage).

Therefore we can modify:

  • Table core_millivolts, establishing the voltages that core can use.

  • Table cpu_millivolts, establishing the voltages that cpu can use. It contains all the steps and should take into account the difference with the core discussed earlier. If we added any frequency, we add the corresponding voltages.

  • Tables core_speedo_nominal_millivolts and cpu_speedo_nominal_millivolts contain a nominal voltage of both the core and the cpu.

  • The maximum and nominal voltages in structures tegra2_dvfs_rail_vdd_cpu, tegra2_dvfs_rail_vdd_core and tegra2_dvfs_rail_vdd_aon.

  • Finally we adjust the settings for dvfs_init ("cpu", 1,) according to the list of frequencies we want to use (adding if we added new frequencies or changing them if changed change some)
With these changes we should be able to overclock, although we know that although you can configure (once started) a maximum frequency below the maximum that we put on the tables, there is a problem and many times after suspending the system will use the maximum frequency of the table. To avoid this we must make some changes in cpufreq.c

  • drivers/cpufreq/cpufreq.c
The problem occurs in the second core when reconnected after being disconnected in the suspension process. The problem is solved with the next patch.

Code:
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index e157205..2626e2d 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -1048,18 +1048,27 @@ static int cpufreq_add_dev(struct sys_device *sys_dev)
 
        /* Set governor before ->init, so that driver could check it */
 #ifdef CONFIG_HOTPLUG_CPU
+       struct cpufreq_policy *cp;
        for_each_online_cpu(sibling) {
-               struct cpufreq_policy *cp = per_cpu(cpufreq_cpu_data, sibling);
+               cp = per_cpu(cpufreq_cpu_data, sibling);
                if (cp && cp->governor &&
-                   (cpumask_test_cpu(cpu, cp->related_cpus))) {
+                       (cpumask_test_cpu(cpu, cp->related_cpus))) {
+                       dprintk("found sibling CPU, copying policy\n");
                        policy->governor = cp->governor;
+                       policy->min = cp->min;
+                       policy->max = cp->max;
+                       policy->user_policy.min = cp->user_policy.min;
+                       policy->user_policy.max = cp->user_policy.max;
                        found = 1;
                        break;
                }
        }
 #endif
        if (!found)
+       {
+               dprintk("failed to find sibling CPU, falling back to defaults\n");
                policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
+       }
        /* call driver. From then on the cpufreq must be able
         * to accept all calls to ->verify and ->setpolicy for this CPU
         */
@@ -1071,6 +1080,16 @@ static int cpufreq_add_dev(struct sys_device *sys_dev)
        policy->user_policy.min = policy->min;
        policy->user_policy.max = policy->max;
 
+    if (found)
+        {
+        /* Calling the driver can overwrite policy frequencies again */
+        dprintk("Overriding policy max and min with sibling settings\n");
+        policy->min = cp->min;
+        policy->max = cp->max;
+        policy->user_policy.min = cp->user_policy.min;
+        policy->user_policy.max = cp->user_policy.max;
+    }
+
        blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
                                     CPUFREQ_START, policy);
 

RaymanFX

Inactive Recognized Developer
Jan 8, 2011
1,122
16,501
28
Hannover
Ok, I'm on it. Trying my best, but I'm afraid you have to push me a little..

Facing heavy compile errors.
Question :

In your kernel source dir, which command do you use to start compiling ?

EDIT :

EDIT 2 :

@ all people trying to compile, do NOT use

Code:
make tegra_defconfig
!

Better grab an existing .config file from an already running kernel (thanks to guevor for this)
Just google "cyanogenmod building kernel from source" , it's described well over there.
If people request, I can share the kernel config and the precompiled blob tools once I get them from guevor.

First kernel compiled successfull, I have my zImage ready.
OC'd and Voltages changed.
First test kernel incoming the next days, I could need some testers.

Pm me if you want to test. :)
 
Last edited:

Koserman

Senior Member
Apr 6, 2011
259
90
Atlanta
Thanks for this! I love your work and you sharing your vast knowledge of this subject! :) Thanks OP for giving him the means of enlightening us :D
 
1

1chris89

Guest
Say I want to just simply modify my cpu_max_freq via my stock kernel (no source availabel) and I have the boot.img and have unpacked it to boot.img-kernel. What should I do from here to get into the internals of the kernel to adjust the cpu_max_freq? I'm running an ARM Cortex A9, the same as the Tegra2 cpu per say.

Thanks
 

thicklizard

Inactive Recognized Developer
Jul 8, 2011
3,081
5,107
Crown Point
Say I want to just simply modify my cpu_max_freq via my stock kernel (no source availabel) and I have the boot.img and have unpacked it to boot.img-kernel. What should I do from here to get into the internals of the kernel to adjust the cpu_max_freq? I'm running an ARM Cortex A9, the same as the Tegra2 cpu per say.

Thanks

You can't do it that way. You can try to create oc modules but I couldn't tell you how to do that

Sent from my EVO using Tapatalk 2
 

_that

Recognized Developer / Inactive RC
Oct 2, 2012
4,821
4,211
  • Like
Reactions: MCT_

Feche

Senior Member
Oct 5, 2012
611
288
Buenos Aires
I don't understand this part:

The values ​​of interest are the frequency of input and output that indicates the input frequency base to be used and what frequency we want to set (it will use the frequency corresponding to the current base and the output frequency we want). m * p values ​​give us the divisor and n is the multiplier. For simplicity we say that n/(m*p) will give us the multiplier, which applied to the base frequency will give the target frequency.

So if we want to add new frequencies, we must add entries in this structure (tegra_pll_x_freq_table) so the system knows how to program a frequency we want to use.
Add 4 entries for each frequency we want to add (one for each base frequency: 12000000,13000000,19200000,26000000 in our case), with multipliers/dividers to calculate the frequency for which we are adding.

I want to add new frequencies but I don't get it.. also, why 4 entries for a single frequency? thanks!
 
Last edited:

Siegharf

Member
Nov 10, 2015
24
3
Caloocan City
xdaforums.com
I hope there's a video tutorial for "adding overclocking features to your kernel", I hate to admit that I can't follow the instructions carefully due to lack of English knowledge
 
Last edited:

Top Liked Posts

  • There are no posts matching your filters.
  • 36
    Overclocking

    I must say that all I'm going to write, is what I've gathered looking at the code and changes made by others (thanks Blades and Roach2010) (I have not had any documentation about it), so I could make mistakes or misinterpretation.
    Nor do I explain everything, because if you do not have a minimal knowledge get to play this directly may be dangerous:eek:.

    (Q1) Overclocking
    Files to modify

    • arch/arm/mach-tegra/tegra2_clocks.c (All matters relating to the frequencies.)
    The system uses a series of programmed pll clocks which in turn can be used as a basis to other clocks. Let's say for this case pll_x is used for the base of processor clock.
    The frequency table are in tegra_pll_x_freq_table processor. Seeing the type definition clk_pll_freq_table in clock.h we know that has entries consisting of 6 values​​. (input_rate, output_rate, n, m, p, cpcon)
    These values ​​allow tegra2_pll_clk_set_rate function to set the pll frequency.
    The values ​​of interest are the frequency of input and output that indicates the input frequency base to be used and what frequency we want to set (it will use the frequency corresponding to the current base and the output frequency we want). m * p values ​​give us the divisor and n is the multiplier. For simplicity we say that n/(m*p) will give us the multiplier, which applied to the base frequency will give the target frequency.

    So if we want to add new frequencies, we must add entries in this structure (tegra_pll_x_freq_table) so the system knows how to program a frequency we want to use.
    Add 4 entries for each frequency we want to add (one for each base frequency: 12000000,13000000,19200000,26000000 in our case), with multipliers/dividers to calculate the frequency for which we are adding.

    If we add higher frequencies than at present, we have to change the maximum (max_rate) in the tegra_clk_virtual_cpu and tegra_clk_cclk structures, otherwise the system will ignore it. Also have to change the limits for our type of processor in sku_limits. For this case the cpu, cclk y pll_x in the values ​​for our processor (0x04, 0x08, 0x0F).

    Finally we modify the table of frequencies used by the processor (frequency list and their order). Is defined at cpufreq_tables and contains a list of lists where we can add a new list or not to touch anything and modify an existing list.
    We can look at the existing list freq_table_1p2GHz or in my source I added the list freq_table_1p7GHz.
    Contains a list of frequencies that the system can select. It uses the list whose maximum corresponds to the maximum indicated above.

    • arch/arm/mach-tegra/tegra2_dvfs.c (Everything related to the voltages and its relationship with the frequencies.)
    This part is much more sensitive and therefore can affect much to the duration of the battery as to stability. I have no formula (unfortunately for me) on how to modify the values, so the task has been more trial and error.
    The first thing to know is that one must distinguish between the core voltage and the cpu and should be the latter inferior to the first. In tegra2_dvfs_rel_vdd_cpu_vdd_core function establishes the relationship between the two, being the default 120mV core above the cpu.
    Basically what we do if we have added frequencies higher than normal, is to increase the voltage so that they are stable (depend on each processor). I recommend (at first) increment in the same extent all the values ​​involved (maximum voltage).

    Therefore we can modify:

    • Table core_millivolts, establishing the voltages that core can use.

    • Table cpu_millivolts, establishing the voltages that cpu can use. It contains all the steps and should take into account the difference with the core discussed earlier. If we added any frequency, we add the corresponding voltages.

    • Tables core_speedo_nominal_millivolts and cpu_speedo_nominal_millivolts contain a nominal voltage of both the core and the cpu.

    • The maximum and nominal voltages in structures tegra2_dvfs_rail_vdd_cpu, tegra2_dvfs_rail_vdd_core and tegra2_dvfs_rail_vdd_aon.

    • Finally we adjust the settings for dvfs_init ("cpu", 1,) according to the list of frequencies we want to use (adding if we added new frequencies or changing them if changed change some)
    With these changes we should be able to overclock, although we know that although you can configure (once started) a maximum frequency below the maximum that we put on the tables, there is a problem and many times after suspending the system will use the maximum frequency of the table. To avoid this we must make some changes in cpufreq.c

    • drivers/cpufreq/cpufreq.c
    The problem occurs in the second core when reconnected after being disconnected in the suspension process. The problem is solved with the next patch.

    Code:
    diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
    index e157205..2626e2d 100644
    --- a/drivers/cpufreq/cpufreq.c
    +++ b/drivers/cpufreq/cpufreq.c
    @@ -1048,18 +1048,27 @@ static int cpufreq_add_dev(struct sys_device *sys_dev)
     
            /* Set governor before ->init, so that driver could check it */
     #ifdef CONFIG_HOTPLUG_CPU
    +       struct cpufreq_policy *cp;
            for_each_online_cpu(sibling) {
    -               struct cpufreq_policy *cp = per_cpu(cpufreq_cpu_data, sibling);
    +               cp = per_cpu(cpufreq_cpu_data, sibling);
                    if (cp && cp->governor &&
    -                   (cpumask_test_cpu(cpu, cp->related_cpus))) {
    +                       (cpumask_test_cpu(cpu, cp->related_cpus))) {
    +                       dprintk("found sibling CPU, copying policy\n");
                            policy->governor = cp->governor;
    +                       policy->min = cp->min;
    +                       policy->max = cp->max;
    +                       policy->user_policy.min = cp->user_policy.min;
    +                       policy->user_policy.max = cp->user_policy.max;
                            found = 1;
                            break;
                    }
            }
     #endif
            if (!found)
    +       {
    +               dprintk("failed to find sibling CPU, falling back to defaults\n");
                    policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
    +       }
            /* call driver. From then on the cpufreq must be able
             * to accept all calls to ->verify and ->setpolicy for this CPU
             */
    @@ -1071,6 +1080,16 @@ static int cpufreq_add_dev(struct sys_device *sys_dev)
            policy->user_policy.min = policy->min;
            policy->user_policy.max = policy->max;
     
    +    if (found)
    +        {
    +        /* Calling the driver can overwrite policy frequencies again */
    +        dprintk("Overriding policy max and min with sibling settings\n");
    +        policy->min = cp->min;
    +        policy->max = cp->max;
    +        policy->user_policy.min = cp->user_policy.min;
    +        policy->user_policy.max = cp->user_policy.max;
    +    }
    +
            blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
                                         CPUFREQ_START, policy);
    17
    As I cannot find any related guide while google-ing, I want to post this question on here for the purpose of learning and probably helping other people.

    [Q1] How to overclock a kernel

    • which files are needed -> kernel source .. ?
    • what files need to be edited ?
    • is the cpufreq driver related ?
    • how to determine which frequencies need higher voltage and how high exactly ?

    [Q2] Undervolting

    • which files are needed -> kernel source .. ?
    • what files need to be edited ?
    • is the cpufreq driver related ?
    • how to determine which frequencies can use lowered voltage and how to calculate them ?



    I would be very thankful if any developer could teach me (probably others too) and I will contribute back for sure.
    I am right now fixing up bugs in TeamGummy rom, and I'm nearly finished.
    Only thing I lack is a custom kernel, which I want to build myself along with the rom.

    *push*

    Watch out guys, master guevor is going to teach us a little of his enormous knowlegde, so better keep your eyes on this one.

    :)
    5
    Ok, I'm on it. Trying my best, but I'm afraid you have to push me a little..

    Facing heavy compile errors.
    Question :

    In your kernel source dir, which command do you use to start compiling ?

    EDIT :

    EDIT 2 :

    @ all people trying to compile, do NOT use

    Code:
    make tegra_defconfig
    !

    Better grab an existing .config file from an already running kernel (thanks to guevor for this)
    Just google "cyanogenmod building kernel from source" , it's described well over there.
    If people request, I can share the kernel config and the precompiled blob tools once I get them from guevor.

    First kernel compiled successfull, I have my zImage ready.
    OC'd and Voltages changed.
    First test kernel incoming the next days, I could need some testers.

    Pm me if you want to test. :)
    1
    Say I want to just simply modify my cpu_max_freq via my stock kernel (no source availabel) and I have the boot.img and have unpacked it to boot.img-kernel.

    Since the kernel is under GPL, get the sources from where you got the binary.

    I'm running an ARM Cortex A9, the same as the Tegra2 cpu per say.

    Is it a Tegra 2 or not? If not, this thread won't help you.