Collabora contributions to Linux kernel 4.1

Linux 4.1 was released last week and like previous kernel releases, this version again contains contributions made by Collabora engineers as a part of our current projects.

On this release, not only Collabora contributed several patches for different subsystems but also for the first time made it to LWN list of most active employers for a Linux kernel release and Tomeu Vizoso was listed as one of the most active developers by changed lines.

In total 68 patches were contributed to the 4.1 release. These were for:

  • Fixes and improvements to the DRM core atomic support.
  • Fix for Exynos DRM FIMD buffer size calculation.
  • More cleanup and fixes for Exynos DRM in preparation to finish porting the driver to support Atomic Mode Settings for v4.2
  • Add MMC/SDIO power sequencing to make the WiFi chip work on Snow and Peach Pit/Pi Chromebooks.
  • Various fixes and improvement for the ChromeOS Embeded Controller drivers.
  • Add default console serial port configuration for Exynos Chromebooks to avoid having to define a tty in the kernel command line.
  • Enable needed drivers in the Exynos default configuration file.
  • Fix error code propagation in the MMC power sequencing core.
  • Restore clocks needed during suspend for Exynos5 machines to prevent failing to resume.
  • Make the Mwifiex chip on Exynos Chromebooks to keep power during suspend to prevent the driver not allow the system to enter into a suspend state.
  • Fix output disable race on the Samsung PWM driver.
  • Split out touchpad initialisation logic on the Atmel MaxTouch driver.
  • Various enhancements for the Tegra ASoC driver.
  • Add a Device Tree to support the Nyan Blaze Chromebook and factor out common snippets with the Nyan Big Chromebook Device Tree.
  • Add trackpad, WiFi and GPIO restart support for the Nyan Chromebooks.
  • Add support for the Tegra124 Activity Monitor (ACTMON).
  • Fill EMC timings for Tegra Nyan Chromebooks.
  • Many fixes and improvements for the Tegra device frequency scaling driver.
  • Fix the Tegra DRM driver by resetting the SOR to a known state.
  • Enable many drivers in multi_v7 default configuration, that are needed by Tegra Chromebooks.
  • Fix the cros_ec keyboard driver to avoid loosing the key pressed during suspend to resume the system.
  • Fix USB not working on Tegra124 based boards.

Following is the complete list of patches merged in this kernel release:

Collabora contributions to Linux kernel 4.0

Linux 4.0 was released a couple of weeks ago and like previous kernel releases, this version again contains contributions made by Collabora engineers as a part of our current projects.

In total 59 patches were contributed to the 4.0 release. These were for:

  • Fix graphics DP and HDMI display for Exynos DRM.
  • More preparation work to add Atomic Mode Settings support to the Exynos DRM driver.
  • Add support for Power, Lid keys and built-in USB camera to Peach Pi/Pit and Snow Chromebooks.
  • Configure regulators operating modes on suspend for Peach Pi/Pit Chromebooks to reduce power consumption.
  • Add DISP1 power domain and related clocks to have proper display support on Exynos5420 machines.
  • Extend the MMC simple power sequencing provider to support a reference clock and more than one reset GPIO.
  • Fix various regressions in the common clock framework exposed by the per-user clock changes.
  • Fix S3C Real-Time-Clock that was not working on many Exynos SoCs.
  • Fix a bug in the regulator framework that tried to enable regulators that were already enabled.
  • Fix a reboot and poweroff hang on Exynos machines cause by a hang in the samsung serial driver.
  • Various fixes to the Samsung MFC driver.
  • Add support for the Exynos5422 Odroid XU3 board.
  • Enable needed Kconfig symbols on the exynos, omap2plus and multi_v7 defconfigs.
  • Add a devfreq driver for the Tegra Activity Monitor

Following is the complete list of patches merged in this kernel release:

Collabora contributions to Linux kernel 3.19

Linux 3.19 was released last week and this version again contains contributions made by Collabora engineers as a part of our current projects.

In total 60 patches were contributed to the 3.19 release. These were for:

  • Work in the Intel i915 DRM driver to support atomic plane updates.
  • Fixes and removal of unnecessary layers in the Exynos DRM driver as a preparation to add atomic mode settings support.
  • Add support to the regulator framework to define regulators initial and suspend operating modes.
  • Changes to the max77802 regulator driver to support regulator operating modes changes.
  • Fix the Real-Time-Clock in the Snow, Peach Pit and Pi Chromebooks.
  • Enable kernel config options to have display panel working on Exynos boards.
  • Allow the regulator drivers to be enabled and disabled when Exynos system enters and leave suspend states.
  • Many cleanup and fixes to the common clock framework and clock drivers as a preparation for the per-user clock API change.

Following is the complete list of patches merged in this kernel release:

Collabora contributions to the Linux kernel 3.18

Linux 3.18 was released this week and like in previous kernel releases, it contains contributions made by Collabora engineers as a part of the projects involving the Linux kernel.

In total 45 patches were contributed to the 3.18 release. These were for:

  • Cleanups for the Intel i915 DRM driver
  • Various cleanups for the max77686 clock, rtc and regulator drivers.
  • Adding max77802 clock, rtc and regulator drivers.
  • Fixing regmap DT endianess parsing logic.
  • Improving the power model in the Exynos5 Peach Pit and Pi Chromebooks DT.
  • Using the regulator_get_voltage() function to get the mmc OCR mask.
  • Adding max77802 PMIC, ISL29018 sensor and atmel touchpad for Peach boards DT.
  • Setting the correct clock rate for i2c7 in Exynos5 Peach Pit and Pi DT.
  • Enable atmel touchpad, cgroups, sbs battery and atmel touchpad in exynos defconfig.
  • Fixing variable initialization for different regulator drivers.
  • Fixing MFC v5 support in the s5p-mfc driver.
  • Making module autoloading to work for i2c cros-ec-tunnel and cros_ec_keyb drivers.
  • Explicitly configure USB dual role mode as host for Exynos boards.
  • Adding a PM_QOS_MEMORY_BANDWIDTH pm_qos class.
  • Enabling gcov-based kernel profiling for ARM

Following is the complete list of patches merged in this kernel release:

An update on Device Tree support for IGEP boards

Linux v3.13 has been released a couple of days ago and this is the first kernel version that has complete Device Tree support for IGEP boards.

Since the initial DT support that I talked before, the following peripherals were added:

Ethernet
NAND flash
– USB HOST and OTG
Wifi/BT combo (support added by Enric Balletbo)

The only remaining bit in DT is video since the DT bindings for the OMAP Display Sub-System (DSS) have not landed in mainline yet so display support is still provided using the OMAP platform data quirk infrastructure.

So, this make the IGEP the first OMAP3 device to complete the transition to Device Tree based booting and the board file could finally be removed.

The migration from board files to Device Tree booting was not trivial as I initially thought since OMAP GPMC and GPIO DT support was not mature enough so I had to add support for GPMC DT ethernet and fix some annoying bugs.

U-Boot backend support for OSTree

Recently I had to work with OSTree which I think is a very promising and interesting project.

The OSTree site advertises it as

a tool for managing bootable, immutable, versioned filesystem trees

and it uses a combination of chroot and hard links to provide atomic upgrades and rollback of filesystem trees. You can refer to the project’s online manual and README for information about the motivation behind OSTree and its implementation.

When updating the kernel and initial RAM disk images OSTree creates Boot Loader Specification entries. These are drop-in snippets that define a kernel and init ramdisk that have to be used and boot arguments that the bootloader has to pass to the kernel command line on boot.

Currently only gummiboot and GRUB have support for these boot loader snippets.

We wanted to use OSTree on embedded devices and since most boards use U-Boot as their boot loader I needed to figure out what was the best approach to add a U-Boot support for OSTree.

Obviously this would have been to add boot loader spec entries support to U-Boot but there are two issues with this approach:

a) U-Boot does not currently support multi-boot

Since U-Boot is designed for embedded it just boots a single default operating system while the boot loader specification was designed for multi-boot. You can drop any number of snippets under /boot/loader/entries and the boot loader should populate its boot menu.

b) Not every vendor allows you to replace the boot loader

Some vendors do not allow to replace the boot loader binaries (i.e: store it on a read-only memory), implements DRM that requires binaries to be signed or are using a very old U-Boot version which would require to backport this support.

So, the solution was to make OSTree to generate boot information instead that could be used by any already deployed U-Boot. The same approach is used on OSTree to support syslinux.

U-Boot allows to modify boards default boot commands by reading and executing a bootscript file (boot.scr) or importing a plain text file (uEnv.txt) that contains environment variables that could parameterize its default boot command or a bootscript.

So, on deploy or upgrade OSTree reads the Boot Loader Specification snippets files and generates a uEnv.txt file that contains the booting information in a format that could be understood by U-Boot.

The uEnv.txt env var file is created in the path /boot/loader.${bootversion}/uEnv.txt. Also, a /boot/uEnv.txt symbolic link to loader/uEnv.txt is created so U-Boot can always import the file from a fixed path.

Since U-Boot does not support a menu to list a set of Operative Systems, the most recent boot loader entry from the list is used.

To boot an OSTree using the generated uEnv.txt file, a board has to parameterize its default boot command using the following variables defined by OSTree:

    ${kernel_image}:  path to the Linux kernel image
    ${ramdisk_image}: path to the initial ramdisk image
    ${bootargs}:      parameters passed to the kernel command line

Alternatively, for boards that don’t support this scheme, a bootscript that overrides the default boot command can be used.

An example of such a bootscript could be:

    setenv scriptaddr 0x40008000
    setenv kernel_addr 0x40007000
    setenv ramdisk_addr 0x42000000
    load mmc 0:1 ${scriptaddr} uEnv.txt
    env import -t ${scriptaddr} ${filesize}
    load mmc 0:1 ${kernel_addr} ${kernel_image}
    load mmc 0:1 ${ramdisk_addr} ${ramdisk_image}
    bootz ${kernel_addr} ${ramdisk_addr}

For more information you can refer to the commit that added U-Boot as backend and OStree test for U-Boot.

I would like to thank my employer Collabora for sponsoring this work.

mmap support for Raspberry Pi bcm2835 ALSA driver

Because I work on an awesome company I spent last week improving the Raspberry Pi ALSA driver.

A long standing issue was that the driver did not support memory-mapped I/O mode for audio stream transfers.

ALSA supports two transfers methods for PCM playback: Read/Write transfer where samples are written to the device using standard read and write functions and Direct Read/Write transfers where samples can be written directly to a mapped memory area and the driver is signaled once this has been done.

ALSA provides an API for both cases and each application using ALSA to access the audio device can choose which API to use. But since mmap was not supported by the bcm2835 driver, applications using the mmap API did not work on the Raspberry Pi.

To bypass hardware limitation such as the lack of mmap support, ALSA provides a set of PCM plug-ins that can be used to extend functionality and features of PCM devices.

These plug-ins are used by defining a custom /etc/asound.conf or .asoundrc and one of them is the mmap emulation plug-in (mmap_emul) which emulates mmap access using a set of read/write transfers. This plug-in was needed on the Raspberry Pi to allow applications using ALSA mmap API to work. But of course it introduces some latency and requires a custom configuration to enable it.

So, the best approach was to just add mmap support to the ALSA driver and get rid of the mmap emulation plug-in. Normally this is straightforward since the kernel allows memory areas to be mapped to user-space address space so applications can have direct access to device memory.

This was not the case on the Raspberry Pi since the PCM samples are processed by its VideoCore IVI GPU. The ARM11 CPU communicates with the VideoCore co-processor using a message passing interface (vchiq) which means that the CPU is not able to directly address the audio device hardware buffers and audio samples have to be sent to the device using vchiq messages.

Since hardware buffers can’t be directly mapped to user-space memory, an intermediate buffer is needed. This intermediate buffer is mapped to user-space so applications can store the audio samples there. Once user-space has finished writing the PCM samples they are pushed to VideoCore as vchiq messages.

Fortunately, the kernel ALSA subsystem provides a PCM indirect API which are a set of helper functions and a data structure to manage the intermediate and hardware buffers. It is really helpful so you don’t have to write all the buffer management.

So, after figuring out all of this I wrote a patch to add mmap support to the Raspberry Pi ALSA driver and send a pull request that also contained other improvements to the driver.

Since it has been merged on the Raspberry Pi kernel, this feature will be available on the next raspbian release but if you want to use it now you can do the following:

$ git clone git://github.com/raspberrypi/tools.git
$ git clone git://github.com/raspberrypi/linux.git
$ cd linux
$ git checkoub -b rpi-3.6.y origin/rpi-3.6.y
$ export ARCH=arm
$ export CROSS_COMPILE=../tools/arm-bcm2708/arm-bcm2708-linux-gnueabi/bin/arm-bcm2708-linux-gnueabi-
$ make bcmrpi_defconfig
$ make prepare modules_prepare
$ make M=sound/arm
$ sudo cp sound/arm/snd-bcm2835.ko /media/rootfs/lib/modules/3.6.11+/kernel/sound/arm/
$ sudo rm /media/rootfs/etc/asound.conf

The last step is very important since using both a mmap capable ALSA driver and the PCM mmap emulation plug-in does not work.

I want to thank my employer Collabora for allowing me to work on this:

Using Siri to control your Linux media center

The Raspberry Pi I bought a few days ago has just arrived. I was looking to existing Raspberry Pi projects to get some ideas on what use I could give to this board. One of the coolest projects I found out there was one that uses SiriProxy and WiringPi to open a garage door.

I thought that while deciding what to do with my Raspberry Pi I could start using it as a media center and let Siri control my multimedia apps.

Thanks to D-Bus talking to Linux apps is extremely easy. So I wrote a very simple SiriProxy plugin that controls the Rhythmbox music player using D-Bus and created a pull request in case upstream is interested in having more sample plugins.

I don’t speak Ruby so probably that won’t be the nicest Ruby code you will ever see (to say the least 🙂 )

To use the plugin just clone the master-rhythmbox branch from my SiriProxy fork on Github and follow the SiriProxy’s README set-up instructions.

Keep in mind that there is a known issue on SiriProxy master and you have to apply the fix found on this pull request.

The last two steps are to install ruby-dbus using Gems and change your .siriproxy/config.yml configuration file to include the Rhythmbox plugin.

$ sudo gem install ruby-dbus
$ echo -e "    - name: 'Rhythmbox'\n      path: './plugins/siriproxy-rhythmbox'" >> ~/.siriproxy/config.yml

That’s all, now you can run siriproxy server and Siri can start playing your favorite songs!

The voice commands currently supported are:

start player: starts the Rhythmbox media player
play, pause, stop, next and previous: to start, pause, stop, go to next and previous track.
shuffle on: turn shuffle mode on
shuffle off: turn shuffle mode off
volume up: turn volume up by 20%
volume down: turn volume down 20%

Device Tree support for IGEPv2 (and IGEP COM Module)

Because I work on an awesome company, I could spend the last few days doing upstream kernel work for the OMAP3 SoC based embedded board I maintain.

Now that SPL/U-Boot and the kernel supports the latest version of the board, the natural next step was to add support for Device Tree (DT).

I didn’t know too much about DT besides it was the new shiny way to describe hardware (instead of the infamous board files) and that it could allow to boot most ARM board using a single kernel image.

So, after spending some time learning about DT, I posted a patch-set that adds DT support for IGEP technology devices (IGEPv2 and IGEP COM Module). Hopefully the patches won’t need too much love before they get merged.

DT is a hot topic on the Linux kernel community right now and it’s been actively developed. Support for it is still premature on some platforms (such as OMAP3). So, these DT don’t have all the hardware support for IGEP that is already implemented using board files.

Currently is working (tested with latest Linux v3.7-rc7 kernel on an IGEPv2 board):
– MMC/SD
– UARTs
– GPIO LEDs
– TWL4030 codec audio
– pinmux/pinconf pinctrl

There are still peripherals not yet supported such as Ethernet, Flash memory and Wifi/BT. Some of these are connected to the OMAP processor through its General Purpose Memory Controller (GPMC) interface and patches to add DT bindings for OMAP GPMC are still flying around. So support for them should be easily added once these patches hit mainline.

It should also work on an IGEP COM Module but since I don’t have this hardware it has been just “compile tested”.

Many thanks to Enric who provided me his initial DT that booted the board, reviewed my patches and gave me lots of feedback and suggestions. Enric’s initial DT and a great explanation on how to boot a kernel with DT can be found on his blog entry.

Also, I’ve updated the oe-core/poky/yocto meta-igep layer to include a mainline Linux kernel recipe. This will make easier to test IGEP support on upstream and to add any remaining hardware enablement bits.

Adding IGEPv2 Rev.C support to mainline u-boot and kernel

I own an IGEPv2 Rev.C board which is a Texas Instrument OMAP3 DM3730 ARM embedded platform very similar to the Beagleboard-MX board but with more peripherals and a 512 NAND flash memory. This board is part of a family of embedded boards known as IGEP-based boards (another popular board from this family is the IGEP COM module).

IGEP’s manufacturer (ISEE) provides a very complete SDK and documentation on how to build a bootable image for the device and use all its features. The SDK is composed of an custom boot-loader (based on TI x-loader and u-boot), a custom kernel (based on v2.6.37 kernel from TI’s arago project), the Linaro ARM cross-toolchain and a root file system with all the necessary software and example code on how to make the best use of the board features. This makes the IGEPv2 a really competitive platform for embedded DIY projects.

Probably ISEE has its reasons to ship a custom kernel and boot-loader instead of their mainline counterparts but I (being a FOSS hacker) wanted to use upstream software on my board. So I started yet another hobby project to do on my (lately very scarce) free time to hack the kernel and u-boot and make them able to boot my IGEPv2 Rev.C board.

Fortunately, ISEE engineers have been pushing support for their IGEP board family to the mainline Linux kernel even though this kernel is not supported by their company. They do this on their free time because they understand the benefits of having their code as close as upstream as possible thus minimizing the size of the patch-set they need to carry on and forward port every time they move to a newer kernel release. But since they do on their spare time, it usually doesn’t support the latest version of their boards (such as the latest IGEPv2 Rev.C I own).

Also, ISEE used to ship u-boot as the IGEP family boot-loader before developing their own boot-loader (igep-x-loader). So it turned out that I only needed to add a few patches to the upstream kernel and u-boot to make them work with my board.

The first issue I had is that previous IGEP boards came with an OneNAND flash memory while newer boards use a NAND flash memory. So the first patch to the kernel was to to give NAND support to the IGEP. With this patch I was able to boot an upstream kernel using ISEE’s custom boot-loader.

The next step was to add the needed support to u-boot. This was a little more complicated since ISEE has not used u-boot for a while and u-boot has added recently a major feature which eliminates the need of a first stage loader (such as TI’s x-loader). Now u-boot has a framework known as SPL (Second Program Loader) that uses the same code base to generate both the first stage and second stage boot-loaders.

So, besides adding NAND support and a compile config option to choose the flash memory type to be used on an IGEP board I added SPL support for IGEP boards and updated the IGEP default kernel command line arguments to use the OMAP-specific serial driver and the EXT4 file system

With these patches my board booted with mainline u-boot and kernel but I found an issue on the IGEP kernel platform code that assumed the boot-loader would set the OMAP mux pin connected to the LAN9221i ethernet chip IRQ line as GPIO input mode (which was true with igep-x-loader but not with u-boot anymore). This should be made on the kernel anyways so the fix was just a trivial one-liner patch to the kernel.

All these patches are upstream now, so to test it just use the latest v3.6-rc4 kernel from Linus and u-boot master branch (git://git.denx.de/u-boot.git).

I had a lot of fun hacking this and my next step is to migrate the IGEP platform code to device trees. So, if anyone else owns an IGEPv2 or an IGEP COM module and is interested on using mainline software instead of ISEE custom one, please contact me so we can share the efforts 🙂