libertas: DAT1 signal IRQ in 1-bit SDIO mode
Hi,
I'm still fighting with a MX31 SDHC controller connected to a 8686 module via SDIO. As the libertas firmware uses multiblock transfers, this can't work in 4bit SDIO mode due to a bug in the SDHC controller of the MX31 silicon. This is now finally also confirmed by Freescale.
So the only way around this is to use 1-bit transfers. This appears to work stable now as long as I don't let the host controller announce the capability of serving SDIO IRQs (MMC_CAP_SDIO_IRQ). The IRQ flag is then polled by the MMC core which is a performance drawback of course, but at least it finally works.
However, I also implemented code for proper SDIO IRQ hardware handling for this controller, but the hardware condition is never triggered. I measured with an oscilloscope and found out the 8686 does not actually drive the DAT1 line (which is used as IRQ in 1-bit SDIO mode) low when it is supposed to do.
My question is - did anyone ever use the chip in this mode? Is that a firmware bug?
Any pointers appreciated - I would like to post my pending patches for that issue asap, but need to clear that last issue first.
Thanks,
Daniel
A message that is not in the archive (sent off-list or not yet received): [email protected]
Hi Alagu,
thanks a lot for your comprehensive answer.
Quoted 8 lines · Alagu Sankar
We have used at-least three different WiFi chipsets on an iMX31 host including the Marvell 8686. It was on a LogicPD reference platform running an older 2.6.1x kernel with a commercial SDIO stack solution. The only problem we had with the platform was that it was not providing enough current for the 8686 module, but again that is nothing to do with the iMX31 as such. It was not a smooth sailing developing the host driver for iMX31. After investing a lot of time on the driver, we figured out a way of doing multi-block transfers. For SDIO multi-block writes, we do
The MX31 has a silicon bug which leads to CRC corruption for multi-block transfers. This is also what the SDHC signals in its error flags. I've had technical support from Freescale and they confirmed this bug. According the the Errata I've been sent, the only ways to get around this are to use 1-bit transfers or single-block transfers only. The latter isn't possible for 8686 as the firmware requires the 'real' firmware to be downloaded with multiblock transfers (CMD53).
Quoted 9 lines
multiple DMA transfers each with the block size. For example if you are doing a multi-block write of 10 blocks of 256 byte each, then following is the sequence that works fine
- Configure the controller for 10 blocks and 256 byte block size (like any other typical transfer)
- Configure the DMA controller to do only the first 256 bytes
- Wait for the DMA Completion handler and then initiate the next 256 bytes
- Continue this until all the blocks are transferred.
So what you're doing is you split up multiblock transfers into single blocks? I might lack some knowledge here, but AFAIK that can't work for every peripheral as the other side is well aware of the command it is been issued, and can hence bail out if not fed correctly. Like the firmware download of the 8686 does, according to my findings.
Did you ever try that technique without DMA?
Quoted 5 lines
If this is too much try for now and would like to still continue with the 1-bit mode, you can try setting the ECSI bit in CCCR - Bus Interface Control Register (This should be done inside the libertas driver once during the initialization). This has helped us running the card in 1-bit mode and get SDIO interrupts as well.
Ok, I'll give that a try later today.
Again, thanks for your help.
Daniel
Quoted 5 lines · Alagu Sankar
If this is too much try for now and would like to still continue with the 1-bit mode, you can try setting the ECSI bit in CCCR - Bus Interface Control Register (This should be done inside the libertas driver once during the initialization). This has helped us running the card in 1-bit mode and get SDIO interrupts as well.
Great, that did the trick. Thanks a lot for this information :)
Daniel