Wednesday, June 30, 2010

U-Boot: PXA SDHC support

Today, it'll be just a quick entry about a recent achievement in the U-Boot land. I was reported by some people from the Zipit Z2 project that U-Boot doesn't detect their SDHC cards. That was really troublesome and so was the state of the pxa_mmc driver in U-Boot.

Actually, pxa_mmc was probably the last SD/MMC driver in U-Boot that used the old driver interface there. I decided it needs a rewrite. I based the new code on the Linux version of pxa_mmc driver. The resulting pxa_mmc_gen.c now uses the generic SD/MMC framework in U-Boot and the code is much more cleaner. It also supports SDHC well. And one more benefit is that the timing issues that were observed with the old driver are gone now.

The code wasn't merged mainline yet and is currently held as a separate driver to make the transition from the old driver to the new one as smooth as possible. Also, I'd like the driver to get some testing before some other boards are converted to use it.

The code is currently available in the u-boot-pxa.git -devel branch. Also, it was submitted to the u-boot mailing list. To enable the new driver, you'll have to replace

And recompile the U-Boot.

To use the new driver, you can use commands like:
$ mmcinfo
$ fatls mmc 0

etc. Note, that the "mmcinfo" command is new and the old "mmc" command class is gone. So no "mmc init" anymore.

Monday, June 21, 2010

OpenPXA: first release

The OpenPXA project proudly released first beta version of the bootloader package for PXA3xx. The package supports the following boards:
  • Toradex Colibri PXA300
  • Toradex Colibri PXA310
  • Toradex Colibri PXA320
  • Marvell Littleton PXA310
The software is labeled "beta" because there still might appear problems that we are unaware of.

The package contains the OpenPXA OBM2 and U-Boot bootloader binaries for the boards as well as installation instructions. The package can be downloaded from the OpenPXA website.

Zaurus hacking

Just a quick update on the problems I described on Zaurus. I've been hacking a little bit further into it and figured there's a problem in PCMCIA. Actually, there was always a warning in the pxa2xx_base.c stating that the timing recomputation for the PCMCIA devices is based off the CPU core frequency and that's probably wrong. I changed this and based the timing off the CPU bus frequency, which fixed one of the problems with Zaurus. It fixed the problem where at 312MHz the harddrive died. The other problem with weird lines on the LCD still persists, though not in such a big scale.

On the other hand, the LCD problem now appears even on 416 MHz which makes me think the PCMCIA timing recomputation has some other bug. Maybe, the timing is now too tight so the PCMCIA device takes too much bus bandwidth, triggering the LCDs FIFOs underruns.

There is one more thing that brings me to that conclusion, that is, when I ran a hdpart -T /dev/sda on the harddrive attached to PCMCIA, I got the following results:

FrequencyRead speed without fixRead speed with fix
416 MHz8 MB/s12 MB/s
208 MHz2 MB/s4 MB/s

Thursday, June 17, 2010

Recent XScale hacking

About a month passed since my last post so it's probably time for a recap. The last month was again very busy and the number of platforms that undercame changes overgrew the size of the header for this entry. For starters, let's just say that even the always so popular and beloved Zaurus got some cosmetic changes. There were also some changes in the PXA3xx land and the ZipitZ2 land wasn't left intact either.

The first turning point on this platform was a release of the U-Boot bootloader update kit for public testing. Some people installed this and reported me various bugs. There was for example a grave typo in the new U-Boot macros for pxa2xx which made wake-up from suspend-to-mem impossible. That was easily located and fixed right away. The new version of update kit was obviously uploaded very fast. Actually, there were no more bugs reported since then.

The only drawback is that U-Boot doesn't support booting from SDHC cards, only SD and MMC are supported. This can be easily worked around by flashing the kernel into the NOR to an address 0x60000. In case the U-Boot bootloader is unable to either detect a card or find a script on the card, it boots the kernel from the 0x60000 location.

The other changes related to ZipitZ2 happened within the Linux kernel. Firstly, the NOR flash layout was standardized. It is incompatible with the old layout, though on the other hand, now there are strict rules on how the NOR flash layout will look and no more anarchy will take place. The final layout is like this:
  • 0x0-0x40000 -- U-Boot bootloader
  • 0x40000-0x60000 -- U-Boot environment
  • 0x60000-END -- Linux kernel or possibly some small filesystem
I was also reported a bug in the screen blanking on ZipitZ2. Not long ago, Alberto Panizzo wrote a driver for his LCD based on my LMS283GF05 driver (the LCD in ZipitZ2). Though back when I wrote this driver, I made a mistake and screen blanking wasn't working correctly. Sadly, the same mistake got into the new driver by Alberto as well. I therefore sent a patch for both of the drivers.

In the end, I must not forget to mention, that the WM8750 codec is now finally registered in the platform definition file for both ZipitZ2 and Sharp Zaurus/Spitz. This brings the conversion of the WM8750 codec which I started before the 2.6.34 was out to an end.

Income SBC
In one of the older entries here, I mentioned I got my hands on the Income SBC and that my patch started some discussion in the Linux-ARM kernel mailing list. Just to explain what this Income SBC device is, it is a custom-made board with a LCD which is powered by the Toradex Colibri PXA270 module. The conclusion of the discussion was so that we need to separate the board support code from the module support code.

A friend of mine, Daniel Mack, took the Income SBC patch and the Colibri PXA270 code and did the split, which was very helpful. Before the split, I sent a pile of patches which added support for various devices on the Toradex Colibri PXA270 module/baseboard as the support was quite incomplete in mainline.

Sharp Zaurus
Just recently, a friend of mine, Metan, was complaining that the LCD screen on his Sharp Zaurus goes crazy when he uses the mainline Linux kernel and changes frequency of the CPU with CPUfreq to just about anything but 416MHz. He also complained, that if he changes the frequency to 312MHz, the harddrive in the machine fails. He lent me the machine for a while with an explanation on how to boot kernel on it.

It didn't take long and I came up with a first patch. That was actually just a cleanup. The Zaurus support code in mainline Linux kernel was in a terrible state. The first patch therefore only improved the readability of the code. Actually, there was also a minor revamp of the CF/SD power control function. All in all, the patch was pretty much a complete rewrite of the file.

Then, there was another patch. The Zaurus contains an Intersil ISL6271A PMIC for the CPU. Even before I got my hands on the Zaurus device, I implemented a driver for it and asked Metan if he can test it. Well in the end, he lent me the Zaurus instead. The initial version of the ISL6271A driver contained bugs, but after about three revisions of the patch, the driver was clean and was applied to the regulator tree.

There was still the LCD going crazy though. I discussed this with Eric Miao and he explained to me, that the CPU bus probably isn't capable of transferring so many data and therefore the LCD FIFOs underrun. I checked this by enabling the Input and Output FIFO Underrun interrupt in the PXAFB driver. And bingo, the underruns really happened. This means there is either something, that consumes the bus bandwidth or the bus is simply slow. I also tested some other kernels which supported CPUfreq and noticed the issues was there as well. Sadly, I wasn't able to get CPUfreq working with a stock Zaurus ROM.

Also there is still a lingering issue with the harddrive and 312MHz CPU speed. This will need further investigation. It'll probably involve the Sharp SCOOP chip and PCMCIA drivers undergoing a rewrite.

Apparently, the popularity of the OpenPXA project is rising. I assume this from a fact that I get more requests for help and bug reports. There were some that helped the project greatly, even if there was no patch included with them. What's even better is the project actually gets testers and that really helps.

The first important bug report that arrived was from some person from HCLTech. He had issues with saving the U-Boot environment into the NAND on the Marvell Littleton PXA310 board. The whole problem was that the size of the environment sector differed from the size of NAND block and the U-Boot MTD subsystem can only write whole blocks. Also, the environment position wasn't aligned to block boundary.
That was quickly solved and a patch was applied on top of u-boot-pxa, openpxa branch.

Though he then wanted to do a TFTP boot and figured out the ethernet chip doesn't work in U-Boot. This took some further investigation. I figured out, that if I flash a Marvell BBU into the board and execute U-Boot from it, the ethernet magically works. I dumped various interesting registers from this setup and bisected the one which caused the problems with ethernet. The most funny part that the problem was caused by a bit marked as "SETALWAYS" not being set. Apparently, these bits marked as "SETALWAYS" mean something Marvell doesn't want other people to know. Obviously, armed with this knowledge, I fixed the ethernet and applied a patch.

The other batch of problems came from a guy owning a Colibri PXA320 board. He complained that he can't even boot a kernel from U-Boot. I figured this issue was only there if the kernel was compiled with a built-in initramfs. In the end, it was fixed by a quick patch. The problem was a mess in the RAM base addresses. It's an agreement in Linux-ARM, that the RAM on XScale starts at 0xa0000000. On PXA3xx though, the RAM is mirrored from 0x80000000 to 0xa0000000 by default for compatibility reasons. The U-Boot contained mess in this and both of these 0x80000000 and 0xa0000000 addresses were used. Unifying these addresses to 0xa0000000 fixed the problem.

Furthermore, this person complained, that the Colibri PXA320 board doesn't support USB device mode in Linux. A quick hack fixed that and patch already hit LAKML. With this guy happy and not considering buying a very expensive BSP from a certain corporation, I could have taken a rest. Though, I noticed some things worth fixing in U-Boot for this board along the way. I fixed the ethernet support on the Colibri PXA320 board in U-Boot and added USB host support.

This is still not all though. I mentioned in one of the older entries, that I got those Marvell Zylonites. I decided to take a look at those, particularly on the one with PXA320 C0 CPU. Firstly, I figured the CPU contains BootROM v3.38. This was a big surprise as this implies the CPU supports the NTIM header. Furthermore U-Boot apparently supported this board, but with the ongoing changes in the U-Boot bootloader, the platform was broken. I therefore took it and rewrote it from scratch, reusing just some of the static memory controller configuration values from it. The U-Boot works just fine. There is still a problem with this board though.

With the Zylonite320, I decided to try a new approach. I pushed all of the low-level init into the OpenPXA OBM2. I also implemented a DDR DRAM initialization code in the OBM2. This should in the end allow me, to totally skip and remove lowlevel_init.S in U-Boot. With just a few tweaks in the OpenPXA OBM2 and the NTIM header, I managed to get this working on the Zylonite320 as well.

And now to the problem. The expected behavior would be that if a power supply is attached to the device, it'd power up and U-Boot will come up. For some unknown reason, this doesn't happen on the Zylonite320. The only way I was able to get the Zylonite320 boot from NAND was to issue a "reset run" in the OpenOCD shell over JTAG. Then the board booted, no problem. I was slightly investigating this with a Marvell XDB and figured the NFC is maybe misconfigured in a way the NAND is detected as x16 instead of x8 by the BootROM. Though maybe there are just some switches that toggle the boot-up behaviour of the CPU.

This month was quite rich in finishing conversions. Not only was the WM8750 conversion finished, but also the final removal of wm97xx_batt.h happened. The file was lingering in the kernel tree for about a year now, to be accurate ever since it was possible to pass platform data through the AC97 bus. So now the file is gone and all the platforms that used this file are now fixed.

In the end, I must not forget I got into a little fight with Russell King. We exchanged a few rough mails etc. Also, if I mention Pavel Machek was involved, I believe no further explanation is necessary. Actually, I was only teasing Russell a bit, but he probably took it personally.

I hope you enjoyed the reading, it was quite a lot of boring text as always.