PowerVR SGX on the BeagleBone Black in 2019

Since I spent way too much time on figuring this out, confused by plenty of old and outdated online sources, here is how one would get the PowerVR SGX driver running on a current Linux in 2019 - in this case a debian 9.6 with a 4.4 kernel. Other combinations might/should work also, but I have not tested them.

To summarize briefly, the difference to the previous ways of getting the SGX stuff running, is that the old GFX_SDK_* based setups are outdated. This includes omaplfb.ko kernel module based instructions, which also come from the GFX_SDK_* times. Last but not least, it looks like one has to run a TI kernel (updated to with flag --ti-kernel, see below), as the bone kernels (--bone-kernel) don't seem to have the new SGX driver stack.

I used bone-debian-9.6-console-armhf-2018-12-10-2gb.img.xz from RobertCNelson's site at https://rcn-ee.com/rootfs/2018-12-10/microsd/, as I wanted a leaner base system than what's available on https://beagleboard.org/latest-images.

To put it in a nutshell, we need to run a TI kernel, and install the matching SGX DDK, and ideally initialize it on startup. So on your system on the BBB the following should install the TI kernel (v4.4, which worked for me) - the below assumes that the default user debian of the image is used, so some sudo is needed occasionally:

cd /opt/scripts/tools

# install TI kernel, this also installs the matching SGX drivers
git pull                                       # fetch latest revisions of kernels to upgrade to
sudo ./update_kernel.sh --ti-kernel --lts-4_4  # if branch not there anymore, make sure whatever branch is used contains a working pvrsrvkm.ko
sudo reboot

Now the SGX DDK, which we'll build from source:

# some libs for later
sudo apt install -y libdrm-omap1 libgbm1

# get the SGX DDK for userland libraries, demos and tools needed to initialize PowerVR
# NOTE: the branch used below has to match kernel version, change if using different kernel above
cd ~
git clone -b ti-img-sgx/1.14.3699939_k4.4 git://git.ti.com/graphics/omap5-sgx-ddk-um-linux.git --depth=1
cd omap5-sgx-ddk-um-linux/
sudo env DISCIMAGE=/ TARGET_PRODUCT=ti335x make install
cd ~
rm -rf ./omap5-sgx-ddk-um-linux

# hackfix needed missing reference to libgbm.so.2
sudo ln -s /usr/lib/arm-linux-gnueabihf/libgbm.so.1 /usr/lib/arm-linux-gnueabihf/libgbm.so.2

# verify driver loaded - should show pvrsrvkm
lsmod | grep pvr

# verify, there should be some info like "[drm] Initialized" and "PVR_K: UM DDK..." infos
dmesg | grep -i -C1 'drm\|sgx\|pvr'

# set mode SGX should work in - at this point there are three installed, but
# only one that works, as the libpvrws_WAYLAND.so and libpvrGBMWSEGL.so are
# both for DRM/WAYLAND based multi-window systems and weston isn't installed.
# According to the docs there also should be libpvrDRMWSEGL_FRONT.so, a no-vsync
# and thus faster version of libpvrDRMWSEGL.so.
# Other options like pixel format can also be set to RGB565, RGB888 or ARGB8888,
# select the one that works for you (colors might be swapped for 565 or 888, depending
# on LCD wiring, see TI's AM335x silicon errata.
sudo rm /etc/powervr.ini
sudo tee -a /etc/powervr.ini <<EOF

# init powervr for testing, will be automated later, below
sudo /usr/bin/pvrsrvctl --start --no-module

# verify via tools shipped in the omap5-sgx-ddk:
cd /usr/bin   # b/c gles2test1 depending on that pwd for shader files in /usr/bin/
eglinfo       # should spit out a lot of things
gles1test1 x  # shows some spinning triangles on green background (arg is num_frames it should run I guess, non-integer args make it run forever)
gles2test1 x  # similar but on purple backgroun (see above for dummy arg x) - if red background check powervr.ini's pixel format we set above
cd -

# more info about SGX chip if needed
cat /proc/pvr/version

If the above installed fine, and all the test steps in the above block also worked, let's automate the SGX initialization at startup via systemd:

# service script starting PowerVR environment
sudo tee -a /etc/systemd/system/pvr-init.service <<"TTT"
# startup fails sometimes (too early?), retry in loop - this paired with TimeoutStartSec is a
# workaround to oneshot services refusing decent Restart= settings (at least for systemd <= 232)
ExecStart=/bin/sh -c 'while ! /etc/init.d/rc.pvr start; do sleep 5; done'
ExecStop=/etc/init.d/rc.pvr stop

sudo systemctl enable pvr-init

# done
sudo reboot