I was curious if it was possible to overclock the MPU of the beaglebone and, of course it was. 🙂 So here is how I did it. (And be careful, overclocking may damage your beaglebone)
At first i tried to overclock the MPU by manually set the MPU registers. The registers who controls the MPU-freqency is CM_DIV_M2_DPLL_MPU and CM_CLKSEL_DPLL_MPU.
The ADPLLS calculates the MPU clock by following formula:
CLKINP * [1 / (N+1)] * [M] * [1/M2]
CLKINP is the source input-clock, 24.
N is the divider in CM_CLKSEL_DPLL_MPU
M is the multiplier in CM_CLKSEL_DPLL_MPU
M2 is the divider in CM_DIV_M2_DPLL_MPU
Below is the main-function of my program bclock.
int main(int argc, char **argv) { Dpll_mpu* dpll_mpu = malloc(sizeof(Dpll_mpu)); int fd = open("/dev/mem", O_RDWR); int i; if (fd < 0) { perror("Could not open file \n"); return 1; } uint8_t *map; map = mmap(NULL, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, OFFSET); if (map == MAP_FAILED) { perror("mmap failed"); return 1; } get_dpll_mpu(dpll_mpu, map); if (argc == 1) { printf("Usage: %s [OPTION...]\n -N, set N-divider\n -M, set M-multiplier\n \ -M2, set M2-divider\n", argv[0]); get_dpll_mpu(dpll_mpu, map); printf("\nCurrent settnings \n-----------------\n"); print_dpll_mpu(dpll_mpu); printf("\nCalculated by formula CLKINP * [1 / (N+1)] * [M] * [1/M2]\n\n"); } else { for (i = 1; i < argc; i+=2) { if (argc != i+1) { if (strcmp(argv[i],"-N") == 0) if (atoi(argv[i+1]) > 0 && atoi(argv[i+1]) <= 0x7f) dpll_mpu-> N_divider = atoi(argv[i+1]); if (strcmp(argv[i],"-M") == 0) if (atoi(argv[i+1]) > 0 && atoi(argv[i+1]) <= 0x3ff) dpll_mpu-> M_multiplier = atoi(argv[i+1]); if (strcmp(argv[i],"-M2") == 0) if (atoi(argv[i+1]) > 0 && atoi(argv[i+1]) <= 0x1f) dpll_mpu-> M2_divider = atoi(argv[i+1]); } } set_dpll(dpll_mpu,map); get_dpll_mpu(dpll_mpu, map); print_dpll_mpu(dpll_mpu); } munmap(map, SIZE); close(fd); free(dpll_mpu); return 0; }
You can overclock the MPU from userspace by writing to the mapped registers. This is what my software bclock does. Try it out and tell me what you think.
Below is the output when running the program.
./bclock
Usage: ./bclock [OPTION...]
-N, set N-divider
-M, set M-multiplier
-M2, set M2-divider
Current settnings
-----------------
CLKINP = 24
N_divider = 2
M_multiplier = 130
M2_divider = 1
MPU frequency = 1040.00 Mhz
Calculated by formula CLKINP * [1 / (N+1)] * [M] * [1/M2]
If you are using cpu-frequency scaling, cpufreq module will overwrite the settnings generated by bclock. You can disable the frequency scaling by set the minimum frequency to maxfrequency, like,
cpufreq-set -d 720Mhz
You can also change the scaling frequencies by modifying the kernelcode in /arch/arm/mach-omap2/opp3xxx_data.c and change the am33xx_opp_def_list structure to the desired frequencies and recompile the kernel. I bought a small heatsink to spead the heat, and so far ive run my MPU at 1040 Mhz successfully.
So does the overclock make any difference? Yes indeed! 🙂
When I’m running 7-Zip benchmark (7zr b
) I get the following results:
Orginal @ 720Mhz
Dict Compressing | Decompressing Speed Usage R/U Rating | Speed Usage R/U Rating KB/s % MIPS MIPS | KB/s % MIPS MIPS 22: 279 100 272 271 | 5442 100 491 491 23: 272 100 277 277 | 5365 100 491 491 24: 263 100 283 283 | 5286 100 490 490 ---------------------------------------------------------------- Avr: 100 277 277 100 491 491 Tot: 100 384 384
Overclocked @ 1040Mhz
Dict Compressing | Decompressing Speed Usage R/U Rating | Speed Usage R/U Rating KB/s % MIPS MIPS | KB/s % MIPS MIPS 22: 356 100 346 346 | 7578 100 684 684 23: 346 100 353 353 | 7451 100 682 682 24: 334 100 360 359 | 7318 100 679 679 ---------------------------------------------------------------- Avr: 100 353 353 100 682 681 Tot: 100 517 517
Be careful, and happy overclocking 🙂
Get the source-code @ gitub.org
Kernel source: AM335x_04_06 04_06_00_08 kernel
TI AM335x Ref Manual