Overclocking a MK808B plus (Amlogic S805) to run LAKKA.

Hello blog. It was many years sins I made a post on this blog, but I guess now its the time again.

I bought a MK808B plus with thserveimagee Amlogic S805 chip onboard a while ago, I really like this SOC. Its efficient and quite powerful for its size.

Sins my sister requested a NES Classic Mini for the kids for Christmas, I thought that it was better to create a Emulator-console instead. And I think that they have a hard time to appreciate a 8 bit console now days 😛

Sins they already got a MK808B plus with android ( Yes I installed it a year a go so they could stream Youtube and watch movies with Kodi) I saw the perfect plan to pimp this computer a little bit.

I noticed that this computer has support for LAKKA. A lightwight Distro with Retroarch on top. And it worked out great. Check it out here:  http://www.lakka.tv/lakka-retrogaming-linux

I bought a couple of cheap china ps3 wireless gamepads on ebay witch had support in the distro.

I took a while until I figured out Retroarch worked. The first thing was that I could not add my games to the library. Seems like they where not from the correct release. Looking at the retroarch page, they refer to support the No-Intro releases, and after some googling I found a torrent with all the No-Intro releases packed into a big bundle.

I also wanted the boxcovers for the games. I manually installed them in the thumbnails folder because I had some problem to download this directly in retroarch. It was just to extract them in the folder with the correct name. you find them here.

 

Said and done. Everything seems to work out quite well. Snes, Nes, SegaMS and Sega IMG_20181225_104148Genesis. and even PS1 seems to work. But I didn’t got the N64 to work, which was my main console that I wanted to work. Mainly because they have many games for kids, likplaying, seems to work okay for about 5 minutes and after that it was thermal throttling. The day before Christmas I bought a 50mm fan  and solder it to a USB cable. It was working. The SOC did not throttle anymore and the N64 games worked out, a bit laggy thought with some slowdowns running Mario Kart.

The Kids loved the christmas gift, and we where playing Mario Kart the whole evening, and they did not care about the slowdowns. But I did. 🙂

So long story short. I wanted to overclock this SOC and see if I could get a more smooth gameplay in the N64 console. I thought it was wierd that it was thermal throttling because its not hot at all. All my other SOM computers have been much warmer.

Said and done. At first I cloned the src from github.

git clone https://github.com/libretro/Lakka-LibreELEC

And after that run the magical make command.

PROJECT=S805 SYSTEM=MK808B-Plus ARCH=arm make image -j4

The Lakka/LibreELEC should have super cred for the amazing build scripts. Every thing worked out without any breaks which often happens in big project like this. 🙂

6 hours later the build-process was complete and we got a nice image to deploy to the target. It worked out perfect. Now was the time to experiment and see if we could get some more performance out of the Amlogic SOC.

After some researching i found out 4 files that I had to modify to overclock the S805 in the Linux kernel.

/arch/arm/boot/dts/amlogic/meson8b_mk808bplus.dtd

The device tree file contains all board specific data. Here I found the voltage regulation depending on which frequency we are using. I needed to bump the voltage a little bit to get it stable… by writing 1f instead of 1c, I get 1,17 volt instead of 1,14v. This made the trick.

	0x050017        1090000
	0x040018        1100000
	0x030019        1110000			
	0x02001a        1120000			
	0x01001b        1130000
	0x00001f        1140000

Thermal throttling values are also at this file. Before it was thermal throttling @ 70C, Sins we are going to push it, it will get warmer. So I set the the thermal barrier @ 85C.

	thermal{
		compatible = "amlogic-thermal";
		#thermal-cells=<7>;
		dev_name = "aml_thermal";
        trip_point=<85 1488001 1488001 511 511 3 2 87 1200001 1200001 435 435 2 2 90 800001 800001 328 328 1 1 260 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff>;

Next file we had to edit is the arch/arm/mach-meson8b/clock.c

This file holds the PLL table so we get corresponding clock values. Here we change the max frequency limit 2088Mhz.

#define CPU_FREQ_LIMIT 2088000000

Perfect, next up is to edit the frequency scaling table. We find it here: /arch/arm/mach-meson8b/include/mach/cpufreq_table.h

Here I edited the cpufreq_frequency_table meson_freq_table so it matches the overclock I wanted.

static struct cpufreq_frequency_table meson_freq_table_fix_syspll[]=
{
    {0	,   96000   },
    {1	,  192000   },
    {2  ,  384000   },
    {3  ,  768000   },
#if 1
    {4  , 1250000   },
    {5  , 1536000   },
    {6  , 1632000   },
    {7  , 1728000   },
    {8	, 1824000   },
    {9	, 1920000   },
    {10	, 2016000   },
    {11	, 2088000   },
    {12	, CPUFREQ_TABLE_END},
#else
    {4  , 2088000   },
    {5	, CPUFREQ_TABLE_END},
...

I tried several different frequencies, but ended up running the CPU @ 2088Mhz, Pretty nice overclock if you ask me, from 1536 which was the original clock.

At last I managed to overclock the Mali GPU by editing platform_m8b.c adding support for 850Mhz mode.
@ /drivers/amlogic/gpu/mali/platform/meson_m450

struct mali_gpu_clk_item  meson_gpu_clk[]  = {
    {255,  1150},   /* 182.1 Mhz, 1150mV */
    {364,  1150},   /* 318.7 Mhz */
    {425,  1150},   /* 425 Mhz */
    {510,  1150},   /* 510 Mhz */
    {637,  1150},   /* 637.5 Mhz */
    {850,  1250},   /* 850 Mhz */

I created a script so I could monitor the frequency and the temperature.

Lakka:~ # ./monitor.sh 
Sun Jan  6 14:19:08 UTC 2019
cpu_freq: 2088000
cpu temp: 72000
gpu_freq: 637
Sun Jan  6 14:19:09 UTC 2019
cpu_freq: 2088000
cpu temp: 72000
gpu_freq: 637
Sun Jan  6 14:19:10 UTC 2019
cpu_freq: 2088000
cpu temp: 72000
gpu_freq: 637

And the script:

#!/bin/sh
while [ 1 ]; do 
date
echo "cpu_freq: `cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq`"
echo "cpu temp: `cat /sys/class/thermal/thermal_zone0/temp`"
echo "gpu_freq: `cat /sys/class/mpgpu/cur_freq`" 
sleep 1
done

After some tuning, It worked out perfectly. Mario Kart are now runnning smooth. Without slow-downs, and Super Mario 64 also works great. So the overclock made a big difference here. With the fan 50mm fan connected to 5v its running @ max 75C, stable.

If you want to try the modded kernel you can download it here including the modified source-code. Just replace your current kernel.img and kernel.img.md5 on your lakka partition. Disclamer: Your device will overheat if you dont use a fan.

Take care friends. Hope my overclock comes in handy. 😉

Simple fix if the wandboard fails do detect the hdmi-resolution (edid)

I had a problem that the wandboard did not recognize the resolution of my Sony 1600×1200 TFT display.
This issue seems to be on all screens I’ve tested when I used a HDMI-DVI converter.

By editing the file /etc/X11/xorg.conf you can set the resolution manually.
At the bottom of the file, you got a section thats called “Screen”

Change this to somthing like this, and change “Modes” to the resolution of your screen.

Section "Screen"
        Identifier      "Default Screen"
        Device          "Configured Monitor"
        Monitor         "i.MX Accelerated Framebuffer Device"
        DefaultDepth    24
        DefaultFbBpp    32
        SubSection "Display"
                  Modes "1600x1200"
         EndSubSection
EndSection

Just a tip, Hope it can come in handy 🙂
Take care & thanks for passing by…

How to overclock the Wandboard cpu (Freescale i.mx.6)

Hello every-one!
The blog has been pretty passive, time to change it with a new overclocking tutorial.
This time I have a Wandboard in my hand. Wand board is a really nice opensource ARM cortex A9 SOM development board, with a i.mx 6 SOC and 1 GB RAM. My version is equipped with a duallite module @ 1000Mhz.

Somthing that I really like is overclocking and pushing the barriers, so here is how you do it!
This soc has speed fuses that tells the kernel which clock frequency the cpu shall have. It is possible change this fuses, but this is inverversible, so we do it by modifying the kernel instead.
By looking into /arch/arm/mach-mx6/cpu_op-mx6 in the kernel, we find the frequency-tables. at the bottom we find the function: void mx6_cpu_op_init(void)

By removing the check of the fuse bit and manually set the freqency we are on our way.
Make it look somthing like this:

void mx6_cpu_op_init(void)
{
        arm_max_freq = CPU_AT_1_2GHz;
        printk(KERN_INFO "arm_max_freq=%sn", (arm_max_freq == CPU_AT_1_2GHz) ?
                "1.2GHz" : ((arm_max_freq == CPU_AT_1GHz) ? "1GHz" : "800MHz"));
        get_cpu_op = mx6_get_cpu_op;
        set_num_cpu_op = mx6_set_num_cpu_op;
        get_dvfs_core_op = mx6_get_dvfs_core_table;
}

For now I had some instability issues. It seemed that the powersupply and LDO-voltage was dropping too much so I had to turn the LDO off. By turning this of it made some different in temperature thought, about 2-3 degrees warmer.

In the same folder you have the file mx6_anatop_regulator.c. This file holds the LDO-regulator functions and the one we want to disable is the set_voltage() function.
So by making this function empty, the set_voltage() does not change the voltage.
Make it look somthing like this:

static int set_voltage(struct anatop_regulator *sreg, int uv)
{   
     return 0;
}

Then make the new kernel and dd it to the flashmemory, be careful which disk you are writing too.

sudo make CROSS_COMPILE="arm-linux-gnueabi-" ARCH="arm" -j4 uImage
sudo dd if=arch/arm/boot/uImage of=/dev/DISK bs=1M seek=1
sync

Okay, we are almost there. Now the voltages are too low at default values from u-boot. This will not work. We have to turn the voltage to the maximum by disabling the voltage-regulation. We do this by set the Digital Regulator Core Register (PMU_REG_CORE).
You find this register documented in the reference manual at page 4493-4495.

By setting the REG0_TARG REG1_TARG REG2_TARG to 11111 == Power FET switched full on. No regulation.
We do this by modifying the u-boot/board/wandboard/wandboard.c
Make it look somthing like this.

int board_init(void)
{
    /* address of boot parameters */
    gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
 
    int reg;
    reg = 0x7C3E1F;     
    writel(reg, ANATOP_BASE_ADDR + HW_ANADIG_REG_CORE);
 
    return 0;
}

I had some problem with the bootlogo locking up my system in the beginning, so I disabled this by editing u-boot/include/configs/wandboard.h
and commented out the code below.

/* Framebuffer and LCD */
/*#define CONFIG_CMD_HDMIDETECT
#define CONFIG_VIDEO
#define CONFIG_VIDEO_IPUV3
#define CONFIG_CFB_CONSOLE
#define CONFIG_VGA_AS_SINGLE_DEVICE
#define CONFIG_SYS_CONSOLE_IS_IN_ENV
#define CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE
#define CONFIG_VIDEO_BMP_RLE8
#define CONFIG_BMP_24BPP
#if defined(CONFIG_BMP_24BPP) 
#define CONFIG_BPP_BYTES 4
#elif defined(CONFIG_BMP_8BPP)
#define CONFIG_BPP_BYTES 1
#endif 
#define CONFIG_VIDEO_XRES 720
#define CONFIG_VIDEO_YRES 480
#define CONFIG_SYS_VIDEO_LOGO_MAX_SIZE         (CONFIG_VIDEO_XRES * CONFIG_VIDEO_YRES * CONFIG_BPP_BYTES + 1024+ 100)
#define CONFIG_VIDEO_BMP_GZIP
#define CONFIG_SPLASH_SCREEN
#define CONFIG_SPLASH_IS_IN_MMC
#define CONFIG_CMD_BMP
#define CONFIG_VIDEO_LOGO
#define CONFIG_IPUV3_CLK 260000000
#define CONFIG_SYS_DCACHE_OFF
*/

Now compile the bootloader:

sudo make CROSS_COMPILE="arm-linux-gnueabi-" ARCH="arm" wandboard_dl -j4
sudo dd if=u-boot.imx of=/dev/sdc bs=1k seek=1

Pooowoowooww! So now we are there. I was able to boot it stable at 1200Mhz. Whoho! 🙂

Here we have some benchmark results:

Wandboard@1000Mhz


RAM size:     834 MB,  # CPU hardware threads:   2
RAM usage:    425 MB,  # Benchmark threads:      2
 
Dict        Compressing          |        Decompressing
      Speed Usage    R/U Rating  |    Speed Usage    R/U Rating
       KB/s     %   MIPS   MIPS  |     KB/s     %   MIPS   MIPS
 
22:     564   141    389    548  |    12812   200    578   1156
23:     560   143    398    570  |    12698   200    582   1162

Wandboard@1200Mhz

RAM size:     834 MB,  # CPU hardware threads:   2
RAM usage:    425 MB,  # Benchmark threads:      2
 
Dict        Compressing          |        Decompressing
      Speed Usage    R/U Rating  |    Speed Usage    R/U Rating
       KB/s     %   MIPS   MIPS  |     KB/s     %   MIPS   MIPS
 
22:     819   147    543    797  |    19548   200    883   1765
23:     829   150    561    845  |    19365   200    887   1773

You find the kernel-source at http://www.wandboard.org
And the reference manual at Freescales website

Remember that you do this at your own risk. I cant guarantee that it wont damage anything.

Enjoy, feel free to ask questions and comments… and remember to have fun 😀
Peace!

How to overclock the Beaglebone MPU

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

How to make LED-display driver – Beaglebone

I have been playing around with the beaglebone for a while, and the latest project was to make a driver for my 7SEG-LED display using the GPIO ports.
I’m trying to learn more about kernel programming so i made a kernel-module for this task. Its also possible to make a driver like this in userspace, using exported variables in sysfs.

So at first I tried to figure out how to manage the mux configuration from the kernel. Sins the functions in mux.h is’nt exported, i wrote my own routine to set the mux-registers. The function uses the pin_mux structure and set the mux-registers to mux-mode 7 (GPIO).

static int setup_pin_mux(void)
{
	void* adress;
	int i;
	if (request_mem_region(AM33XX_CONTROL_PADCONF_MUX_PBASE, AM33XX_CONTROL_PADCONF_MUX_SIZE,"MuxMem") == NULL)
			printk("Error requesting mem reqion MUX_PBASE\n");

	adress = (void *)ioremap (AM33XX_CONTROL_PADCONF_MUX_PBASE,AM33XX_CONTROL_PADCONF_MUX_SIZE);

	if (adress == NULL)
	{
		printk("Error ioremap: MUX_PBASE\n");
		return -1;
	}

	for (i = 0; pin_mux[i].reg_offset != OMAP_MUX_TERMINATOR; i++)
			iowrite16(pin_mux[i].value, adress+pin_mux[i].reg_offset);

	iounmap(adress);
	release_mem_region(AM33XX_CONTROL_PADCONF_MUX_PBASE,AM33XX_CONTROL_PADCONF_MUX_SIZE);

	return 0;
}

Im using the GPIO ports at the P8 Expansion header. The LEDs are configurated as follow:

  • 3 LED1_1 – GPIO1_6
  • 4 LED1_2 – GPIO1_7
  • 5 LED1_3 – GPIO1_2
  • 6 LED1_4 – GPIO1_3
  • 7 LED1_5 – GPIO2_2
  • 8 LED1_6 – GPIO2_3
  • 9 LED1_7 – GPIO2_5
  • 10 LED1_8 – GPIO2_4
  • 11 LED2_1 – GPIO1_13
  • 12 LED2_2 – GPIO1_12
  • 13 LED2_3 – GPIO0_23
  • 14 LED2_4 – GPIO0_26
  • 15 LED2_5 – GPIO1_15
  • 16 LED2_6 – GPIO1_14
  • 17 LED2_7 – GPIO0_27
  • 18 LED2_8 – GPIO2_1
  • 19 LED1_SWITCH – GPIO0_22 (anode)
  • 20 LED2_SWITCH – GPIO1_31 (anode)

At the LED-display anode, ive put resistors at 480 Ohm, to get safe currents cause maximum output current is 8mA and input 6mA, according to  Gerald Coley. To calculate the resistor of the circuit you can use the formula: voltage – LED-voltage / LED-current.

The function display_number() sets the ledmask according to each number. So for example to display number 2, we set LED 1,2,4,5,7 to zero and LED1_SWITCH to 1.

You can display numbers by using the char-device. Either by writing ioctl command:  ioctl(fd,DISPLAY_SET, &output) or by writing directly to the char-device like “echo 20 > /dev/LED_display”

Right now im using the display to show the CPU-usage and it works great 🙂

To install the driver you run the load-script LED_display_load, and remove with LED_display_unload.

Get the source-code @ gitub.org

Feel free to ask questions and make comments!

Heatsink arrived to MK802

I bought a MK802 for a couple of weeks ago. It’s a really cool ARM-device that runs Linux. I’ve been running a Lubuntu-distro for a while and it works pretty decent. Of course I miss the hardware acceleration in X, and really holding my thumbs for the Limaproject.
Anyway. The allwinner A10 chip gets really hot! Compared to the TI-AM3359 overclocked to 920Mhz, it is still MUCH warmer. So to spread the heat i got a small heatsinks from Conrad.

The heatsink did the job, so now i’m not worried about heating issues anymore. Over and out!

The recipe for a silent, powerful and small computer

Last year, I got really tired of loud hard-drives and noisy fans. I decided to build a passively cooled computer (without fans :). I wanted it to be high-performance, small, energy efficient and completely silent.

This became the recipe:
Case: Morex T3500 (80W PS)

HDD: Intel 160GB G2 SSD

MEM: Corsair XMS3 8GB DDR3 PC10666 1333MHz

MOBO: MSI H61I-E35

CPU: Intel Core i3-2100

CPU Cooler: Thermal Right HR-2 Macho

PCH Cooler: Thermal Right HR-05 SLI/IFX

I got big heatsinks and a case with a external passive 80W powersupply. My thought was in the beginning to under-clock the Core-i3 to match the 2100T == 35W TDP, but sins it worked out pretty nice at the orginal frequency(3.1Ghz) I didn’t had too. A little bit of Ghetto-mod about this project, but I really wanted the heatsinks to be outside of the case for maximum cooling and performance. So had to modify it a littlebit 🙂

So whats the temperature?

It becomes pretty hot at full-load, but still good temperatures thought.
36C idle,
65C in usual full load. But with some prime-benchmarking-software ive got CPU temp over 70C. In normal condition, at normal usage, like running some virtual-machines, browsing the web, coding and such, the CPU never gets over 50 degrees.

This computer have been a Linux Server/Desktop computer for almost a year now, and I never had any stability or heating issues. But the project became a little bit more expensive thought.. cause when my computer became silent I noticed that my monitor had a nasty beeping sound, hehe.. so I had to replace it 🙂

I got a article about my project at sweclockers.com and fanlesstech.com