Quantcast
Channel: Boundary Devices
Viewing all 391 articles
Browse latest View live

Switching U-Boot versions on i.MX6

$
0
0
In our earlier post we described the what of the main-line based U-Boot sources for SABRE Lite and Nitrogen6X boards.

In this post, we’ll discuss the how.

To begin with, there’s the easy piece. We’ve published two Zip files that can upgrade or downgrade your U-Boot semi-automatically:


The reason for the term semi-automatically is that you will have to invoke the the upgrade or down-grade using the upgradeu command as discussed in our U-Boot conventions post:
U-Boot> run upgradeu


In each of these packages, you’ll see two files:

  • A boot script – named 6q_bootscript for the upgrade, and 6x_bootscript for the down-grade package, and
  • A U-Boot binary – named u-boot.imx for the upgrade, and u-boot-nopadding.bin in the down-grade.
If you look closely, you’ll see that we’re changing conventions[1]. We’re doing the same with the auto-boot script. We’re changing the name from 6q_bootscript to 6x_bootscript. The reason for the change is that these two versions have slight incompatibilities:

  • The new version contains support for the setexpr command, which prevents set from uniquely identifying setenv[2].
  • The new version has a slight difference in the syntax for sf probe. Specifically, it allows this form:
    sf probe [[bus:]cs] [hz] [mode]
    
    instead of this form:
    sf probe [bus:]cs [hz] [mode]
    
    In English: the chip-select is mandatory in U-Boot 2009.08. What’s worse is that it also has a different numbering scheme.
  • The primary outputs of the builds are different. U-Boot 2009.08 produced a file named u-boot.bin that contains the ROM header and 1024 bytes of padding at the start of the image. U-Boot 2012.10 produces a file named u-boot.imx which does not contain the header, so it needs to be burned to offset 0x400.
By changing the name along with the version bump, we can update each of our images to include support for either boot loader, and we’ll be doing that in the coming days.

In upcoming posts, we’ll fill you in on the details of how to get the sources for this latest version of U-Boot (they will be here). We’ll also add a check-list of each of the images on-line and a set of prototype boot scripts. In the mean-time, you can try these out and experience the new display and SATA support.

We can’t finish this post without referring you to the post on un-bricking your board. This process should be straightforward, but things happen and it’s always good to have the imx_usb tool handy.



Footnotes    (↵ returns to text)
  1. 6x_upgrade instead of 6q_upgrade
  2. U-Boot allows shortest-unique short-hand for command invocation. For example, fatl is normally interpreted as the full command fatload.

Boot scripts for main-line U-Boot on i.MX6

$
0
0
As discussed in yesterday’s post on upgrading (and downgrading) U-Boot to the latest version, we’re changing the name of the boot script from 6q_bootscript to 6x_bootscript to reflect the syntax changes between the two and to allow userspace images to continue to operate with either version in the near term. In this post, we’ll walk through the structure of the new boot scripts, which have auto-configuration of displays as discussed in in this post. We’ll also provide sample source and binaries for both Android and non-Android Linux userspaces.

Boot script review

To recap a lot of other posts, boot scripts provide a very flexible means of setting up the environment for a particular Operating system. For Linux-based systems, this generally involves four steps:

  1. Load the kernel,
  2. Optionally load a RAM disk image,
  3. Configure bootargs (the kernel command-line), and
  4. Launch the kernel
Each of these steps have distribution-specific tweaks. For example, Android wants command-line arguments for things like androidboot.console and calibration. Ubuntu and Debian systems often use a flag like fixrtc to prevent extraneous filesystem checks.

Boot scripts are essentially text files with a 64-byte header that contains a checksum of the content.

There’s an on-line tool to compile a boot script on this page.

Auto-configuration of displays

Configuration of displays under Linux on i.MX6 involves mostly adding a set of “video=” clauses to the kernel command-line, but for high-resolution displays, the “fbmem=” clause is also needed.

The following code snippet will be included in all of the 6x_bootscript sources that we’ll use to set these variables.
setenv nextcon 0;
if hdmidet ; then
	setenv bootargs $bootargs video=mxcfb${nextcon}:dev=hdmi,1280x720M@60,if=RGB24
	setenv fbcon "fbcon=28M";
	setexpr nextcon $nextcon + 1
else
	echo "------ no HDMI monitor";
fi

i2c dev 2
if i2c probe 0x04 ; then
	setenv bootargs $bootargs video=mxcfb${nextcon}:dev=ldb,LDB-XGA,if=RGB666
	if test "0" -eq $nextcon; then
		setenv fbcon "fbcon=10M";
	else
		setenv fbcon ${fbcon},10M
	fi
	setexpr nextcon $nextcon + 1
else
	echo "------ no Freescale display";
fi

if i2c probe 0x38 ; then
	setenv bootargs $bootargs video=mxcfb${nextcon}:dev=ldb,1024x600M@60,if=RGB666
	if test "0" -eq $nextcon; then
		setenv fbcon "fbcon=10M";
	else
		setenv fbcon ${fbcon},10M
	fi
	setexpr nextcon $nextcon + 1
else
	echo "------ no 1024x600 display";
fi

if i2c probe 0x48 ; then
	setenv bootargs $bootargs video=mxcfb${nextcon}:dev=lcd,CLAA-WVGA,if=RGB666
	if test "0" -eq $nextcon; then
		setenv fbcon "fbcon=10M";
	else
		setenv fbcon ${fbcon},10M
	fi
	setexpr nextcon $nextcon + 1
else
	echo "------ no 800x480 display";
fi

while test "3" -ne $nextcon ; do
	setenv bootargs $bootargs video=mxcfb${nextcon}:off ;
	setexpr nextcon $nextcon + 1 ;
done
This is a lot of script, but has a pretty simple form. As discussed in the post on auto-configuration, we’re making use of the hdmidetect and i2c detect commands to determine whether an HDMI monitor or set of touch screen controllers is connected to the system.

The ordering of the display detection code is from highest resolution to lowest resolution, and if multiple are connected, the first will be the primary display.

At the tail end of the script, a while loop will explicitly turn off all remaining displays because the Linux kernel will otherwise default to enabling a 1024x768 display.

Reference boot scripts

The following is a list of reference boot scripts. In order to use each, you’ll need to rename the binary file to /6x_bootscript on the first partition of your bootable media.

Operating systemSourceBinaryDetails
Android android-bootscript-20121110.txt android-bootscript-20121110 Loads /uImage and /uramdisk.img.
Non-Android Linux 6x_bootscript-20121110.txt 6x_bootscript-20121110 Sets root=/dev/mmcblk0p1 (the first partition of the first SD card)
All 6x_upgrade-20121111.txt 6x_upgrade-20121111 Validates U-Boot in SPI-NOR from /u-boot.imx or //u-boot.nopadding.

Updated images

If you don’t already have an SD card image for your platform, we’ve updated the following images to contain 6x_bootscript:

To-do list

We’re in the process of cleaning up our patch set and re-basing on the latest main-line code base. As soon as this is done, we’ll publish a new branch of source code in the production branch of this project on GitHub:

We’ll also create a blog post with instructions on how to get and compile the image.

If you’re in a hurry, you can look at the nit6x-prerelease branch.

i.MX6 is officially launched

$
0
0
In case you hadn’t heard, Freescale has officially launched the i.MX 6 Series into production:
Freescale’s i.MX 6 Series Applications Processors Roar into Production

This should end the hassle regarding documentation and source code access. We’ll be pushing more information your way via our blog, but in the near term, here are some notes about the information that’s now available:

We’ve been referring to them for quite a while, and you’ll now be able to access them directly without an NDA.

Wait a second (hopefully less)

$
0
0
It’s amazing how multiple paths often lead to the same place. We’ve been tracking a couple of issues and recently that seem to have the same remedy.

For the impatient:

If you’re seeing inconsistent ping times or sporadic stalls in the startup of your userspace, the enable_wait_mode=off kernel parameter might fix the issue.

U-Boot> setenv bootargs $bootargs enable_wait_mode=off
U-Boot> saveenv && boot

The details:

The two issues are these:

  • The Android stall issue discussed in the post about our recent Android release, and
  • An issue with inconsistency in ping times.
The first we narrowed down to a stall in a call to rcu_barrier in the Linux filesystem code:

The second caused intermittent ping times:

root@freescale:~/$ ping 192.168.0.201 -i.2 -c1000
...
1000 packets transmitted, 1000 received, 0% packet loss, time 200010ms
rtt min/avg/max/mdev = 0.124/64.579/199.945/82.149 ms 
Both of these issues are addressed by enable_wait_mode=off. That kernel parameter changes around the kernel idle loop to run in clocked mode instead of unclocked, power-off mode.

With this change in place, we haven’t seen either the Android stall and ping times are consistently below 1ms.

We’ve only run crude measurements of input power consumption, but only saw ~10mA increase on the 5V supply.

Nitrogen6X Metal Enclosure

$
0
0
As discussed previously, one of the primary differences between SABRE Lite and Nitrogen6X is connector placement and orientation. Nitrogen6X has all of the field pluggable connections along one edge of the board so it can be enclosed and used directly in production applications.

To that end, we put together a simple yet effective metal box for the Nitrogen6X – Nit6X_ENC.

Contact us if you need dimensional drawings or other information.

Compiling latest U-Boot for i.MX6

$
0
0
This is probably old-hat to most readers of this blog, but here are the steps to get and compile the latest U-Boot for i.MX6.

Don’t let the nitrogen6x reference below fool you. These work for both SABRE Lite and Nitrogen6X, since our U-Boot code base auto-detects them.

Note that these instructions don’t currently work for Solo or Dual-Lite devices. If you have one of those, you should have received separate instructions from us.

~$ git clone git://github.com/boundarydevices/u-boot-imx6.git
Cloning into 'u-boot-imx6'...
remote: Counting objects: 98621   
remote: Counting objects: 194430, done.
remote: Compressing objects: 100% (37277/37277), done.
remote: Total 194430 (delta 156593), reused 192232 (delta 154419)
Receiving objects: 100% (194430/194430), 49.84 MiB | 1.87 MiB/s, done.
Resolving deltas: 100% (156593/156593), done.
~$ cd u-boot-imx6
~/u-boot-imx6$ git checkout origin/production -b production
~/u-boot-imx6$ export ARCH=arm
~/u-boot-imx6$ export CROSS_COMPILE=arm-none-linux-gnueabi-
~/u-boot-imx6$ make nitrogen6x_config 
Configuring for nitrogen6x - Board: nitrogen6x, Options: IMX_CONFIG=board/freescale/imx/ddr/mx6q_4x_mt41j128.cfg
~/u-boot-imx6$ make all
Generating include/autoconf.mk
...
make -C examples/api all
make[1]: Entering directory `/home/ericn/u-boot-imx6/examples/api'
make[1]: Nothing to be done for `all'.
make[1]: Leaving directory `/home/ericn/u-boot-imx6/examples/api'
~/u-boot-imx6$ ls -l u-boot.imx 
-rw-rw-r-- 1 user group 312572 Nov 26 11:48 u-boot.imx


In English, these steps are:
  • Clone the U-Boot sources from git://github.com/boundarydevices/u-boot-imx6.git, and
  • Check out the production branch, and
  • Set your PATH and CROSS_COMPILE environment variables to point at your cross compiler, and the ARCH variable to arm, and
  • Choose the nitrogen6x_config configuration, and
  • Compile
The output is the file u-boot.imx as discussed in this post.

Note that the PATH and CROSS_COMPILE variables above refer to the latest LTIB package. You’ll need to change them if you’re using a different cross-compiler.

Android R13.4-GA for i.MX6 in stages – Stage 3: Customization

$
0
0
In our previous posts on Android R13.4-GA release from Freescale, we discussed how to boot it over NFS, and how to boot it on an SD card, making a handful of changes to the file-system images.

What we didn’t do was compile it from source. At the time of those posts, the source weren’t available except to those under NDA with Freescale, so it was difficult to describe our customizations. In this post, we’ll describe the next steps in getting, customizing, and building the Android image from source, and we’ll discuss some of the challenges along the way.

This will be a rather lengthy post, but we hope it’s worth your time. As you look to create a product based on i.MX6 (and hopefully Nitrogen6X), you’ll likely need to know some of the things described below.

Overview and highlights

The customization done in this release includes some fixes over the previous image:
  • Dual display support
  • Analog Audio support
  • Camera support
It also has some omissions:
  • Wi-Fi and Bluetooth support on Nitrogen6x
  • Proper support for recovery partition

For the impatient

If you just want to grab a new release, we’ve placed one here:

Note that this is not an SD card image in the form used previously (to be restored using dd). Instead, this image is a tar-ball that contains a set of directories, one for each partition used and a README file that describes the copying process.

This is a precursor to what we’ll do in better way later. It suggests the use of the tool sfdisk to create a set of partitions on your SD card, then uses cp -ravf to copy the files.

Baseline sources

All of this discussion starts with the Freescale R13.4-GA source package.

You should probably get and install that package into /opt/imx-android-r13.4-ga if only for the documentation (/opt/imx-android-r13.4-ga/docs/), since we’ll refer to some of the notes in the documents below, starting with the file “R13.4_Android_User_Guide.pdf”.

In that file, you’ll see roughly the steps below:

  • Get repo
  • Initialize a repo tree from AOSP
  • Copy Freescale’s default.xml
  • Sync the repo
  • Grab Freescale’s kernel and RAM disk
  • Apply Freescale patches using c_patch
  • Build Android
What you won’t see in that document is what you’re left with on your dev machine. The result of all of the above leaves you with a partial repo repository with some references to external git servers on Google’s site, some references to git servers at Linaro, and some local git trees.

You will be able to run repo status and find local changes to the AOSP code, but not for most of the pieces we’re customizing.

Our infrastructure

While far short of the right solution, we’ve put together a combination of git repositories to allow us (and you) to track updates to the Android R13.4-GA sources for Nitrogen6X. At the end, you should be able to something a little cleaner:

~/$ mkdir myandroid
~/$ cd myandroid
~/myandroid$ repo init \
              -u git://github.com/boundarydevices/imx-android-r13.4-ga.git \
              -b nitrogen6x
~/myandroid$ repo sync
~/myandroid$ ... build here


Unfortunately, you can’t quite do this yet because pieces of the code base are closed source, and subject to the Freescale EULA. We’ll cover the details of how and where you can gain access in a future post.

We’ve split the various projects that comprise the Android tree and divided them up based on their open-source status. Those that are freely distributable are up on GitHub. Others are on a private server of ours running gitolite and require prior authorization.

The resulting list is available here.

Early changes

We started the process of making changes by creating device/boundary/nitrogen6x, to contain the specifics. If you’ve worked with any other Android O/S builds, you know that the convention is to add board support into the device/ tree, one per directory.

All of this is open source and visible on Github:

This tree gives us a place to put the changes we’ve mentioned in previous posts, such as:

We’ve also uploaded our patches to ts_calibrator in a proper git repository:

Additional structural updates

All of the changes listed above were present in the prior image though. Now that we have a place to keep our changes, we can feel comfortable making additional updates without fear of losing them or losing track. You can browse the history to see some of the changes:

New (fixed) features

As mentioned in the preface above, we also fixed some things that were broken in our previous R13-4 images.

Camera support

Fixing camera support didn’t require re-compilation, or at least not re-compilation of the Android pieces. What it did require was removal of the OV56340 MIPI camera from this bit of init.rc, and removal of the same from the kernel configuration.

Dual display

Dual display support also didn’t require re-compilation of any Android bits. It also didn’t require re-compilation of the kernel. What we found when tracking this down is that either or both of the following are needed:

  • The HDMI display needed to be the second display (/dev/fb2), and/or
  • The files /system/etc/display_fb0..2.conf need to have the proper screen resolutions
We’ve only done limited testing here, and there are some quirks:
  • Dual display with RGB and LVDS doesn’t work (crashes)
  • Triple display also fails
We’ll post some updates in the future. In the mean-time, if you change your display bootargs such that it has an LVDS or RGB display as mxcfb0 and the HDMI device as mxcfb2 and make sure that /system/etc/display_fb2.txt contains the resolution found in /sys/class/graphics/fb2/mode, you should be able to get both displays working together.

Analog audio (SGTL5000)

This one took a bit longer to fix, and did require changes to the Android HAL for Nitrogen6x.

It’s also going to take a bit longer to explain, and we can’t give direct code reference, because the changes needed are in a closed-source package (hardware/imx tree).

Between R13.2 and R13.4, Freescale switched to using a hardware module named tinyalsa, located in hardware/imx/alsa/tinyalsa as the bridge between Android’s Audio Flinger and the alsa audio drivers used on the various i.MX6 boards.

In the process, they only included support for HDMI and the Wolfson Micro codecs that are present on the Freescale-branded development boards. We added support for the SGTL5000 with this patch.

The to-do list

Stay tuned for the next couple of posts which will describe:

  • How to get access to the repo mentioned above, and
  • How to enable Wi-Fi and Bluetooth support on Nitrogen6X.

Access to private repositories

$
0
0
As discussed in our previous post on Android Customization, some of the software we’re modifying for SABRE Lite and Nitrogen6X are restricted by licenses.

They’re still open-source, but not completely free to distribute, and require acceptance of an End User License agreement, so we can’t simply post the sources in a public repository on GitHub, et cetera.

In order to address these needs, we’ve put together a private git server using gitolite. This system is configured to performs user authorization through SSH Public key authentication.

If you look in the the Android R13.4 repo manifest, you’ll see that the server (remote) named boundary-linode has a base URL of ssh://git@linode.boundarydevices.com/.

In English, this means that the reference is to a user named git on a server named linode.boundarydevices.com and uses the ssh protocol. This user is configured with no valid password and can only be accessed by clients that provide specific public keys. For details on how this works, please Google “ssh public key authentication”.

As a practical matter, this will require that you have an ssh client installed. This should be automatic on any Linux or Mac installation. Under Windows, you’ll likely need Cygwin to get the combination of ssh and git.

Once you have SSH and git installed, you’ll also need to generate a private/public key pair. There’s a nice tutorial on Github that explains how to do this.

Finally, in order to confirm agreement with our EULA, we’ll need you to:

Once this is done, you’ll receive a confirmation e-mail when we’ve configured the private server(s) with your credentials.

This is a hassle, but having this infrastructure in place will allow us to share code for a number of restricted packages, and we help it enables you to get your products to market faster.


HDMI CEA mode

$
0
0
This is just a quick note regarding something we found in the Linux kernel last week.

After swapping monitors to an LG W2361VG (a 23″ monitor with a DVI input port), I noticed that the screen resolution kept coming up at 640×480, even though the bootargs was specifying 720P resolution.

After much digging through the kernel drivers, I found that most of the modes reported by the monitor over EDID were being rejected by a piece of code in drivers/video/mxc_hdmi.c which was looking up the resolution in an embedded table in drivers/video/mxc/mxc_edid.c.

Tracing through the ramifications, it doesn’t appear that this restriction is necessary, and in fact, removing the requirement seems to work just fine, so we pushed a patch to both of our active kernel branches:

If you’re experiencing similar things, you might want to pull in this patch, or upgrade to our latest.

The root password is “Boundary”

$
0
0
This should be the shortest blog post ever.

This needs to be said, apparently hasn’t, and the title should say it all.

When we have a choice (and we usually do), we set the root password for any userspace distribution we send out to “Boundary”.

We’d leave it empty, but OpenSSH usually requires a non-empty password and we do just about everything through SSH.

‘Nuff said.

Microphone input on the SABRE Lite and Nitrogen6x

$
0
0
We just identified a bug in the i.MX6 Linux driver for the SGTL5000 audio codec that could account for some reports of microphone failure.

You can see the patch here:

In English, that 4 is used as the maximum value for a control named “Mic” which is supposed to allow setting of a microphone gain:

Simple mixer control 'Mic',0
  Capabilities: volume volume-joined penum
  Playback channels: Mono
  Capture channels: Mono
  Limits: 0 - 4
  Mono: 0 [0%] [0.00dB]
The only trouble is, there are only two bits of gain in the corresponding SGTL5000 register, so setting the value to 4 causes wrap and yields zero.

When a commodity PC microphone is attached, the result is silence.

We’ve pushed patches to both the boundary-imx-android-r13.4-ga and boundary-L3.0.35_12.09.01_GA kernel branches on GitHub.

We also found that for the microphones we have here (commodity PC boom mics) a default value of 2 for the gain gives the best results. We pushed patches for that too.

As a final note, you might need to change this setting to match other microphones. The value of 4KOhms worked well in our testing.

Testing under Linux was done with arecord and aplay as follows:

root@linaro-alip:/tmp# arecord -vvv -d 5 -f cd t.wav
Recording WAVE 't.wav' : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo
Plug PCM: Hardware PCM card 0 'sgtl5000-audio' device 0 subdevice 0
Its setup is:
  stream       : CAPTURE
  access       : RW_INTERLEAVED
  format       : S16_LE
  subformat    : STD
  channels     : 2
  rate         : 44100
  exact rate   : 44100 (44100/1)
  msbits       : 16
  buffer_size  : 22052
  period_size  : 5513
  period_time  : 125011
  tstamp_mode  : NONE
  period_step  : 1
  avail_min    : 5513
  period_event : 0
  start_threshold  : 1
  stop_threshold   : 22052
  silence_threshold: 0
  silence_size : 0
  boundary     : 1445199872
  appl_ptr     : 0
  hw_ptr       : 0
Max peak (11026 samples): 0x00001580 ####                 16%
Max peak (11026 samples): 0x0000119f ###                  13%
Max peak (11026 samples): 0x000003f6 #                    3%
Max peak (11026 samples): 0x0000033b #                    2%
...
Max peak (11026 samples): 0x00001a5e #####                20%
Max peak (11026 samples): 0x000009f1 ##                   7%
Max peak (11026 samples): 0x000011b2 ###                  13%
Max peak (11026 samples): 0x00001437 ####                 15%
Max peak (11026 samples): 0x0000187e ####                 19%
Max peak (11026 samples): 0x0000101c ###                  12%
Max peak (11026 samples): 0x000045d1 ###########          54%
Max peak (11026 samples): 0x00001e57 #####                23%
Max peak (11026 samples): 0x00002306 ######               27%
Max peak (11026 samples): 0x0000104c ###                  12%
Max peak (11026 samples): 0x000016b4 ####                 17%
Max peak (11026 samples): 0x00001697 ####                 17%
root@linaro-alip:/tmp# aplay -D hw:0,0 t.wav 
Playing WAVE 't.wav' : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo

Linaro Precise ALIP on i.MX6

$
0
0
We’ve recently been testing the ALIP (ARM Linux Internet Platform) release from Linaro and just uploaded an image:

This platform has many of the things we love about Ubuntu without the bloat of the Unity package. Instead, it includes a simple LXDE Desktop manager, the Chromium browser, MPlayer and not much else.

This makes it quick to boot and relatively lightweight, at ~250 MB gzipped.

We added just a handful of things to the stock release:

  • OpenSSH Server – because we can’t live without it, and
  • Changed the root password to “Boundary” to allow root login over SSH, and
  • Our latest kernel (including audio patches and modules in /lib/modules), and
  • Our 6x_bootscript for automagic detection of displays, and
  • The firmware for the TiWi module (/lib/modules/ti-connectivity), and
  • A small patch to /etc/init.d/x11-common. For some reason, the ownership of /dev/shm required root access, so Chromium refused to start.
Screen shot running Chromium and iwlist

Nitrogen6X Bluetooth details

$
0
0
The TiWi R2 module on the Nitrogen6X board contains both Wi-Fi and Bluetooth and it seems we haven’t documented the interface to the Bluetooth portion.

This short post aims to remedy that.

There are essentially two connections from the i.MX6 to the TI Bluetooth device: There are other ways to do this, but the sysfs GPIO interface allows us to control the reset line and we can use bluez to configure the Bluetooth interface as follows:

root@linaro-alip:~# bluetoothd
root@linaro-alip:~# echo 176 >/sys/class/gpio/export
root@linaro-alip:~# echo low >/sys/class/gpio/gpio176/direction
root@linaro-alip:~# # sleep 1 is needed here if you write a script
root@linaro-alip:~# echo high >/sys/class/gpio/gpio176/direction
root@linaro-alip:~# hciattach -t 30 -s 115200 /dev/ttymxc2 texas 3000000 flow
Found a Texas Instruments' chip!
Firmware file : /lib/firmware/TIInit_7.2.31.bts
Loaded BTS script version 1
texas: changing baud rate to 3000000, flow control to 1
Device setup complete
root@linaro-alip:~# hcitool scan
Scanning ...
        00:21:4F:B8:A3:C9       ericsony-0
        9C:B7:0D:AB:48:60       MIKEE6430
Let’s walk through this in steps:

  • bluetoothd – This starts up the Bluetooth daemon to manage all Bluetooth connections,
  • echo to /sys/class/gpio/blah – These lines tell the system to expose GP6:16 (#176), then drive the reset pin as an output low (asserted), followed by high (deasserted),
  • hciattach – This line connects the HCI (Bluetooth) device to the serial port at 3Mbps and configures it as a Texas Instruments device with flow control. Note that this also downloads the firmware from /lib/firmware/TIInit_7.2.31.bts,
  • hcitool scan – This line scans for local devices. Now I need to walk around the office to find out who Mike is…

LTIB on i.MX6 without X

$
0
0
Our previous LTIB images for i.MX6 have all been re-packaged versions of the binaries released by Freescale.

We just uploaded the first that we actually built ourselves. You can download it from here:

To install it, simply download and extract onto a single-partition SD card like so:

~/$ echo ,,83 | sudo sfdisk /dev/mmcblk0
~/$ sudo mkfs.ext3 -L ltib-12.09 /dev/mmcblk0p1 && sync
~/$ udisks --mount /dev/mmcblk0p1
~/$ sudo tar -C /media/ltib-12.09/ -zxvf ltib-12.09-20121218.tar.gz
~/$ sync && sudo umount /media/ltib-12.09
For those of you who have gone through the process, LTIB can be quirky and has a number of host-system dependencies that can get in the way of a successful build.

The following is a list of the hurdles we had to overcome during the build process.

The LTIB image contains our latest non-Android kernel from Github and the latest version of U-Boot.

The LTIB configuration itself includes G-Streamer acceleration and the Vivante GPU demos and is configured to provide a login on /dev/tty0. Additional details are available in the file README.ltib in the root of the tar-ball.

i.MX6 Gigabit Ethernet

$
0
0
We’ve recently been doing some digging into Gigabit Ethernet performance issues and questions for our i.MX6 boards and it’s time to publish some of our results. We’ve discovered a number of settings and code updates that can dramatically improve network stability and throughput.

For the impatient

There are some architectural limitations on i.MX6 boards but some configuration options and driver issues are more likely to cause performance issues. We’ve identified a number of fixes that make the situation markedly better as shown below.

Before (TCP)

root@linaro-nano:~# cat /proc/cmdline
video=mxcfb0:dev=hdmi,1280x720M@60,if=RGB24 video=mxcfb1:off video=mxcfb2:off ...
root@linaro-nano:~# cat /proc/version
Linux version 3.0.35-2026-geaaf30e (b21710@bluemeany) ...
root@linaro-nano:~# while iperf -c 192.168.0.162 -r \
                    | grep Mbits ; do echo -n ; done
[  5]  0.0-10.0 sec   474 MBytes   397 Mbits/sec
[  4]  0.0-10.1 sec  10.1 MBytes  8.47 Mbits/sec
[  5]  0.0-10.0 sec   474 MBytes   397 Mbits/sec
[  4]  0.0-10.0 sec  10.4 MBytes  8.72 Mbits/sec
[  5]  0.0-10.0 sec   472 MBytes   396 Mbits/sec
[  4]  0.0-10.0 sec  17.2 MBytes  14.4 Mbits/sec
 

After (TCP)

root@linaro-nano:~# cat /proc/cmdline
enable_wait_mode=off video=mxcfb0:dev=hdmi,1280x720M@60,if=RGB24 video=mxcfb1:off ...
root@linaro-nano:~# cat /proc/version
Linux version 3.0.35-2026-geaaf30e-02076-g68b5fa7 ...
root@linaro-nano:~# while iperf -c 192.168.0.162 -r \
                    | grep Mbits ; do echo -n ; done
[  5]  0.0-10.0 sec   473 MBytes   397 Mbits/sec
[  4]  0.0-10.0 sec   509 MBytes   426 Mbits/sec
[  5]  0.0-10.0 sec   473 MBytes   397 Mbits/sec
[  4]  0.0-10.0 sec   508 MBytes   426 Mbits/sec
[  5]  0.0-10.0 sec   471 MBytes   395 Mbits/sec
[  4]  0.0-10.0 sec   510 MBytes   427 Mbits/sec
  In the output from iperf above, each pair of lines indicate the transmit and receive bandwidth in that order. Note the horrible performance numbers for receive in the baseline. The UDP performance is markedly better, with transmit throughput of ~450 Mbits/s and receive speeds that can exceed 600 Mbits/s.

After (UDP)

[  4]  0.0- 1.0 sec  55.3 MBytes   462 Mbits/sec  0.084 ms   15/39459 (0.038%)
[  3]  0.0- 1.0 sec  72.8 MBytes   611 Mbits/sec  0.012 ms   -1/51843 (-0.0019%)
  The details below will provide details of how we tested things, and describe a series of patches that lead to this improvement in both stability and speed.

Test environment

Four devices were used during the tests defined below:
  • A Sony Vaio laptop with internal Gb Ethernet adapter,
  • A Nitrogen6X board with i.MX6Quad TO 1.0
  • A SABRE SD board with i.MX6Quad TO 1.1
  • A SABRE Lite board with i.MX6Quad TO 1.2
  • A Cisco Linksys SE2500 Gigabit Ethernet switch
The tests used a Linaro nano userspace. A tar-ball is available here that contains all of the kernel versions mentioned. Specific baseline kernel versions include:
  • Blue Meany – This is the binary kernel (uImage) provided in the images_L3.0.35_12.09.01-GA release. We did not re-compile this kernel.
  • Boundary Before – This is the first version we compiled, as a test to ensure that it matches Blue Meany and serves as the baseline for this series of tests.
  • Boundary Latest – This is the latest release from the boundary-L3.0.35_12.09.01-GA branch of our Github kernel.
All of the testing was done with kernels based on Freescale’s L3.0.35_12.09.01_GA release with various patches as described.

First change: enable_wait_mode=off

We’ve documented the first change made in this post a week ago, but we didn’t mention the throughput implications. In the output below, you can see around a 10% improvement in the Blue Meany kernel by just adding enable_wait_mode=off to the kernel command-line. This change made a huge difference on Tapeout 1.2. It increased the receive speed from on the order of 10 Mbits/s to ~200 Mbits/s. on Tapeout 1.0 devices, the difference was less dramatic, presumably because a number of the spots that use enable_wait_mode in the kernel are also conditional on the silicon revision. In any case, with just this change, both revisions of board have markedly increased receive performance as shown below.
root@linaro-nano:~# cat /proc/version
Linux version 3.0.35-2026-geaaf30e (b21710@bluemeany)...
root@linaro-nano:~# cat /proc/cmdline
enable_wait_mode=off ...
root@linaro-nano:~# while iperf -c 192.168.0.162 -r | grep Mbits ; do echo -n ; done
[  5]  0.0-10.0 sec   443 MBytes   372 Mbits/sec
[  4]  0.0-10.0 sec   250 MBytes   210 Mbits/sec
[  5]  0.0-10.0 sec   476 MBytes   399 Mbits/sec
[  4]  0.0-10.0 sec   252 MBytes   211 Mbits/sec
^C
As noted in the previous post, this environment update will also make ping times more consistent.

Measuring performance

In the summary above, we showed the output from the simplest invocation of iperf. When used as shown, the program will connect over TCP:
root@linaro-nano:~# iperf -c 192.168.0.162 -r
------------------------------------------------------------
Server listening on TCP port 5001
TCP window size: 85.3 KByte (default)
------------------------------------------------------------
------------------------------------------------------------
Client connecting to 192.168.0.162, TCP port 5001
TCP window size: 58.4 KByte (default)
------------------------------------------------------------
[  5] local 192.168.0.119 port 52681 connected with 192.168.0.162 port 5001
[ ID] Interval       Transfer     Bandwidth
[  5]  0.0-10.0 sec   475 MBytes   398 Mbits/sec
[  4] local 192.168.0.119 port 5001 connected with 192.168.0.162 port 42421
[  4]  0.0-10.0 sec   228 MBytes   191 Mbits/sec
Because of the use of TCP, flow control is imposed on the link by the upper layers, and the bandwidth is throttled to the slower of the speeds of the two ends. Using UDP removes this possible bottleneck and also allows a flag to set the target bandwidth (-b SPEED) and will show us the amount of packet loss. The -t flag allows us to override the default 10 second test for quicker results.
root@linaro-nano:~# iperf -c 192.168.0.162 -r -u -b 200M -t 2
------------------------------------------------------------
Server listening on UDP port 5001
Receiving 1470 byte datagrams
UDP buffer size:  106 KByte (default)
------------------------------------------------------------
------------------------------------------------------------
Client connecting to 192.168.0.162, UDP port 5001
Sending 1470 byte datagrams
UDP buffer size:  106 KByte (default)
------------------------------------------------------------
[  4] local 192.168.0.119 port 51275 connected with 192.168.0.162 port 5001
[ ID] Interval       Transfer     Bandwidth
[  4]  0.0- 2.0 sec  48.2 MBytes   202 Mbits/sec
[  4] Sent 34359 datagrams
[  4] Server Report:
[  4]  0.0- 2.0 sec  48.1 MBytes   202 Mbits/sec   0.063 ms   71/34358 (0.21%)
[  4]  0.0- 2.0 sec  1 datagrams received out-of-order
[  3] local 192.168.0.119 port 5001 connected with 192.168.0.162 port 53796
[  3]  0.0- 2.0 sec  48.3 MBytes   203 Mbits/sec   0.038 ms    0/34483 (0%)
[  3]  0.0- 2.0 sec  1 datagrams received out-of-order
Doing a quick smoke-test at a few key rates shows some interesting results. The following are slightly edited to make them more readable:

100Mbit/s UDP test

root@linaro-nano:~# iperf -c 192.168.0.162 -u -r -b 100M ;
[  4]  0.0- 2.0 sec  23.9 MBytes   100 Mbits/sec   0.048 ms    0/17082 (0%)
[  3]  0.0- 2.0 sec  24.0 MBytes   101 Mbits/sec   0.001 ms    3/17094 (0.018%)

400Mbit/s UDP test

root@linaro-nano:~# iperf -c 192.168.0.162 -u -r -b 400M -t 2;
[  4]  0.0- 2.0 sec  34.1 MBytes   143 Mbits/sec   0.091 ms    0/24338 (0%)
[  3]  0.0- 5.7 sec   205 MBytes   301 Mbits/sec   0.013 ms 198303/344825 (58%)

1Gbit/s UDP test

root@linaro-nano:~# iperf -c 192.168.0.162 -u -r -b 1000M -t 2;
[  4]  0.0- 2.0 sec   108 MBytes   453 Mbits/sec   0.036 ms   54/77241 (0.07%)
[  3]  0.0- 2.1 sec  64.9 MBytes   254 Mbits/sec  15.539 ms 95165/141465 (67%)
As you can see, there’s no loss at 100M, very little loss at 400M and a huge amount of receiver loss at 1G (the second line reports the receiver numbers). Interestingly, the received bandwidth also decreased when going from 400M to 1Gbit/s. Using a script to be a bit more thorough, and convince ourselves that the pattern holds:
root@linaro-nano:~# cat > bwtest.sh << EOF
#!/bin/sh
bw=50;
while [ \$bw -le 1000 ]; do
	echo "----------bandwidth \$bw" ;
	iperf -c 192.168.0.162 -u -r -t 2 -b \${bw}M | grep % ;
	bw=\`expr \$bw + 50\` ;
done
EOF
root@linaro-nano:~# chmod a+x bwtest.sh
root@linaro-nano:~# ./bwtest.sh 
root@linaro-nano:~# ./bwtest.sh 
----------bandwidth 50
[  4]  0.0- 2.0 sec  11.9 MBytes  50.0 Mbits/sec   0.010 ms    0/ 8510 (0%)
[  3]  0.0- 2.0 sec  11.9 MBytes  50.0 Mbits/sec   0.002 ms    0/ 8511 (0%)
----------bandwidth 100
[  4]  0.0- 2.0 sec  24.0 MBytes   100 Mbits/sec   0.048 ms    0/17085 (0%)
[  3]  0.0- 2.0 sec  24.0 MBytes   100 Mbits/sec   0.009 ms    4/17094 (0.023%)
----------bandwidth 150
[  4]  0.0- 2.0 sec  35.9 MBytes   150 Mbits/sec   0.063 ms    8/25601 (0.031%)
[  3]  0.0- 2.0 sec  35.9 MBytes   151 Mbits/sec   0.010 ms    0/25641 (0%)
----------bandwidth 200
[  4]  0.0- 2.0 sec  48.2 MBytes   202 Mbits/sec   0.066 ms    0/34413 (0%)
[  3]  0.0- 2.0 sec  48.3 MBytes   203 Mbits/sec   0.028 ms    0/34483 (0%)
----------bandwidth 250
[  4]  0.0- 2.0 sec  59.2 MBytes   248 Mbits/sec   0.056 ms   52/42246 (0.12%)
[  3]  0.0- 2.0 sec  59.7 MBytes   250 Mbits/sec   0.028 ms    0/42553 (0%)
----------bandwidth 300
[  4]  0.0- 2.0 sec  71.7 MBytes   301 Mbits/sec   0.030 ms   55/51222 (0.11%)
[  3]  0.0- 2.0 sec  71.8 MBytes   302 Mbits/sec   0.024 ms   33/51282 (0.064%)
----------bandwidth 350
[  4]  0.0- 2.0 sec  83.8 MBytes   352 Mbits/sec   0.040 ms   87/59888 (0.15%)
[  3]  0.0- 2.0 sec  83.7 MBytes   355 Mbits/sec   0.018 ms  868/60606 (1.4%)
----------bandwidth 400
[  4]  0.0- 2.0 sec  95.6 MBytes   401 Mbits/sec   0.043 ms    5/68180 (0.0073%)
[  3]  0.0- 2.0 sec  90.2 MBytes   379 Mbits/sec   0.012 ms 4601/68965 (6.7%)
----------bandwidth 450
[  4]  0.0- 2.0 sec   105 MBytes   440 Mbits/sec   0.036 ms  369/75113 (0.49%)
[  3]  0.0- 2.0 sec  98.9 MBytes   415 Mbits/sec   0.013 ms 6388/76922 (8.3%)
----------bandwidth 500
[  4]  0.0- 2.0 sec   110 MBytes   460 Mbits/sec   0.031 ms   36/78302 (0.046%)
[  3]  0.0- 2.0 sec  99.5 MBytes   420 Mbits/sec   0.010 ms 15956/86956 (18%)
----------bandwidth 550
[  4]  0.0- 2.0 sec   110 MBytes   459 Mbits/sec   0.031 ms   22/78186 (0.028%)
[  3]  0.0- 2.0 sec   105 MBytes   440 Mbits/sec   0.008 ms 20359/95236 (21%)
----------bandwidth 600
[  4]  0.0- 2.0 sec   109 MBytes   456 Mbits/sec   0.034 ms    0/77709 (0%)
[  3]  0.0- 2.0 sec  90.7 MBytes   381 Mbits/sec   0.009 ms 40526/105254 (39%)
----------bandwidth 650
[  4]  0.0- 2.0 sec   109 MBytes   458 Mbits/sec   0.035 ms    0/77991 (0%)
[  3]  0.0- 2.2 sec  91.2 MBytes   340 Mbits/sec  15.658 ms 46033/111110 (41%)
----------bandwidth 700
[  4]  0.0- 2.0 sec   109 MBytes   458 Mbits/sec   0.034 ms  111/78120 (0.14%)
[  3]  0.0- 1.9 sec  82.6 MBytes   358 Mbits/sec   0.009 ms 66049/124997 (53%)
----------bandwidth 750
[  4]  0.0- 2.0 sec   110 MBytes   463 Mbits/sec   0.031 ms   62/78837 (0.079%)
[  3]  0.0- 2.2 sec  82.0 MBytes   311 Mbits/sec  15.645 ms 74847/133328 (56%)
----------bandwidth 800
[  4]  0.0- 2.0 sec   109 MBytes   458 Mbits/sec   0.029 ms   11/78013 (0.014%)
[  3]  0.0- 2.0 sec  75.1 MBytes   315 Mbits/sec   0.006 ms 88480/142033 (62%)
----------bandwidth 850
[  4]  0.0- 2.0 sec   109 MBytes   456 Mbits/sec   0.056 ms   10/77684 (0.013%)
[  3]  0.0- 2.2 sec  70.2 MBytes   262 Mbits/sec  15.214 ms 99717/149777 (67%)
----------bandwidth 900
[  4]  0.0- 2.0 sec   109 MBytes   457 Mbits/sec   0.032 ms   85/77943 (0.11%)
[  3]  0.0- 2.0 sec  69.4 MBytes   290 Mbits/sec   0.009 ms 100431/149932 (67%)
----------bandwidth 950
[  4]  0.0- 2.0 sec   108 MBytes   451 Mbits/sec   0.075 ms    0/76778 (0%)
[  3]  0.0- 2.2 sec  71.4 MBytes   266 Mbits/sec  15.250 ms 91053/142012 (64%)
----------bandwidth 1000
[  4]  0.0- 2.0 sec   108 MBytes   453 Mbits/sec   0.076 ms    0/77143 (0%)
[  3]  0.0- 1.9 sec  71.2 MBytes   311 Mbits/sec   0.029 ms 90616/141376 (64%)
From this, it’s pretty clear that the transmit throughput rises pretty linearly to ~450 Mbits/s and stays there. The receiver bandwidth scales linearly to ~400 Mbits/s and then starts losing ground as the rate increases. Also note that we don’t lose packets on the transmit side, only on the receiver side.

Cratering performance

Using UDP also exposed some issues on the boundary kernel. Using the boundary-before kernel, we see that the receive performance degrades as the bandwidth is increased past 400M. Note that this test has an updated bwtest.sh script that allows the test time to be set through the tsecs environment variable and the bandwidth increment to be set through incr.
root@linaro-nano:~# tsecs=2 incr=200 ./bwtest.sh 
----------bandwidth 200
[  4]  0.0- 2.0 sec  48.1 MBytes   203 Mbits/sec   0.061 ms  164/34479 (0.48%)
[  3]  0.0- 2.0 sec  48.3 MBytes   203 Mbits/sec   0.034 ms    0/34483 (0%)
----------bandwidth 400
[  4]  0.0- 2.0 sec  96.5 MBytes   405 Mbits/sec   0.040 ms   67/68911 (0.097%)
[  3]  0.0- 1.9 sec  93.9 MBytes   406 Mbits/sec   0.035 ms 1990/68965 (2.9%)
----------bandwidth 600
[  4]  0.0- 2.0 sec   110 MBytes   460 Mbits/sec   0.030 ms  234/78615 (0.3%)
[  3]  0.0- 2.3 sec   110 MBytes   410 Mbits/sec  15.672 ms 26703/105262 (25%)
----------bandwidth 800
[  4]  0.0- 2.0 sec   110 MBytes   461 Mbits/sec   0.033 ms    0/78511 (0%)
[  3]  0.0- 2.2 sec  2.91 MBytes  11.1 Mbits/sec  101.865 ms 140266/142342 (99%)
----------bandwidth 1000
[  4]  0.0- 2.0 sec   110 MBytes   461 Mbits/sec   0.033 ms    0/78383 (0%)
[  3]  0.0- 0.2 sec  90.4 KBytes  3.18 Mbits/sec  110.420 ms 141295/141358 (1e+02%)
This one took a while to find because it turned out to not be a code change between Blue Meany and our source tree, but a configuration change to enable a new driver API (NAPI). This API is is described on this web page. It is an architecture to decrease the interrupt overhead on high-performance networks. When enabled, the interrupt handler in the FEC driver schedules but does not process incoming packets. Instead, those are handled out of interrupt context. The change to our config file is trivial, but performance is much better at higher speeds as shown below:
----------bandwidth 200
[  5]  0.0- 2.0 sec  48.1 MBytes   203 Mbits/sec   0.063 ms  153/34482 (0.44%)
[  3]  0.0- 2.0 sec  48.3 MBytes   203 Mbits/sec   0.029 ms    0/34483 (0%)
----------bandwidth 400
[  4]  0.0- 2.0 sec  96.4 MBytes   404 Mbits/sec   0.052 ms  151/68888 (0.22%)
[  3]  0.0- 1.9 sec  85.5 MBytes   381 Mbits/sec   0.018 ms 7949/68965 (12%)
----------bandwidth 600
[  4]  0.0- 2.0 sec   109 MBytes   458 Mbits/sec   0.075 ms  269/78262 (0.34%)
[  3]  0.0- 1.9 sec   102 MBytes   447 Mbits/sec   0.007 ms 32747/105262 (31%)
----------bandwidth 800
[  4]  0.0- 2.0 sec   110 MBytes   461 Mbits/sec   0.090 ms    0/78464 (0%)
[  3]  0.0- 2.0 sec  82.2 MBytes   347 Mbits/sec   0.006 ms 84223/142847 (59%)
----------bandwidth 1000
[  4]  0.0- 2.0 sec   110 MBytes   461 Mbits/sec   0.072 ms  123/78698 (0.16%)
[  3]  0.0- 2.1 sec  70.6 MBytes   278 Mbits/sec  15.230 ms 91863/142251 (65%)
Note that there’s still a lot of loss at rates of 400M and above.

How to improve this

Where is that loss coming from? If we look at ifconfig we can see that the network driver is aware of the dropped packets:
root@linaro-nano:~# ifconfig eth0
eth0      Link encap:Ethernet  HWaddr 00:19:b8:00:fa:9a  
          inet addr:192.168.0.119  Bcast:192.168.0.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:3901387 errors:782502 dropped:0 overruns:782502 frame:782502
          TX packets:3775053 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:4178248807 (4.1 GB)  TX bytes:853327178 (853.3 MB)
The condition that increments the overrun count is here. Table 23-85 in the i.MX6DQ Reference Manual says that this means “A receive FIFO overrun occurred during frame reception”. The i.MX6DQ Errata document states in Errata ERR004512 that the maximum performance “is limited to 470 Mbps (total for Tx and Rx)”. The errata doesn’t say what the precise symptom of exceeding that limit might be, but this sure looks like it. The numbers above are pretty close to the 400Mbit/s reported in the errata. It turns out that we can do something about this. The Ethernet spec calls for a form of flow control using something called “pause frames”, which allows a receiver to tell a sender to back off for a quantum of time. That’s what this patch does. The very first part of the commit shows the addition of SUPPORTED_Pause to the phy device for i.MX6Quad and i.MX6DualLite processors. That part is key.

Sidebar: check out some other tools

Before we go too much further, we need to introduce a couple of key tools to understanding this. The first is a tool called ethtool. It is designed to allow you control the low-level functions of a network adapter. We’ll use it to see the state of the link negotiation. The second is a tool we developed named devregs. It is designed to allow access to device registers through /dev/mem. You can find details in this post. The post describes the use of the program on i.MX5x, but it’s perfectly happy to run on i.MX6 and we have a lot of registers defined in devregs_imx6x.dat. Let’s look at the output before and after the patch:

Before

root@linaro-nano:~# cat /proc/version
Linux version 3.0.35-2026-geaaf30e (b21710@bluemeany)
root@linaro-nano:~# ethtool eth0
Settings for eth0:
        Supported ports: [ TP MII ]
        Supported link modes:   10baseT/Half 10baseT/Full 
                                100baseT/Half 100baseT/Full 
                                1000baseT/Half 1000baseT/Full 
        Supported pause frame use: No
        Supports auto-negotiation: Yes
        Advertised link modes:  10baseT/Half 10baseT/Full 
                                100baseT/Half 100baseT/Full 
                                1000baseT/Half 1000baseT/Full 
        Advertised pause frame use: No
        Advertised auto-negotiation: Yes
        Speed: 1000Mb/s
        Duplex: Full
        Port: MII
        PHYAD: 6
        Transceiver: external
        Auto-negotiation: on
        Link detected: yes
root@linaro-nano:~# devregs ENET_RCR
ENET_RCR:0x02188084     =0x05ee0244

After

root@linaro-nano:~# cat /proc/version
root@linaro-nano:~# cat /proc/version
Linux version 3.0.35-2026-geaaf30e-02074-g92a9e1e ...
root@linaro-nano:~# ethtool eth0
Settings for eth0:
        Supported ports: [ TP MII ]
        Supported link modes:   10baseT/Half 10baseT/Full 
                                100baseT/Half 100baseT/Full 
                                1000baseT/Half 1000baseT/Full 
        Supported pause frame use: Symmetric
        Supports auto-negotiation: Yes
        Advertised link modes:  10baseT/Half 10baseT/Full 
                                100baseT/Half 100baseT/Full 
                                1000baseT/Half 1000baseT/Full 
        Advertised pause frame use: Symmetric
        Advertised auto-negotiation: Yes
        Speed: 1000Mb/s
        Duplex: Full
        Port: MII
        PHYAD: 6
        Transceiver: external
        Auto-negotiation: on
        Link detected: yes
root@linaro-nano:~# devregs ENET_RCR
ENET_RCR:0x02188084     =0x05ee0264
The key things to look at are the line that says “Supported pause frame use” and the line that shows the ENET_RCR register. Bit 5 of the ENET_RCR enables flow control (generation of pause frames) if set, and you can see that after the patch, flow control is enabled. Unfortunately, the situation is still much the same: The receive error numbers using bwtest.sh start rising and the bandwidth starts falling as we exceed 450 MBits/s.

Pause frames on TO1.0

The next patch in the series fixes this. It turns out that tweaking the default almost empty threshold on Tapeout 1.0 helps the situation, as does increasing the receive FIFO section full register. After applying this patch, we can see stable results when we overload the ethernet receiver. Note that we’ve also added a couple of lines to bwtest.sh to read the values of the ENET_IEEE_T_FDXFC and ENET_IEEE_R_MACERR statistics registers. These tell us how many pause frames were transmitted and how many receive FIFO overruns are seen.
root@linaro-nano:~# tsecs=2 incr=200 ./bwtest.sh 
----------bandwidth 200
[  4]  0.0- 1.7 sec  40.1 MBytes   203 Mbits/sec  50.557 ms  176/28804 (0.61%)
[  3]  0.0- 2.0 sec  48.3 MBytes   203 Mbits/sec   0.034 ms    0/34483 (0%)
ENET_IEEE_T_FDXFC:0x02188270	=0x00000d6c
ENET_IEEE_R_MACERR:0x021882d8	=0x00000000
----------bandwidth 400
[  4]  0.0- 2.0 sec  96.5 MBytes   405 Mbits/sec   0.043 ms  103/68952 (0.15%)
[  3]  0.0- 1.9 sec  90.0 MBytes   406 Mbits/sec   0.021 ms 4751/68965 (6.9%)
ENET_IEEE_T_FDXFC:0x02188270	=0x00001ad0
ENET_IEEE_R_MACERR:0x021882d8	=0x00000000
----------bandwidth 600
[  4]  0.0- 2.0 sec   110 MBytes   462 Mbits/sec   0.056 ms    0/78679 (0%)
[  3]  0.0- 1.9 sec   129 MBytes   583 Mbits/sec   0.061 ms 4750/96927 (4.9%)
ENET_IEEE_T_FDXFC:0x02188270	=0x0000f544
ENET_IEEE_R_MACERR:0x021882d8	=0x00000000
----------bandwidth 800
[  4]  0.0- 2.0 sec   110 MBytes   461 Mbits/sec   0.030 ms   92/78732 (0.12%)
[  3]  0.0- 2.0 sec   138 MBytes   580 Mbits/sec   0.062 ms   20/98693 (0.02%)
ENET_IEEE_T_FDXFC:0x02188270	=0x00000310
ENET_IEEE_R_MACERR:0x021882d8	=0x00000000
----------bandwidth 1000
[  4]  0.0- 2.0 sec   107 MBytes   449 Mbits/sec   0.060 ms  465/76969 (0.6%)
[  3]  0.0- 1.9 sec   129 MBytes   583 Mbits/sec   0.021 ms 4687/96830 (4.8%)
ENET_IEEE_T_FDXFC:0x02188270	=0x0000f482
ENET_IEEE_R_MACERR:0x021882d8	=0x00000000
Now that’s better! We’re seeing no FIFO overruns even up to 1G and a substantial increase in receive performance. Tapeout 1.2 shows even better performance, peaking at over 630 Mbit/s.

Final changes

The final two patches are really belt and suspenders updates. The first sets the Frame truncation receive length register so a FIFO error will not result in an extra long frame and spew error messages to the kernel log. The second treats frames with FIFO errors in the same way as framing errors and doesn’t forward them to the network stack for processing. We found that this increased performance in the presence of FIFO overruns.

Recap

We’ve uploaded the SD card image used in this testing so that you can repeat our results: If you format a single-partition SD card as ext3, you can extract it like so:
~/$ sudo mkfs.ext3 -L iperf /dev/sdc1
~/$ udisks --mount /dev/sdc1
... Assuming auto-mount as /media/iperf
~/$ sudo tar -C /media/iperf/ -zxvf imx6-iperf-test-20121214.tar.gz
~/$ sync && sudo umount /media/iperf
As mentioned earlier, this started off as a Linaro nano filesystem. We updated it to include a boot script, the devregs program and each of the kernels used in the tests above. The SD card image has each in the /boot directory. We encourage you to download the image, test it out on your boards and report back. Note that we haven’t yet updated the Android kernel tree, but will do that shortly. We’ll also be testing i.MX6 Solo, Dual-Lite, and the new SABRE SDB boards in upcoming days. Stay tuned to the blog for updates. If you’re using Gigabit ethernet, you’re likely to see improvements by adopting these updates.

Latest silicon revision for i.MX6

$
0
0
While testing Gigabit Ethernet as discussed in our last blog post, we found the first measurable differences between silicon revisions on the i.MX6.

It also came to our attention that we haven’t publicly discussed the chip revisions shipped on any of our i.MX6 boards to date.

As early adopters, most of our i.MX6 customers are in close contact with their Freescale representatives and have known the situation. Others have received answers by e-mail, but quite a number haven’t asked, and we haven’t said.

The situation is relatively simple:

  • Essentially all of the i.MX6Quad CPUs shipped before this week have contained i.MX6Q CPUs with silicon revision 1.0.
  • All i.MX6Quad boards shipped from today on will contain silicon revision 1.2.
  • All i.MX6Solo or i.MX6Duallite processors we’ve shipped to date have silicon revision 1.1.
If you’re running our latest U-Boot, you can see the silicon during boot as shown below:

U-Boot 2013.01-rc1-02388-ga90f257 (Nov 27 2012 - 14:02:30)
CPU:   Freescale i.MX6Q rev1.2 at 792 MHz
...
As mentioned earlier, the first measurable difference we’ve seen between these chip revisions has been the improved Ethernet receive performance on i.MX6Quad Tapeout 1.2.

Please refer to the Freescale i.MX6 site for a detailed list of updates on the processor. There were quite a number of updates and whether any of them is meaningful in your application depends a lot on how you’re using the parts.

i.MX6 options (single, dual core, 2GB DDR)

$
0
0
If you’ve been paying attention to our U-Boot or Linux kernel trees, you’ve probably seen updates adding support for the single and dual-core (Solo, Dual-Lite, and Dual) variants of the i.MX6 processor. You may also have seen support for 2GB DDR configuration.

We’ve had these variants up and running in the office for the last 6 months, but haven’t yet tied a string around the source code releases, so we’ve only let a handful of lucky customers have early access.

We’re still a bit early to announce general availability and standard SKUs, but we are building small numbers of both Nitrogen6X and Nitrogen6X-SOM with variations for customer testing. Contact us to purchase any of these variants for evaluation or production.

If you haven’t done so already, you should check out the i.MX6 series fact sheet for the details of the differences between models. The breadth is very impressive. Some of the highlights include:

 SoloDual-LiteDualQuad
# Cores1224
Cache512 KB512 KB1 MB1 MB
Memory bus32-bit64-bit64-bit64-bit
3D Graphics1 shader1 shader4 shaders4 shaders
2D Graphicsx1x1x2x2
SATA  SATA-IISATA-II
We’ll be announcing general availability of both U-Boot and the Linux kernel for single and dual core configurations in the coming weeks. Subscribe to our blog if you want to receive notifications.

Our testing shows that even the low end of this processor family has outstanding performance, and it may be worthwhile to see how your applications perform with one or more of the variants.

Playing multiple HD videos on i.MX6

$
0
0
This is just a quick post with some details of some gstreamer-fu to decode and play back multiple HD videos using the VPU hardware acceleration on the i.MX6. The command-lines below use the mfw_isink gstreamer element to display the output from the 1920×816 Kung Fu Panda trailer from pocketmovies.net into three windows on a display configured at 1080P.

The only real trick to this is setting the display-width, display-height, axis-top, and axis-left parameters. For what it’s worth, this was tested on our LTIB-No X userspace.

Window 1 at 0:0

root@boundary ~/$ gst-launch filesrc location=kungfu.flv \
        ! 'video/quicktime' \
        ! aiurdemux name=demux demux. \
        ! queue max-size-buffers=0 max-size-time=0 \
        ! vpudec \
        ! mfw_isink disp-width=960 disp-height=408 demux. \
        ! queue max-size-buffers=0 max-size-time=0 \
        ! mfw_aacdecoder ! audioconvert \
        ! 'audio/x-raw-int,channels=2' \
        ! alsasink

Window 2 at 960:480

root@boundary ~/$ gst-launch filesrc location=kungfu.flv \
        ! 'video/quicktime' \
        ! aiurdemux name=demux demux. \
        ! queue max-size-buffers=0 max-size-time=0 \
        ! vpudec \
        ! mfw_isink axis-top=408 axis-left=960 disp-width=960 disp-height=408 demux. \
        ! queue max-size-buffers=0 max-size-time=0 \
        ! mfw_aacdecoder ! audioconvert \
        ! 'audio/x-raw-int,channels=2' \
        ! alsasink

Window 3 at 0:672

root@boundary ~/$ gst-launch filesrc location=kungfu.flv \
        ! 'video/quicktime' \
        ! aiurdemux name=demux demux. \
        ! queue max-size-buffers=0 max-size-time=0 \
        ! vpudec \
        ! mfw_isink axis-top=672 axis-left=0 disp-width=960 disp-height=408 demux. \
        ! queue max-size-buffers=0 max-size-time=0 \
        ! mfw_aacdecoder ! audioconvert \
        ! 'audio/x-raw-int,channels=2' \
        ! alsasink
Note that audio blending from the three videos also just works.

I know this begs for a video, but it’s late in the day and we thought this might be useful.

Cross compile i.MX6 kernel using LTIB toolchain

$
0
0
Again, this may be old hat to many, but here’s a quick how-to on getting and cross compiling a kernel from our Github kernel repository.

~/$ git clone git://github.com/boundarydevices/linux-imx6.git
~/$ cd linux-imx6
~/linux-imx6$ export PATH=/opt/freescale/usr/local/gcc-4.6.2-glibc-2.13-linaro-multilib-2011.12/fsl-linaro-toolchain/bin/:$PATH
~/linux-imx6$ export ARCH=arm
~/linux-imx6$ export CROSS_COMPILE=arm-none-linux-gnueabi-
~/linux-imx6$ git checkout origin/boundary-imx-3.0.35_1.1.0 \
        -b boundary-imx-3.0.35_1.1.0
~/linux-imx6$ make nitrogen6x_defconfig
~/linux-imx6$ make uImage module
The output will be placed in ~/linux-imx6/arch/arm/boot/uImage.

If you’ve build any drivers as modules, you’ll generally want to install them into /lib/modules/kernelversion/.... You can use the INSTALL_MOD_PATH variable and the modules_install to install them to a temporary location as follows. Note that before copying them to an SD card or filesystem image, you’ll generally want to kill the link back to the source directory, or you’ll copy 100s of MBytes of source code and increase your disk image size.

~/linux-imx6$ make INSTALL_MOD_PATH=~/tmp modules_install
~/linux-imx6$ find ~/tmp/lib/modules -type l -exec rm -f {} \;

U-Boot updates for i.MX6: Single core, Dual core, 2GB DDR

$
0
0
To follow up on our announcement of single-core, dual-core, and 2GB options on our Nitrogen6X boards, we’ve just pushed a set of code updates to the staging branch of our U-Boot GitHub repository.

The details were also sent to the U-Boot mailing list, but only as Request For Comment until we figure out how best to merge multi-CPU code into the main-line code base.

In the meantime, these patches have undergone fairly thorough testing and are ready for field tests. If you have one of these boards, please give the code base a spin when you have a chance. For that matter, if you have a standard i.MX6Quad board with the standard 1GB of DDR3, we encourage you to test the code base as well. We’ll likely begin shipping boards with this code base for all devices in the next couple of weeks.

Updates to the build process

The build process has changed in a minor way. Instead of nitrogen6x_config, you’ll need to select from this list:

ProcessorDDRConfiguration
i.MX6Quad/Dual1GBnitrogen6q_config
i.MX6Quad/Dual2GBnitrogen6q2g_config
i.MX6Dual-Lite1GBnitrogen6dl_config
i.MX6Dual-Lite2GBnitrogen6dl2g_config
i.MX6Solo512MBnitrogen6s_config
i.MX6Solo1GBnitrogen6s1g_config


So, to compile for an i.MX6Solo processor with 512MB of RAM, the build process will be this:

user@build:~$ git clone git://github.com/boundarydevices/u-boot-imx6.git
Cloning into 'u-boot-imx6'...
remote: Counting objects: 200078, done.
remote: Compressing objects: 100% (36179/36179), done.
remote: Total 200078 (delta 161056), reused 199999 (delta 160995)
Receiving objects: 100% (200078/200078), 50.96 MiB | 1.63 MiB/s, done.
Resolving deltas: 100% (161056/161056), done.
user@build:~$ cd u-boot-imx6/
user@build:~/u-boot-imx6$ git checkout origin/staging -b staging
Branch staging set up to track remote branch staging from origin.
Switched to a new branch 'staging'
user@build:~/u-boot-imx6$ export ARCH=arm
user@build:~/u-boot-imx6$ export CROSS_COMPILE=arm-none-linux-gnueabi-
user@build:~/u-boot-imx6$ make nitrogen6s_config
Configuring for nitrogen6s - Board: nitrogen6x, Options: IMX_CONFIG=board/boundary/nitrogen6x/nitrogen6s.cfg,MX6S
user@build:~/u-boot-imx6$ make all
Generating include/autoconf.mk
Generating include/autoconf.mk.dep
...
make -C examples/api all
make[1]: Entering directory `/home/user/u-boot-imx6/examples/api'
make[1]: Nothing to be done for `all'.
make[1]: Leaving directory `/home/user/u-boot-imx6/examples/api'
user@build:~/u-boot-imx6$ ls -l u-boot.imx
-rw-rw-r-- 1 user user 315128 Feb  1 12:41 u-boot.imx
Note that all of the configurations generate u-boot.imx as their output and they’re all programmed to offset 0×400, so the upgradeu command will work as on previous builds.

Boot scripts

No modifications are needed to boot scripts in order to use this release.

Kernel and userspaces

All of our current kernels contain support for each of these processor variants:

We’ve tested these against Timesys, LTIB, and Yocto userspaces. We’ve not yet tested Android on single processor or dual processor boards.

Viewing all 391 articles
Browse latest View live