AnsweredAssumed Answered

i.MX53 i.MX51 SPI 8 bit mode only, No GPIO CS & Baud Rate

Question asked by TomE on Oct 14, 2015
Latest reply on Nov 8, 2015 by TomE

SUMMARY:

 

It looks like the Linux SPI Driver for the i.MX53 is buggy and doesn't support 16 or 32 (or anything except 8) bit SPI transfers. I'm surprised nobody else had had trouble with this. I can't find any reports in this or other forums.

 

DETAILS:

 

I've been running a mainline Linux 3.4 on an i.MX53 board. It is working fine.

 

In order to get video capture working, we've been forced to use the Freescale 2.6.35 Kernel.

 

I'm now trying to get the other peripherals working on 2.6.35.

 

We have a LED driver on one of the SPI ports. It just doesn't work, and I'm pretty sure I've tracked down the problem.

 

The SPI port can be configured to almost any width. Common values are 8, 12, 16, 24 and 32. We have the port configured to 32-bits and are sending 18 32-bit wide words.

 

This works fine with Linux 3.4.

 

Linux 2.6 is sending 72 32-bit words instead of sending 18. It is sending each 4-byte word 4 times. It is actually running right off the end of the transmit buffers and sending garbage.

 

I've traced this to what looks like a very basic design problem within the drivers. The "length" is passed from the user space as a "byte count", but the driver never converts this into a "word count" anywhere. It looks like it can only work when the port is configured to be 8 bits wide (wasting 75% of the FIFO), and also looks like it has only ever been tested set to 8 bits wide too.

 

Linux 3.4 and the versions of Linux running on the i.MX6 are using "drivers/spi/spi-imx.c". Linux 2.6 has this driver present (as "drivers/spi/spi_imx.c"), but in 2.6.35 it only supports (and is only used in) the i.mx3 builds, as as of that version it only supported the i.MX3 CSPI and not the i.MX5 ECSPI. Instead, Freescale's custom 2.6 kernel uses "drivers/spi/mxc_spi.c".

 

The "spi-imx.c" file handles the byte-length to word-length conversion properly, by decrementing the byte count in the following function:

 

#define MXC_SPI_BUF_TX(type)                        \
static void spi_imx_buf_tx_##type(struct spi_imx_data *spi_imx)     \
{                                   \
    type val = 0;                           \
                                    \
    if (spi_imx->tx_buf) {                      \
        val = *(type *)spi_imx->tx_buf;             \
        spi_imx->tx_buf += sizeof(type);            \
    }                               \
                                    \
    spi_imx->count -= sizeof(type);                 \ #### This is the bit that decrements the byte count by the right size.
                                    \
    writel(val, spi_imx->base + MXC_CSPITXDATA);            \
}


 

The equivalent function in mxc_spi.c is called "count" times from the parent function (mxc_spi_pio_transfer()), which simply copies "t->len" into "count".

 

#define MXC_SPI_BUF_TX(type)    \
u32 mxc_spi_buf_tx_##type(struct mxc_spi *master_drv_data)\
{\
    u32 val;\
    const type *tx = master_drv_data->transfer.tx_buf;\
    val = *tx++;\
    master_drv_data->transfer.tx_buf = tx;\
    return val;\
}


 

 

Was this ever fixed anywhere or have the i.MX51 and i.MX53 SPI ports (courtesy of the driver) never worked in anything other than 8-bit-width mode?

 

As well as this problem, this driver only support "real chip selects" in the hardware, and doesn't allow the use of GPIOs as chip selects. Our hardware was designed for Linux 3.4, and that only allows GPIOs, so it doesn't have the chip selects on the right pins for 2.6. I've had to add this capability.

 

It looks like "mxc_spi.c" was only used in 2.6., and the kernel switched over to using "spi-imx.c" after it was changed to support the im.MX5x and it's ECSPI.

 

So what's the easiest way for me to get our i.MX53 board driving our LEDs? Is there a fix for mxc_spi.c? Should I try and get the 2.6.37 spi_mxc.c file running on 2.6.35? Any other suggestions?

 

Following the history of these files are quite difficult as they keep changing their names.

 

It was originally added as "spi_mxc.c" here, but only supporting MX1, MX2 and MX3 (and certainly not ECSPI):

 

commit 69c202afa8ad6d6c1c673d8f9d47b43a0a3604e5
Author: Andrea Paterniani <a.paterniani@swapp-eng.it>
Date:   Mon Feb 12 00:52:39 2007 -0800
Branches: many (81)
Follows: v2.6.31
Precedes: v2.6.32-rc1, v2.6.32-rc2

    [PATCH] SPI: Freescale iMX SPI controller driver (BIS+)
   
    Add the SPI controller driver for Freescale i.MX(S/L/1).
    Main features summary:
...
M   drivers/spi/Kconfig
M   drivers/spi/Makefile
A   drivers/spi/spi_imx.c

That had a number of revisions, but then a new version got parachuted in (new file, previous history unknown) here:

 

Author: Dinh Nguyen <Dinh.Nguyen@freescale.com>  2010-08-18 07:46:40
Follows: v2.6.35.3
Precedes:

 

    ENGR00126692-3: Upgrade kernel to 2.6.35

 

M   drivers/spi/mxc_spi.c

 

Then, less than a month later, spi_mxc.c picked up MX5/ECSPI support:

 

commit 0b599603d8534bc3946a0f07e461c76d7947dfcf

Author: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>  2010-09-10 05:02:48
Committer: Sascha Hauer <s.hauer@pengutronix.de>  2010-10-01 17:32:13
Branches: many (59)
Follows: v2.6.36-rc4
Precedes: v2.6.37-rc1

    spi/imx: add support for imx51's eCSPI and CSPI

M   drivers/spi/spi_imx.c

 

What makes these changes harder to track than they should be is that the files get renamed every now and then. For instance there was a big name-change party that renamed everything, including  spi_imx.c to spi-imx.c::

 

Author: Grant Likely <grant.likely@secretlab.ca>  2011-06-06 17:16:30
Committer: Grant Likely <grant.likely@secretlab.ca>  2011-06-06 17:16:30
Child:  edd501bbf177ab62f963476c917cbdb0dc7dc862 (spi/imx: do not make copy of spi_imx_devtype_data)
Branches: many (40)
Follows: v3.0-rc1
Precedes: v3.1-rc1

 

    v2: - Use 'spi-' prefix instead of 'spi_' to match what seems to be
          be the predominant pattern for subsystem prefixes.

 

A   drivers/spi/spi-imx.c
R100    drivers/spi/spi_imx.c   drivers/spi/spi-imx.c

 

Freescale's support of the i.MX53 seems to have stopped at their 2.6.35 version though. This is the one I started from:

 

http://git.freescale.com/git/cgit.cgi/imx/linux-2.6-imx.git/log/?h=imx_2.6.35_maintain

 

There is a later one that seems to have the other driver updated, and looks like it has changed the configuration and platform files (for ARD, EVK and LOCO) to use it. Maybe I should have started from this one instead of 2.6.35_maintain.

 

http://git.freescale.com/git/cgit.cgi/imx/linux-2.6-imx.git/log/?h=imx_2.6.38_12.01.01

 

Tom

 

Message was edited by: Tom Evans

Outcomes