Sunday, December 13, 2009

OpenOCD: PXA3xx NAND flash driver

Just a quick entry today. Recently, I was hacking on a PXA3xx NAND flash support for OpenOCD. It's finally ready, though it has a few limitations. The preliminary version is available in the OpenPXA GIT as always, though the patches are being pushed into mainline OpenOCD. The limitations mentioned before are that you can't erase multiple blocks as once, you have to do it one after another for now. Also, this driver for now works only for large block devices, but adding support for small block ones should be easy. And the driver is quite slow too, so it's probably only useful for flashing in the bootloader.

A quick howto on reflashing the bootloader using the NAND code in OpenOCD follows:
  • run OpenOCD with the following command: openocd -s tcl -f board/colibri_pxa320.cfg -f interface/jtagkey.cfg (for Colibri/PXA3xx board and Amontec JTAGkey)
  • connect to OpenOCD using telnet: telnet localhost 4444
  • Issue the following commands, one after another:
    • reset halt
    • nand probe 0
    • nand erase 0 0x0 0x20000 ; nand erase 0x20000 0x20000 (erase first two blocks)
    • nand write 0 bootloader.img 0x0
  • To read data from NAND, use: nand dump 0 dump.img 0x0 0x800 (0x0 is base address, 0x800 is amount of bytes)

Sunday, November 29, 2009

Colibri/PXA320 meets OpenOCD, becomes free

In the last blog entry, I mentioned getting a development kit. It's cool and all, but as the Colibri/PXA320 and other PXA3xx boards, it has one really bad flaw -- all of the flashing tools for PXA3xx are for certain proprietary OS only. Moreover this particular overly proprietary debugger/flasher I got with the board was so choosy about adapters it supported it really went on my nerves badly especially since the adapter I got was not working properly and I couldn't use any other of those I had. So there was no way to reflash PXA3xx boards from Linux ... until recently.

I took a look at OpenOCD project, which is a Free Software JTAG Debugger, and figured it'd be actually quite simple to update it to support PXA3xx by looking into the PXA3xx documentation and comparing it with PXA2xx one. Apparently, the only differences there were the Instruction Length (which was 7 for PXA2xx and 11 for PXA3xx) and - the more weird change - that PXA3xx has the instruction codes shifted by 4 to the left in some cases. After fixing these, I was able to connect to the CPU using my FTDI FT2232 based fake-amontec JTAG cable and operate with it normally. The patches are available in the OpenPXA GIT.

Maybe someone would like to see a howto for loading new software into the board using the OpenOCD, so here it is. Firstly, download the OpenOCD patches from OpenPXA GIT and do:
  • git clone git:// # download OpenOCD sources
  • cd openocd # enter the OpenOCD directory
  • apply OpenPXA patches for OpenOCD
  • ./bootstrap # prepare files necessary for OpenOCD compilation
  • ./configure --enable-maintainer-mode --enable-ft2232_libftdi # the first option is necessary (dunno why), the other one enables support for the ft2232-based cables
  • make # compiles OpenOCD
  • ./src/openocd -s tcl -f board/colibri_pxa320.cfg -f interface/jtagkey.cfg # executes the OpenOCD debugger; tells it to search for configuration scripts in directory tcl, to use colibri_pxa320.cfg board support file and jtagkey.cfg cable support file
  • telnet localhost 4444 # connect to the OpenOCD
Once connected using the telnet, we can start issuing commands. We'll want to load a program to a particular location in SRAM:
  • reset halt # reset the CPU and stop executing instructions
  • fast_load_image /path/to/file 0x5c080000 bin # prepare to load binary file to address 0x5c080000 (NOTE: 0x5c080000 is valid SRAM only for PXA320, for other CPUs use 0x5c000000 or something)
  • fast_load # actually upload the file
  • resume 0x5c080000 # continue instruction execution at address 0x5c080000 (about the address used, see previous note)
And now that you can load a file into SRAM and execute it, you can use this technique to load a bootloader there and control it over UART or something. Once you succeed in running the bootloader, you can do whatever you want with the hardware (for example flash the bootloader into NAND).

Tuesday, November 10, 2009

Colibri/PXA320 Ethernet, OpenPXA IPL v2.0 and UCB1400

Just a quick summary to keep possibly interested people in the loop today. I got the ethernet working on the Colibri/PXA320 board in u-boot. The problem was with the way the ax88796 driver was accessing the registers of the ethernet chip. It was actually accessing them in some weird 16bit mode, which caused two registers to be read at one time and the contents of the upper one was sometimes lost, caused malfunction of the driver. So I supplied my own access functions the same way as some Renesas board did and that eventually fixed the issues. Now the ethernet controller is working happily.

I recently started working on making the OpenPXA IPL more generic in preparation for supporting more devices. As I explained in an earlier post, the NAND is configured to some sane defaults and some of it's characteristics are determined by the BootROM already when the IPL is being executed. So I make use of this information and don't reconfigure the NAND, but just reset the chip and do READ0 and READYREAD commands. Also, I'm working on cleaning up the code and fixing some of it's possible issues.

Moreover, I plan to add debugging functionality into the IPL, which would probably allow the user to load some code into SRAM through serial console (XMODEM possibly or something) instead of NAND as it's now. Such thing will eventually allow the user to restore pretty much any system without NAND page number 0 being wiped out.

And the last thing today is about the UCB1400. I sent a patch upstream, that allows the UCB1400 to accept touchscreen IRQ GPIO through platform data. I also explained the reason for this in the previous post so read it there.

Saturday, November 7, 2009

Recent happening - PXA3xx, u-boot etc.

I just want to write some sum of what happened since last time I posted something here as stuff actually pretty piled up and I'm overly busy now. Expect somehow longer entry as quite a bit happened actually.

All this machinery started back in late September, when I got a Toradex Colibri carrier board with a PXA320 CPU card from INCOME s.r.o. and was instructed to prepare a decent bootloader for it and possibly make Linux kernel run smoothly on it. Sure, sounds easy, it's a Marvell CPU afterall and U-Boot already has some support for a few boards with PXA3xx too. Moreover, it's not too different from PXA2xx series, right? Yes sure, it's not, but there are a few changes.

I was suffering for some time, trying to make use of the preinstalled EBOOT bootloader to load Linux and even wrote some wrapper so it loads the kernel correctly at least, but I gave up on this idea as it turned out EBOOT is a worthless piece of crap. Not to mention, EBOOT is a proprietary goo. So I figured I need to replace it. U-Boot was the only choice here of course, but here came the first difference between PXA2xx and PXA3xx. The PXA3xx CPU does not need a NOR flash to boot from, it can boot directly from the NAND flash. Actually, there is something called BootROM buried in the CPU as I figured out later, but it's not possible to read it's contents without electron microscopy I think. Well this BootROM apparently configures the NAND properly, copies it's first sector to SRAM and executes it. But here popped in another problem, I managed to overwrite the first sector with not working code rendering the board unusable. Sadly, there is no utility for Linux that can flash the PXA3xx board so I had to use their proprietary one to reflash the board.

After numerous reflashes and testing, digging through the bootloader images Toradex released publicly and analyzing them, I managed to put together an open source GPLed IPL (initial program loader) that can be stored in the first sector of NAND with a sole purpose of loading further sectors from NAND, copying them to SRAM and then jumping to the beginning of these copied data. For this IPL, I established the OpenPXA project hosted on SourceForge as the plan is to extend it's support to other boards as you'll figure out later. Well, the data I mentioned a while ago that are being copied and executed are actually U-Boot. Maybe you are asking -- why is it so complicated. That's because the BootROM can apparently load only the first sector from NAND, the rest has to be done by the IPL, that's how the chip is.

Back to the U-Boot. There was one more obstacle I had to fight, it was the RAM. The PXA3xx supports DDR DRAM besides some other types of DRAM and the hardware I have has the DDR DRAM. That's why I had to write the initialization routine, which soon turned out to be one hell of a hard work to be done properly. As a side story, I made a decision to stick most of the hardware initialization into the U-Boot and keep the IPL size to the minimum. That's also why the IPL is loading the U-Boot into SRAM, to avoid initializing the DRAM controller.

After all this suffering, the current status of U-Boot for the Colibri/PXA320 is such that it's usable to boot Linux from MMC or NAND, the CPU is properly configured, DRAM works just fine. There are still a few problems though. The most noticable one is that the NAND can't be written from U-Boot, but I suspect that's because of a GCC bug that produces wrong code causing the U-Boot to hang. The other problem is that the ethernet adapter doesn't work in U-Boot, but that's being worked on now. It actually works from Linux so that's not much of a problem. Just as a side note, I sometimes update the patches for U-Boot in the OpenPXA git so if you are interested, you can find them there.

Mentioning GCC bugs, let me warn you that you should not even try compiling U-Boot with >= GCC4.3. It produces weird code and makes the U-Boot not work properly, like unexpectedly hang and such. I tried fixing some of those issues in U-Boot, but there are still many so stick with GCC4.2 for the time being. The exceptionally nasty one was with 64bit division. In the end, I ripped the code for 64bit division from Linux kernel and stick it into U-Boot, but that's more like a workaround.

Before I disclose my future plans with U-Boot on PXA3xx, I first need to explain why I'm so into it probably. That's because somewhere along the process of fixing U-Boot, I made some negotiations with a certain corporation that makes CPUs and such (I'm not sure if I can disclose anything more here, sorry) and was supplied some hardware to hack on. So that's why I'm sticking very closely to this and why I'm investing such a load of my time to this low-level stuff. Also I have to say, the people I communicated with so far are awesome and I like it the way it is.

So to the plans I have with the IPL and U-Boot. Firstly, I'll have to hack on the IPL a bit to make it support PXA310, Monahans LV CPU. Then there was an idea to use the values from BootROM to auto-configure the NAND in the IPL and possibly even later in U-Boot and Linux, which is awesome as the NAND will be technically auto-detected and we won't have to care for it much. Next of course will be fixing of the ethernet on the Colibri/PXA320, ok, maybe this will be first as I'm getting close here. What I'd also like to have working is the USB host in U-Boot so the thing can also boot from an USB thumb-drive or something.

Besides these plans with IPL and U-Boot, I have an idea that there needs to be an improvement made in the Linux kernel concerning the UCB1400 chip driver which is integrated on the Colibri/PXA320 module. This improvement would make use of the recently merged possibility of passing platform data through the AC97 bus. Let me explain properly. I recently got an email from someone that the pseudo-auto-detection routine which somehow should detect the proper touchscreen IRQ GPIO for UCB1400 doesn't work on his hardware. Well that sucks and it was unavoidable anyway I think. So this patch would pertain to removal of this routine altogether and modifying all the platforms that use the UCB1400 driver to supply the touchscreen IRQ GPIO as AC97 bus platform data. There are just two or three such platforms so it's not much of a problem anyway.

Well this is about it, life was pretty busy recently and the article actually grew quite long, sorry to hold you here for so long. I hope you enjoyed your stay at least.

Saturday, August 22, 2009

OmniVision OV9640 hacking - part IV

I recently had some talk with Guennadi Liakhovetski (aka. the soc-camera maintainer and v4l2 guru) about this driver. He pointed out that there will certainly be a large amount of changes going into 2.6.32 affecting the soc-camera API and advised me to prepare the driver for those. Besides that, we found out there are certain differences between OV9640 and OV9650, so support for the later one was dropped (it was never tested anyway). For that model there's another driver scheduled for merge written by Stefan Herbrechtsmeier. Subsequent changes are mostly because of the API change. There are also some minor cleanups and changes in logic of the driver.

The patch got split into three separate patches, but prior to applying those, you need to apply a patchset available here (LINK) on top of linux-next (in case you run into merge issues, git reset --hard to commit hash in 0000-base) . The OV9640 patches are then available here:
  • Patch adding support for RGB555X and RGB565X formats into pxa-camera (LINK)
  • OV9640 support adding patch (LINK)
  • Patch adding support for the camera into PalmZ72 platform file (LINK)

Friday, August 21, 2009

Marvell Libertas CF8305 partly supported

So after my own private hackathon I held for last two weeks and where OpenBSD gained support for Palm hardware to some extent, I felt the urge to fix some hardware to work with Linux. And there was a perfect candidate for that, the WiFi card in Palm LifeDrive. That damn little piece of silicon bothered me for more than two years already, but just a few hours ago, I cracked the nut there at least.

The Marvell Libertas CF8305 is actually a very ancient piece of silicon and runs Marvell proprietary firmware version 3.0 . Being this old, the card has various issues which later models (like CF8381 and CF8385) do not have. The first difference from the later models is that this card runs only an one-stage firmware, but that's luckily loaded the same way as a helper firmware on the later models. The second-stage firmware isn't loaded at all on this card.

Next issue on the list happens when accessing registers of the card. It seems the card can not do an unaligned accesses to it's registers which means the driver has to access only odd addresses. Accesses to even addresses doesn't work - in case of reading the returned value is the one of the nearest lower odd address. But luckily, there is only one such unaligned access happening in the whole if_cs.c part of the driver and that is when reading the SCRATCH_PAD register which has address 0x3F . And this can be easily worked around by doing a 16bit read of address 0x3E and bit-shifting the result by 8 to the right.

This was the easy part, but the horrible bugs are still waiting. Apparently, with the first problem fixed, the firmware can be loaded and the card seem to respond to some commands, so far so good. What the card really does not like though is a command with code 0x0006 aka. CMD_802_11_SCAN. Once that command is sent to the card, the card plain hangs and all you can do is remove the driver, eject the card and reinsert it (there's no hardware eject so use 'pccardctl eject' and 'pccardctl insert'). The real problem here is, once the card is brought up (for instance by 'ifconfig eth0 up', the driver itself issues the SCAN command - or at least that's what it does when configured into Ad-Hoc mode. This can be worked around by editing 'drivers/net/wireless/libertas/scan.c' and commenting out 'ret = __lbs_cmd(priv, CMD_802_11_SCAN...);' at around line 333.

With the hack above, it's possible at least for the card to serve as a node in an Ad-Hoc network. But that's not the last limitation it has. It's impossible for now to reconfigure the card once brought up. Since in case you do that, the command 0x002b aka. CMD_802_11_AD_HOC_START will fail and again hanging the whole card.

Other than that, if the card is configured by 'iwconfig' and then brought up by 'ifconfig', it seems to be possible to establish at least the Ad-Hoc network. Well there are still some very hard limitations, but at least there are some signs of life from the card and it can't get any worse now.

Here's the patch for the if_cs.c file: LINK
And here's a picture of a working WiFi on Palm LifeDrive:

Friday, August 7, 2009

OmniVision OV9640 hacking - part ]|[

I spent the last few days tracking down some really weird issues with the OV9640 driver. The major problem was a bright stripe, exactly 90px from the top of the photo. But it only occurred on photos in 640x480 and lower resolution. Also, there were other problems like brightness too dim in certain resolutions, swapped colors, i2c glitches etc. Interestingly enough, I haven't met such issues at the 1280x960 resolution.

The bright stripe was in the end caused by the camera not being ready right after reconfiguration. A little delay pretty much solved it, but it might need some further investigation still. Tinkering some more with the chips' registers, I also managed to eliminate most of the color-swap related problem as well as improve overall image quality.

But then there was that i2c problem. It was pretty hard to even notice it since writing the chip registers worked. The problem popped up when I tried reading the registers back though. It returned total nonsense. Further investigation came up with the chip not being able to communicate in SMBUS-mode so I switched to i2c-mode and it worked like a charm.

Anyway, with the problems listed above solved, the driver reached something that can be called a beta-state. It can now do capture in both RGB565X and VYUY (though it could be better in the RGB565X, the VYUY is fine). Sadly, the RGB555X is still not there, but I wonder if anyone will actually be missing it since there are those two higher-quality formats.

The patch is available here. Actually, I upload a new version of the patch from time to time and the old version of the patch gets overwritten so there might pop up a new version of the driver between blog entries announcing it. Though the changes are often very minor.

Monday, August 3, 2009

OmniVision OV9640 hacking - part ][

So once the i2c problem was partly solved, I started putting together a driver for the camera chip. It's in an alpha-state currently, which means some things are still missing/doesn't work/are untested etc., but it can already make photos! Some examples follow.

This is a RGB565 photo of a monoscope.

This is a VYUY photo of a monoscope.

Here comes a list of the problems so far:
  • The image quality is still a little bad in case of VYUY, more bad in case of RGB565 and it doesn't work for RGB555 yet. This needs some further work.
  • Some of the advanced features of the OV96xx are missing altogether.
If you still haven't lost your interest, here are the patches:

Saturday, August 1, 2009

OmniVision OV9640 hacking

I've been hacking on this camera module in last three days or so. Whew, it gave me quite a pain especially because of the SCCB interface (which is renamed i2c), but I finally defeated it. This chip can be found for example in Palm Zire72. I made some hardware research to figure out what GPIOs drive it. the results are:
  • GPIO56 - PWDN
  • GPIO57 - RESET
  • GPIO91 - DVDD
Ok, with this knowledge, it's simple to setup PXA QCI and read some data from the chip. With a little effort I was able to make a photo using the fswebcam tool. Though the colours were totally off and messed up because the camera chip wasn't configured at all. And here came the main problem.

The problem was, when I tried to communicate with the chip using i2c-pxa driver (the native PXA I2C driver), it didn't work. The i2c driver complained about timeouts etc. Just a while ago, I got quite crazy idea to give the i2c-gpio driver (this one toggles GPIOs to emulate i2c behaviour) a go. To my surprise, it worked. I was able to read registers of the chip and all. So this is it, the whole solution was to use the i2c-gpio driver instead of i2c-pxa.

But here comes another question - why ... why does it work with i2c-gpio and doesn't with i2c-pxa ? I think the problem might be with I2C and QCI clocks supplied to the module (speed, sychro, ... who knows). But interestingly enough, PalmOS seems to use the PXA I2C. So this makes the whole situation even more confusing. So in the end, this will need some further investigation, but at least the camera is working somehow and I can start writing a proper driver for it.

Sunday, July 26, 2009

Summary of happening in last two weeks or so

I was pretty much silent for last two weeks or so, but that doesn't mean I wasn't hacking on the kernel. More like the opposite is true, I was quite busy actually. Therefore I'm writing a little summary of what I did with some comment about it's usefulness etc.
  • Passing platform_data to devices attached to AC97 bus

    This is actually the most revolutionary change. It allows passing platform_data (values like IRQ line, sampling frequency and many others) to devices connected to AC97 bus. This wasn't previously possible and the values were mostly hardcoded into the drivers or were using helper functions to pass the platform_data (which is not nice, but was inevitable). With this change, you can now easily set up a structure containing the parameters for your AC97 device inside your platform definition file and pass it to the AC97 device.

    Also, I converted the wm97xx-battery driver to utilize this change and prepared a patch that converts all platforms using this driver to pass the platform_data properly.

    Another change related to this are cleanups in the wm97xx-battery driver, but also there's a patch queued that adds IRQ-driven charger detection. This means the driver doesn't have to poll the charger state anymore.

    Also, I'm planning to convert the Mainstone Accelerated Touch driver to use this patch as it contains hardcoded values.

    There's also one more patch related to the sound part of wm97xx, but this time it's Palm-specific. I converted palm27x-asoc driver to use jack detection api. With this change I could have removed all the buggy GPIO handling code from there and leave the jack detection to the subsystem which is passing it to the userspace as a keypress event. I also used this pxa27x-asoc hacking opportunity to fix a few minor issues in there.

    The above patches are pretty much ready and should hit 2.6.32

  • Fix broken pxaficp-ir driver and improve it

    This driver wasn't probably tested for a long time, therefore noone noticed the breakage. Since I was tinkering with kbdd and needed IrDA working on the Palm, I noticed this. The fix was fairy simple and is already submitted to kernel mailing list.

    Hand in hand with this goes another patch, a patch that removes redundant code from platform definition files concerning pxaficp-ir. I noticed most of the platforms used very similar initialization, controlling and shutdown routines where often a particular GPIO was requested in the initialization routine, toggled according to IrDA mode in the controlling routine and freed in the shutdown routine. Therefore I took all this, put it into pxaficp-ir, added two more entries (.gpio_pwdown, .gpio_pwdown_inverted) into pxaficp platform_data structure and converted all the platforms in question to use this. This also fixed a few oversights in the code. Though some platforms still has to use the old way (mainstone, lubbock to name a few) since their IrDA routines are much more complicated then toggling a GPIO.

    Actually, this GPIO toggling thing is happening because most of the IrDA transceivers have around 5 pins, those are Vcc, GND, TXD, RXD, PWDOWN. The PWDOWN pin is interesting, since by pulling it high it blocks the transceiver (disconnects the logic) so it can't either transmit or receive anything. This approach is used on pretty much everything (not only PXA board) since it's cheapest and easiest to do.

    Those two will hopefully hit 2.6.32 as well.

  • I put together NAND driver for Palm T|X

    This driver uses the gen_nand driver, therefore all of the controlling routines are implemented in platform definition file. So far so good. The really bad part is Palm hardware engineering squad probably had some issues (better leave it at this since I don't want to insult anyone). They connected the NAND flash in very obscure way. As you can see on the schematic*, the CLE (Command Latch Enable) and ALE (Address Latch Enable) lines of NAND are connected to pretty high MA (memory address) lines of CPU. This makes allocating two memory regions a must to drive those pins. Allocating one continuous region would be unthinkable. Actually, vast majority of hardware manufacturers wire the ALE and CLE pins of NAND flash to low memory addresses. But otherwise the wiring is quite fine.

    * this is available thanks to Ales 'snua12' Snuparek who took apart broken Palm T|X and gave me a board with no components on it so I can trace the connections from CPU to NAND

  • I added Palm Universal Wireless Support into kbdd

    This was quite a quick hack. I had to switch the pxaficp-ir off in kernel in the end though, reconfigure the ttyS2 port as STUART and toggle the PWDOWN GPIO using the GPIO API through sysfs since pxaficp-ir is a network device and the keyboard surely doesn't speak ethernet frames, therefore all what the keyboard generated was dropped even before it entered the network stack. I think we might need some middle layer here, between where RAW IrDA frames are unpacked and network layer, from which we can get raw keyboard data, but that's not important now and needs to be properly thought through. Well since I has the port in STUART mode, I had to implement cruncher for IrDA frames. They are pretty simple so it wasn't a problem. Otherwise the keyboard protocol was simple. What the keyboard actually says is 6 byte sequence: [XBOF][BOF][keycode, highest bit (7) is indicating keypress][previous byte, but bit-inverted][probably CRC, no idea][EOF].

    This patch, if wasn't already applied will be applied soon.

  • LMS283GF05 LCD SPI controller driver

    This hit mainline through the -mm tree. There's an article about this driver earlier this month.

  • The never ending tale of serial port power management hook goes on

    But this time it actually moved somewhere. Russell came up with some vast patch for selectively registering UARTs on PXA from platform definition files. If this patch will be combined with mine, which adds the hook, this tale might actually have a happy ending meaning we will finally be able to switch the level shifters and similar chips attached to UARTs on and off without pain.

  • UCB1400 touchscreen shivering

    Today, a friend of mine reported me that ucb1400_ts driver pretty much sucks. I gave it a go and he was right. Therefore we had two absolutely different platforms, but the same problem, the touchscreen was barely usable because of the shivering. The cursor was jumping like crazy even if the touchscreen was properly calibrated and all. He also suggested to check the ADCSYNC pin as it might help. So I started investigating around that. Not too long after that I noticed a kernel parameter which was set to 0 by default and which enables utilization of ADCSYNC pin by the touchscreen driver. Setting that to 1 made the touchscreen calm down and with that it works beautifully. I'm thinking of setting it to 1 be default in kernel and using the kernel parameter to set it to 0 since most platforms, if not all, have that pin connected (it's necessary to sync the touchscreen with LCD as not being in sync is the cause of shivering).

  • Updates to Palm Tungsten|C patches

    I also updated to Palm Tungsten|C patchset to incorporate the ucb1400 change as well as a few other fixes.

And that's about it. The article grew unexpectedly long so if you are reading this, I'm happy you didn't get bored and ran away.

Friday, July 17, 2009

PalmLD NOR Flash driver

I sent one more patch to linux-arm-kernel mailing list adding support for AMD Am29LV400BB90VI CMOS NOR Flash memory to Palm LifeDrive Linux port through physmap-flash driver. This flash as used in Palm LifeDrive has 16bit wide data/address bus and total capacity of 4Mbit (512kB).

PalmTX,T5,LD fixes

Today, I sent a few fixes for PalmTX, T5 and LifeDrive to some mailing lists (alsa-devel, linux-input, linux-wireless, linux-arm-kernel). They are addressing the following issues:
  • MFP configuration for STUART on T5, TX, LD (fixes not working serial port)
  • WiFi channel issue on TX (that is, fix for FWv4 register shift in libertas driver)
  • MMC delay on T5, TX, LD (fixes problems with some cards not being detected properly)
  • Interrupt driven touchscreen driver for T5, TX, LD (see below)
I also sent RFC patch for pxaficp driver to remove too many copies of similar code for startup/shutdown of the IrDA chip.

Interrupt driven touchscreen driver: I modified the mainstone interrupt driven touchscreen driver and added support for Palm hardware. The benefit from this is that this driver removes some load from the CPU. The main problem with getting this driver work was weird WM1613 chip found in Palms. The chip is some weird crossbred between WM9712 and WM9713 (because WM9712 has AC97_GPIO_STATUS register shifted by one to left, WM9713 doesn't and WM1613 doesn't either, though reports it's ID as WM9712 ; also, reportedly this chip as found in Palm Treo680 reports it's ID to be the one of WM9713).

Further Z2 kernel hacking

As you might have noticed, I was hacking quite a lot on the Z2 recently. I finally got the patches into some releasable form, so here they are (LINK). To apply them, issue the following commands:
  • Clone Eric Miao's kernel tree:
    • $ git clone git://
    • $ git checkout -t -b devel origin/devel
  • Extract the tarball with patches:
    • $ tar -xvjf Z2-patches.tar.bz2
  • Apply the patches:
    • $ git am Z2-patches-clean/*.patch
The current version still has some issues, but that's being worked on (mostly usability issues, hardware seems to work well). Beware, this version of kernel doesn't work with BLOB bootloader. You'll need U-Boot flashed into your Z2 in order to run this kernel.

Saturday, July 11, 2009

Z2 LCD problem solved

As I wrote in the previous entry, the LCD wasn't working if BLOB was replaced with U-Boot on Z2. This is not true anymore. A member of Z2 hacking community called 'g1powermac' supplied me with a datasheet to the LCD module which clearly stated the LCD needs initialization over SPI bus. I took a quick glance at the BLOB sources and found out it's really true, the LCD needs to be initialized as there was something very similar to the stuff in datasheet. I put together a simple driver (patch available here) to do the initialization and it really turned out to be the problem why LCD stood blanked. Therefore the way to replacing BLOB with U-Boot is now open.

Thursday, July 9, 2009

Zipit Z2 bootloader hacking

Some time ago, I got quite nice device called Aeronix Zipit Z2 from Martin 'Magon' Kupec. The configuration is pretty normal - 32MB of RAM, 8MB of Flash, 312MHz PXA270C5. Moreover, the device is Linux-based, but running some proprietary userspace application.

Actually, the maker of the Z2 was kind enough and provided some patches and some hardware information (can be found here). I'm a little suspicious whether the patches and what's in the device correspond, but whatever. Unlike Palm Inc. (whose behavior towards Linux community is very disgusting and rude), the Z2 maker is very open to cooperation with Linux community and very supportive.

Anyway, just recently, I started hacking on a new bootloader for Z2 as the one the device is shipping with is total crap (details left out for the sake of mentally weaker readers). The bootloader of choice was u-boot again. In it's current state, the only problem with replacing BLOB (the original bootloader) with u-boot is that with u-boot, the LCD doesn't work even later in Linux, it just stays blank white. The rest of the hardware works (you can even boot kernel from MMC card, serial console is OK, Flash memory is supported etc.). I suspect the problem with LCD is some GPIO setup problem or PMIC setup problem and will need further investigation. Here's a simple howto to get an u-boot binary for your Z2:
  • Clone U-Boot-ARM sources: git clone git://
  • Download patch here and apply it to the sources
  • Run the following commands to compile U-Boot for Z2:
    • make CROSS_COMPILE=arm-linux-gnueabi- clean
    • make CROSS_COMPILE=arm-linux-gnueabi- zipitz2_config
    • make CROSS_COMPILE=arm-linux-gnueabi-
The above procedure will produce file called u-boot.bin. You'll need a serial port attached to Z2 to replace the BLOB bootloader. In case you happen to fail the process of replacing the bootloader, you'll have to attach JTAG adapter to the Z2 and reflash using JTAG.


Ok, so if you are still brave enough, here's the procedure.
  • Run minicom terminal emulator on your PC, set serial port configuration to 115200Bd 8N1 (^A-o).
  • Power up Z2, press Enter repeatedly to interrupt autoboot ... you will get bootloader prompt (blob>).
  • On your PC, prepare two files from u-boot.bin by issuing the following commands:
    • dd if=u-boot.bin of=u-boot.bin.1 bs=64k count=1
    • dd if=u-boot.bin of=u-boot.bin.2 bs=64k skip=1
    The first file should be exactly 65536 bytes long, the second one should be a little shorter.
  • Now you have to send the files to the device. In the BLOB command prompt type "xdownload blob" without quotes and press ^A-s, select xmodem and navigate to the u-boot.bin.1 file. Send that one.
  • Once the above procedure succeeded, continue to sending second part of u-boot. In the BLOB prompt, type "xdownload kernel", do the same sequence as before, that is ^A-s, select xmodem, but this time send u-boot.bin.2 file.
  • Now finally you can flash the u-boot into the device. That is done by issuing the following two commands in BLOB prompt (this is the unsafe part, anything to this point was safe): "flash kernel" "flash blob". Once those complete, type "reboot" and you should get an u-boot prompt.
If the above worked, congratulations to your new Z2 with u-boot.

Just a final note to this patch, it needs cleaning up and fixing the LCD problem.

Tuesday, July 7, 2009

A way to PalmOS-less device IV

This being probably the last article of the series, I decided to sum things up a little. But firstly, I have to admit there's still a minor issue. The system sometimes refuses to suspend and hangs instead. That is being worked on. I made some chart of support available here. As of now, the device is pretty much usable. My current setup looks like the following:
  • xfce4 on debian-based rootfs running from 2Gb class-4 SD card
  • Flash containing UBoot bootloader and basic recovery system (fits well in 16Mb)
Even though I think this kind of full-blown setup might be a little too heavy on a device PalmTC is, it copes with it well.

Now to the kernel stuff, as you might have found out in the previous posts, there are some files available, here's the list:
  • Kernel config: .config
  • Patches: Available here, apply on the following kernel tree
  • U-Boot patch: available here
To compile kernel, do the following:
  • Copy the downloaded .config to kernel source directory, apply all patches (use git am).
  • make ARCH=arm CROSS_COMPILE=arm-something- menuconfig # this is not needed in case you don't want to modify the kernel configuration
  • make ARCH=arm CROSS_COMPILE=arm-something- # this will get you arch/arm/boot/zImage (suitable for Cocoboot)
  • make ARCH=arm CROSS_COMPILE=arm-something- uImage # this will get you arch/arm/boot/uImage (suitable for U-Boot)
  • INSTALL_MOD_PATH=/somewhere/safe make ARCH=arm CROSS_COMPILE=arm-something- modules_install # this will install modules to /somewhere/safe/lib/modules/... You really don't want to mix them with your systems' modules
To compile U-Boot, do the following:
  • Apply all patches (again, git am is your friend)
  • make CROSS_COMPILE=arm-something- clean
  • make CROSS_COMPILE=arm-something- palmtc_config
  • make CROSS_COMPILE=arm-something- # this will get you u-boot.bin, the bootloader binary
You can use busybox to prepare some initramfs for your kernel if needed.

Friday, July 3, 2009

A way to PalmOS-less device ]|[

So after some more tinkering with linux kernel, I got a decent, cleaned up version of the sources ready. Without further ado, get the sources here:

What still has issues is the keypad, I'll have to talk about it with Eric Miao since he made some changes to the original driver. The WiFi works, sadly, the module was faulty so I replaced it with another one. Also, sound is now fixed as well. I'll prepare some kind of linux installer soon.

Thursday, July 2, 2009

A way to PalmOS-less device ][

And here comes one more entry today. Once I have a nice uboot on PalmTC now, why not give linux a go, right? Actually, collecting all the ancient patches for PalmTC I produced last year, I managed to compile a kernel from them and load it on PalmTC. Many things work, though there are some that do not. Here's the list of those that need fixing:
  • Keyboard (needs to be replaced by gpio-matrix-keypad that will land in mainline soon ... I hope)
  • WiFi (this might be caused by the highly suspicious state of the WiFi module, I need to test with another one)
Sound has one issue as well, the palmtc-asoc driver doesn't work, but with the native PXA driver, the UCB1400 chip is properly detected and touchscreen works as well. Therefore it'll be an easy fix.

U-Boot on PalmTC, way to PalmOS-less device

About a month ago, I made initial port of u-boot bootloader to Palm Tungsten|C. Back then it was bootable from PalmOS and pretty safe to tinker with. But just recently I gave it a go on real hardware. The hardware of choice was an old PalmTC I had lying around here for some time, covered with dust since I thought it was somehow damaged. To my surprise, after a few hours with JTAG ( more info on JTAG with Palm hardware ) and openwince-jtag tool, I managed to get serial console ( for that I used FTDI-based RS-232/USB converter from ). Tinkering with it further got me a proper LCD support and MMC support (therefore it's even safe to damage kernel in flash as it still can boot from MMC card if inserted).

The patch is here:

Just apply it on top of uboot sources, compile and you should be ready to test it, but be careful, writing to flash can damage your device and the only way out is to solder JTAG to the board and reflash using that (the way I did the initial revival process for my PalmTC unit).

Blog revived

After a few years of silence on this blog, I decided to revive it. I prepared a ToDo list for this summer holiday and I'd like to make it all in time.

Here it is: