This tutorial aims at getting you ready to use the LCDs of the extension board in an embedded Linux systems. It assumes that you already have a working embedded Linux configuration and that you have access to the Altera toolchain.
As mentionned in the introduction, you must have a working Linux system on an SD card. You do not need to have built everything from scratch but you need to be able to recompile the kernel sources. Typically, your SD card should at least consist of the following partitions:
The hardware is divided into two components. The frame manager is responsible for accessing the frame buffer in memory. The LCD interface (at the moment, only a VGA interface called VGA sequencer is available) is responsible for transforming the stream of pixels it receive from the frame manager in the correct timing for the LCD. You are responsible for generating the correct VIDEO_CLK depending on your LCD with a PLL from Altera.
The Qsys components can be downloaded here.
Enabling framebuffer support in Linux
As the provided driver is a framebuffer driver, our first goal is to enable the framebuffer support in your kernel. To do this, you must recompile your kernel. Don’t worry: if you have already done it once, it’s going to be fast. For all the following terminal manipulations, be sure to be in a terminal where the global variable ARCH and CROSS_COMPILE have been set to arm and to the prefix of your cross-compiling toolchain (e.g. arm-linux-gnueabihf- if you are using the Embedded command shell from Altera), respectively.
In your terminal, cd wherever your kernel sources are. Then, type the following command:
If you get an error, it might be that you don't have ncurses installed. In (K)Ubuntu, you can use the following command to install it:
The make menuconfig command should open a text-based user interface that lets you configure the kernel build. Then, use the following path:
You should now be able to use the Y key to enable the options as follows:
(You might need to enable the very first to see the other ones appear.)
Then, press the ESC key until you are asked whether you want to save before quitting. Choose to save. Then, it is time to recompile the kernel with the following command:
Your new kernel image can be found in <linux-source-path>/arch/arm/boot/zImage. You need to copy it on the boot partition of your SD card.
Adapting and compiling the device tree
Drivers are board-agnostic. Otherwise, they would need to be rewritten from scratch for each board. Therefore, a compiled structure called the Device Tree is loaded in kernel’s memory by the bootloader. The kernel makes this structure available to its drivers so that they can read their configuration parameters from it. In such a framework, a new board “only” requires a device tree to be written.
One of the first task performed by our framebuffer driver is to read the device tree to determine the configuration of the board and your Qsys design. Some parameters are compulsory, some aren’t. For the driver to work, the following parameters must be defined:
The non-compulsory parameters is the prsoc,reg-init parameter. It defines the initialization sequence of the registers in a key-value fashion where the key is the offset and the value is what should be written to it. The offsets are computed from the address of the LCD interface Avalon‑MM slave port specified above. If this parameter isn’t provided, the LCD interface is left as is.
Differentiating the dimensions of the screen and the one of the buffer can be used to perform ping-pong buffering (sometimes referred to as double buffering or triple buffering depending on the number of buffers). This means that your application can mmap a larger buffer than the screen and can draws in non-visible portion of the screen. For those of you that are already familiar with the userland API exposed by framebuffer, the application can then use a code resembling the following to swap buffers:
You can find a full dummy example of working ping-pong buffering here.
Here is a full example device tree that configures the ER TFT043:
In this example, the IRQ line of the frame manager is wired to FPGA_IRQ0 , the first IRQ slot for FPGA-to-HPS interrupts. This corresponds to the GIC interrupt number 72 which is the 40th (= 72-32) shared peripheral interrupt (SPI). The latter is the rationale behind the 40 appearing in the interrupts property. For more information, see ftp://ftp.altera.com/up/pub/Altera_Material/14.0/Tutorials/Using_GIC.pdf or https://wiki.epfl.ch/prsoc/documents/Cyclone_V_SoC_Linux_Interrupt-2.pdf.
You need to put your DTS file, say mydts.dts, in the <linux-source>/arch/arm/boot/dts folder, then type the command:
This will compile the DTS file and you can put the resulting DTB file on your SD card’s boot partition. The DTB file can be found in the <linux-source>/arch/arm/boot/dts folder and is named mydts.dtb without surprise.
Compiling and installing the framebuffer
The framebuffer sources can be downloaded here.
In your terminal, cd wherever the framebuffer sources are on your machine. Then, edit the Makefile by setting the KERNEL_PATH variable to wherever your kernel sources are on your machine. Then, issue a make command. The binary you need to put on your root filesystem partition is the one ending with the “ko” extension.
You can then load it on the target after boot using:
If the device tree is correct, the driver should properly load. Otherwise, a meaningful error message should indicate what's missing.
 The compatible string is the driver identifier of a device tree node, i.e. a driver specifies the compatible strings for which it must be loaded. Therefore, if you do not specify it, our framebuffer driver won’t be loaded.