Mali

Overview
Mali400 is a GPU from ARM. More information can be found on the ARM website.

Mali 400 on A1x
Allwinner officially supports the Mali GPU driver on the Android platform only. In this article we cover native linux usage, for android refer to publicly available sources https://github.com/allwinnerwk https://github.com/allwinner-ics and many others.

Binary libraries download links
Mali-400 uses proprietary libraries that must be provided by SoC manufacturer. This libraries are built with Mali DDK in various variants defining supported APIs. Example: if VARIANT is mali400-vg-gles20-linux-ump, library will be built with support for OpenGL ES 2 and OpenVG.

Libraries depend on driver version, for each Mali-400 kernel module drivers update you need appropriate libraries version and appropriate X11/DRI2 drivers version. If this conditions will not be met, you will end with unsupported IOCTL's and basically unstable system.

Open-source Mali driver
There is a project to develop a completely open-source Mali driver (work in progress): http://limadriver.org/

Manual installation and details
This section will describe how to install and use official Mali-400 drivers from ARM. If you feel that manual installation is hard for you, see automated one below. First, you need working distro with installed xorg and wip/linux-sunxi-3.0/next_mali kernel, in this tutorial, I'm using linaro-alip 12.08 with LXDE. Second, you need to install development stuff: root@linaro-alip:~# apt-get install autoconf automake make libtool xorg-dev xutils-dev libdrm-dev Pay close attention to last two, without them compilation will likely fail with various headers missing. Now download Mali-400 drivers and UMP from ARM's site, I'm using mali400 directory in my root home folder for this, then unpack archives. cd mali400 wget http://www.malideveloper.com/files/DX910-SW-99003-r3p0-04rel0.tgz wget http://www.malideveloper.com/files/DX910-SW-99006-r3p0-04rel0.tgz tar zxvf DX910-SW-99003-r3p0-04rel0.tgz tar zxvf DX910-SW-99006-r3p0-04rel0.tgz Now go to UMP directory cd DX910-SW-99006-r3p0-04rel0/driver/src/ump By default UMP is configured to be cross-compiled, so we need to disable this: replace CROSS_COMPILE ?= arm-none-linux-gnueabi- with CROSS_COMPILE ?= in Makefile using your favourite editor. Now, because we have hardfloat armv7-a toolchain, edit CFLAGS string like this: - CFLAGS += -I$(UMP_DIR)/include -I$(UMP_DIR)/include/ump -Wall -march=armv6 -mthumb-interwork -fno-strict-aliasing -Wno-strict-aliasing -Wno-long-long -O3 + CFLAGS += -I$(UMP_DIR)/include -I$(UMP_DIR)/include/ump -Wall -march=armv7-a -mthumb-interwork -fno-strict-aliasing -fPIC -Wno-strict-aliasing -Wno-long-long -O3 Now you will be able to make libUMP using standard make root@linaro-alip:~/mali400/DX910-SW-99006-r3p0-04rel0/driver/src/ump# make gcc -c -o arch_011_udd/ump_frontend.o arch_011_udd/ump_frontend.c -I./include -I./include/ump -Wall -march=armv7-a -mthumb-interwork -fno-strict-aliasing -fPIC -Wno-strict-aliasing -Wno-long-long -O3 gcc -c -o arch_011_udd/ump_ref_drv.o arch_011_udd/ump_ref_drv.c -I./include -I./include/ump -Wall -march=armv7-a -mthumb-interwork -fno-strict-aliasing -fPIC -Wno-strict-aliasing -Wno-long-long -O3 gcc -c -o arch_011_udd/ump_arch.o arch_011_udd/ump_arch.c -I./include -I./include/ump -Wall -march=armv7-a -mthumb-interwork -fno-strict-aliasing -fPIC -Wno-strict-aliasing -Wno-long-long -O3 gcc -c -o os/linux/ump_uku.o os/linux/ump_uku.c -I./include -I./include/ump -Wall -march=armv7-a -mthumb-interwork -fno-strict-aliasing -fPIC -Wno-strict-aliasing -Wno-long-long -O3 gcc -c -o os/linux/ump_osu_memory.o os/linux/ump_osu_memory.c -I./include -I./include/ump -Wall -march=armv7-a -mthumb-interwork -fno-strict-aliasing -fPIC -Wno-strict-aliasing -Wno-long-long -O3 gcc -c -o os/linux/ump_osu_locks.o os/linux/ump_osu_locks.c -I./include -I./include/ump -Wall -march=armv7-a -mthumb-interwork -fno-strict-aliasing -fPIC -Wno-strict-aliasing -Wno-long-long -O3 gcc -shared -o libUMP.so ./arch_011_udd/ump_frontend.o ./arch_011_udd/ump_ref_drv.o ./arch_011_udd/ump_arch.o ./os/linux/ump_uku.o ./os/linux/ump_osu_memory.o ./os/linux/ump_osu_locks.o -I./include -I./include/ump -Wall -march=armv7-a -mthumb-interwork -fno-strict-aliasing -fPIC -Wno-strict-aliasing -Wno-long-long -O3 ar rcs libUMP.a ./arch_011_udd/ump_frontend.o ./arch_011_udd/ump_ref_drv.o ./arch_011_udd/ump_arch.o ./os/linux/ump_uku.o ./os/linux/ump_osu_memory.o ./os/linux/ump_osu_locks.o after lib is compiled copy libUMP.so to your /lib or /usr/lib and copy DX910-SW-99006-r3p0-04rel0/driver/src/ump/include/ump/ contents to /usr/include/ump, without last one Mali-400 X11 drivers compilation will fail. Now go back to directory where you downloaded and unpacked DX910-SW-99003-r3p0-04rel0.tgz. Go to DX910-SW-99003-r3p0-04rel0/x11/xf86-video-mali-0.0.1 and run autoreconf -vi root@linaro-alip:~/mali400# cd DX910-SW-99003-r3p0-04rel0/x11/xf86-video-mali-0.0.1/ root@linaro-alip:~/mali400/DX910-SW-99003-r3p0-04rel0/x11/xf86-video-mali-0.0.1# autoreconf -vi autoreconf: Entering directory `.' autoreconf: configure.ac: not using Gettext autoreconf: running: aclocal autoreconf: configure.ac: tracing autoreconf: running: libtoolize --install --copy libtoolize: putting auxiliary files in AC_CONFIG_AUX_DIR, `.'. libtoolize: copying file `./config.guess' libtoolize: copying file `./config.sub' libtoolize: copying file `./install-sh' libtoolize: copying file `./ltmain.sh' libtoolize: Consider adding `AC_CONFIG_MACRO_DIR([m4])' to configure.ac and libtoolize: rerunning libtoolize, to keep the correct libtool macros in-tree. libtoolize: Consider adding `-I m4' to ACLOCAL_AMFLAGS in Makefile.am. autoreconf: running: /usr/bin/autoconf autoreconf: running: /usr/bin/autoheader autoreconf: running: automake --add-missing --copy --no-force configure.ac:20: installing `./missing' src/Makefile.am: installing `./depcomp' autoreconf: Leaving directory `.' Now run ./configure script to produce makefiles, if you installed development stuff that I've mentioned in first step, you should have configure end without errors. Here is last lines of configure saying that everything is ok ./configure --prefix=/usr --x-includes=/usr/include --x-libraries=/usr/lib <..lots of output> checking whether to build shared libraries... yes checking whether to build static libraries... no checking if RANDR is defined... yes checking if RENDER is defined... yes checking if XV is defined... yes checking for XORG... yes checking whether xf86ConfigIsaEntity is declared... no configure: creating ./config.status config.status: creating Makefile config.status: creating src/Makefile config.status: creating config.h config.status: executing depfiles commands config.status: executing libtool commands Now you can compile driver using make. But wait, what is this? root@linaro-alip:~/mali400/DX910-SW-99003-r3p0-04rel0/x11/xf86-video-mali-0.0.1# make make all-recursive make[1]: Entering directory `/root/mali400/DX910-SW-99003-r3p0-04rel0/x11/xf86-video-mali-0.0.1' Making all in src make[2]: Entering directory `/root/mali400/DX910-SW-99003-r3p0-04rel0/x11/xf86-video-mali-0.0.1/src' CC    mali_dri.lo  CC     mali_exa.lo mali_exa.c:35:54: fatal error: ../../../devicedrv/umplock/umplock_ioctl.h: No such file or directory compilation terminated. make[2]: *** [mali_exa.lo] Error 1 make[2]: Leaving directory `/root/mali400/DX910-SW-99003-r3p0-04rel0/x11/xf86-video-mali-0.0.1/src' make[1]: *** [all-recursive] Error 1 make[1]: Leaving directory `/root/mali400/DX910-SW-99003-r3p0-04rel0/x11/xf86-video-mali-0.0.1' make: *** [all] Error 2 This is multimillion corporation releasing bogus untested sources that you need to fix even if you bought their product, good job ARM. Luckily, fix is really simple, this file is from kernel driver package, I dont know why it is mixed with userspace X11 driver, but you can grab it from http://pastebin.com/SY5hSY1C, of course, you need to fix this include in mali_exa.c to continue building. In src/mali_exa.c - #include "../../../devicedrv/umplock/umplock_ioctl.h" + #include "umplock_ioctl.h" Place umplock_ioctl.h in src/ and now compilation will finally work. root@linaro-alip:~/mali400/DX910-SW-99003-r3p0-04rel0/x11/xf86-video-mali-0.0.1# make make all-recursive make[1]: Entering directory `/root/mali400/DX910-SW-99003-r3p0-04rel0/x11/xf86-video-mali-0.0.1' Making all in src make[2]: Entering directory `/root/mali400/DX910-SW-99003-r3p0-04rel0/x11/xf86-video-mali-0.0.1/src' CC    mali_exa.lo  CC     mali_fbdev.lo  CC     mali_lcd.lo  CCLD   mali_drv.la make[2]: Leaving directory `/root/mali400/DX910-SW-99003-r3p0-04rel0/x11/xf86-video-mali-0.0.1/src' make[2]: Entering directory `/root/mali400/DX910-SW-99003-r3p0-04rel0/x11/xf86-video-mali-0.0.1' make[2]: Leaving directory `/root/mali400/DX910-SW-99003-r3p0-04rel0/x11/xf86-video-mali-0.0.1' make[1]: Leaving directory `/root/mali400/DX910-SW-99003-r3p0-04rel0/x11/xf86-video-mali-0.0.1' Now you can install your driver root@linaro-alip:~/mali400/DX910-SW-99003-r3p0-04rel0/x11/xf86-video-mali-0.0.1# make install Making install in src make[1]: Entering directory `/root/mali400/DX910-SW-99003-r3p0-04rel0/x11/xf86-video-mali-0.0.1/src' make[2]: Entering directory `/root/mali400/DX910-SW-99003-r3p0-04rel0/x11/xf86-video-mali-0.0.1/src' make[2]: Nothing to be done for `install-exec-am'. test -z "/usr/lib/xorg/modules/drivers" || /bin/mkdir -p "/usr/lib/xorg/modules/drivers" /bin/bash ../libtool  --mode=install /usr/bin/install -c   mali_drv.la '/usr/lib/xorg/modules/drivers' libtool: install: /usr/bin/install -c .libs/mali_drv.so /usr/lib/xorg/modules/drivers/mali_drv.so libtool: install: /usr/bin/install -c .libs/mali_drv.lai /usr/lib/xorg/modules/drivers/mali_drv.la libtool: finish: PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/sbin" ldconfig -n /usr/lib/xorg/modules/drivers -- Libraries have been installed in: /usr/lib/xorg/modules/drivers

If you ever happen to want to link against installed libraries in a given directory, LIBDIR, you must either use libtool, and specify the full pathname of the library, or use the `-LLIBDIR' flag during linking and do at least one of the following: - add LIBDIR to the `LD_LIBRARY_PATH' environment variable during execution - add LIBDIR to the `LD_RUN_PATH' environment variable during linking - use the `-Wl,-rpath -Wl,LIBDIR' linker flag - have your system administrator add LIBDIR to `/etc/ld.so.conf'

See any operating system documentation about shared libraries for more information, such as the ld(1) and ld.so(8) manual pages. -- make[2]: Leaving directory `/root/mali400/DX910-SW-99003-r3p0-04rel0/x11/xf86-video-mali-0.0.1/src' make[1]: Leaving directory `/root/mali400/DX910-SW-99003-r3p0-04rel0/x11/xf86-video-mali-0.0.1/src' make[1]: Entering directory `/root/mali400/DX910-SW-99003-r3p0-04rel0/x11/xf86-video-mali-0.0.1' make[2]: Entering directory `/root/mali400/DX910-SW-99003-r3p0-04rel0/x11/xf86-video-mali-0.0.1' make[2]: Nothing to be done for `install-exec-am'. make[2]: Nothing to be done for `install-data-am'. make[2]: Leaving directory `/root/mali400/DX910-SW-99003-r3p0-04rel0/x11/xf86-video-mali-0.0.1' make[1]: Leaving directory `/root/mali400/DX910-SW-99003-r3p0-04rel0/x11/xf86-video-mali-0.0.1' Copy xorg.conf to /usr/share/X11/xorg.conf.d/99-mali400.conf root@linaro-alip:~/mali400/DX910-SW-99003-r3p0-04rel0/x11/xf86-video-mali-0.0.1# cp xorg.conf /usr/share/X11/xorg.conf.d/99-mali400.conf Test your driver restarting lightdm service lightdm restart lightdm stop/waiting lightdm start/running, process 11336 UMP<2>: New session opened To test if Mali-400 driver works, you can cat /var/log/Xorg.0.log, you will have something like this http://pastebin.com/fgTRRgL4 key lines are: [ 3458.637] (II) MALI(0): DRI2 version: 1.2 [ 3458.637] (II) MALI(0): [DRI2] Setup complete [ 3458.638] (II) MALI(0): [DRI2]   DRI driver: Mali DRI2 and [ 3458.773] (EE) AIGLX error: dlopen of /usr/lib/arm-linux-gnueabihf/dri/Mali DRI2_dri.so failed (/usr/lib/arm-linux-gnueabihf/dri/Mali DRI2_dri.so: cannot open shared object file: No such file or directory) [ 3458.773] (EE) AIGLX: reverting to software rendering [ 3458.773] (II) AIGLX: Screen 0 is not DRI capable [ 3458.819] (II) AIGLX: Loaded and initialized swrast [ 3458.819] (II) GLX: Initialized DRISWRAST GL provider for screen 0 AIGLX doesnt work because it is aimed for x86. Now you need to delete Mesa swrast EGL libs and place yours as said in section above. Testers are welcome.

Automated installation
Because stuff above seems to be too hard for people I've created git repo with fixed includes and simple build script that builds drivers, installs them and copies two files: xorg.conf and 10-mali400.rules to xorg.conf.d and udev rules.d accordingly. Please use next_mali branch of kernel or you will get unhandeled IOCTLs in dmesg. Also, delete the mesa-egl from your ldconfig, so libs from Mali400 dont collide with mesa-egl and so on. You need only Mali400 hardware accelerated libs in system, no swrast whatsoever. Please report any bugs found.
 * 1) apt-get install autoconf automake make libtool xorg-dev xutils-dev libdrm-dev git
 * 2) git clone git://github.com/rzk/Mali-400-r3p0-04rel0-X11-drivers.git
 * 3) cd Mali-400-r3p0-04rel0-X11-drivers
 * 4) ./libsdl.sh
 * 5) ./build.sh

VARIANT=mali400-vg-gles20-linux-ump
Any use of libEGL will fail with symbol lookup error: /lib/libGLESv2.so.2: undefined symbol: _vg_image_pbuffer_to_clientbuffer Details: https://github.com/amery/linux-allwinner/issues/69#issuecomment-8594930 Built without X11 support.

VARIANT=mali400-gles11-gles20-linux-ump
Fails with "eglcreatewindow fail". Built without X11 support.

VARIANT=mali400-gles20-gles11-linux-x11-ump-no_monolithic
Needs libdri2 LD_PRELOAD'ed, has same fails as r2p4.

Current state for r2p4
Use of libEGL produces random fails, see http://pastebin.com/GCVHSZJh for details. Most likely we have problems with our UMP integration or library is built wrong.

VARIANT=mali400-gles11-gles20-linux-ump
Untested. Built without X11 support.