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

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

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

4,511 次查看
TomE
Specialist II

SUMMARY:

It looks like the Linux SPI Driver for the i.MX53 is buggy and doesn't support 16 or 32 (or anything except 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

标记 (1)
0 项奖励
回复
5 回复数

2,593 次查看
igorpadykov
NXP Employee
NXP Employee

Hi Tom

I would suggest to check it with official FSL BSP release from i.MX53

product page

Board Support Packages (8)

Linux 2.6.35 Source Code Files and documentation 11.09. Supports

MCIMX53-START and MCIMX53-START-R (REV 2011.09)

i.MX53 Quick Start Board|Freescale

If you suspect that this is hadware bug, check it with bare metal obds

(drivers/spi  test)

Lab and Test Software (2)

On-Board Diagnostic Suit for the i.MX53 Quick Start Board (REV 2011.39)

GZ (11.5 MB) On-Board Diagnostic Suit for the i.MX53 Quick Start Board

i.MX53 Quick Start Board|Freescale

Best regards

igor

0 项奖励
回复

2,593 次查看
TomE
Specialist II

If you suspect that this is hadware bug

Do you know of any hardware bugs with the eCSPI that aren't listed in the User Manual or in the Errata?

Because I think I've just found one.

When I know more I'll write it it in another post.

(Edit): This one:

i.MX53 eCSPI Stops Sending when CPU Idles
https://community.freescale.com/thread/379711

Tom

0 项奖励
回复

2,593 次查看
TomE
Specialist II

> I would suggest to check it with official FSL BSP release from i.MX53

> product page Board Support Packages (8)

> Linux 2.6.35 Source Code Files and documentation 11.09.

I/m pretty sure the above release is this branch:

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

That's only a few commits before the one I'm using. I'll check the tree tomorrow.

Tomorrow and checking...

The link on that page contains a "bundle" that contains four more archives, one of which is:

L2.6.35_11.09.01_ER_source.tar.gz

That contains lots of "packages", four of which are:

linux-2.6.35.3.tar.bz2 (74.7MB)

linux-2.6.38.tar.bz2 (70.8 MB)

linux-2.6.35.3-imx_11.09.01.bz2 (6,6 MB)

linux-2.6.38-imx_11.09.01.bz2 (4.0 MB)

The first two are the base (mainline) source files. The second two are all the patches to be applied to those files to make them into the Freescale releases.

2.6.35.3 takes 1129 patches. 2.6.38 takes 609. I've applied those using the provided scripts.

My version of mxc_spi.c is one patch beyond the one in the distribution, having had "ENGR00229787-2  SPI: enable the bidirectional DMA mode in SPI." applied.

I've backed out that patch (and the previous one) and the part of the code that is buggy is wrong in all of these versions.

The provided 2.6.38 kernel has this SPI bug fixed. That's because the configuration file for 2.6.25.3 selects "mxc_spi.c" while the one for 2.6.38 selects the later "spi_imx.c" which as of 2.6.36 supported the i.MX5:

linux-2.6.35.3/arch/arm/configs/imx5_defconfig:
# SPI Master Controller Drivers
#
CONFIG_SPI_BITBANG=y
# CONFIG_SPI_GPIO is not set
# CONFIG_SPI_IMX is not set
# CONFIG_SPI_XILINX is not set
CONFIG_SPI_MXC=y

linux-2.6.38/arch/arm/configs/imx5_defconfig:

# SPI Master Controller Drivers
#
CONFIG_SPI_BITBANG=y
# CONFIG_SPI_GPIO is not set
CONFIG_SPI_IMX_VER_0_7=y
CONFIG_SPI_IMX_VER_2_3=y
CONFIG_SPI_IMX=y

But if you need to use the 2.6.35 kernel rather than the 2.6.38 one like we do, then SPI doesn't work.

> If you suspect that this is hadware bug

??? I never said anything about the hardware. It works perfectly with Linux 3.4, so it can't possibly have anything to do with the hardware.

I've also pasted the faulty code into my original post. That should be enough to demonstrate the Freescale-provided driver simply doesn't work properly.

Tom

0 项奖励
回复

2,593 次查看
TomE
Specialist II

There's another problem with this SPI driver.

The specification for the "Baud Rate" is in the Linux API is:

include/linux/spi/spidev.h:

/* Read / Write SPI device default max speed hz */ #define SPI_IOC_RD_MAX_SPEED_HZ     _IOR(SPI_IOC_MAGIC, 4, __u32) #define SPI_IOC_WR_MAX_SPEED_HZ     _IOW(SPI_IOC_MAGIC, 4, __u32)

Note that sets the MAXIMUM speed. With SPI you normally have a maximum rate that is allowed by various hardware requirements, so you then need to set a speed that the hardware can deliver that is that speed or lower. Having it set it higher than you asked is unacceptable.

The baud rate calculating code in the "mxc_spi.c" driver is as follows:

static unsigned int spi_find_baudrate(struct mxc_spi *master_data,                       unsigned int baud) {     unsigned int divisor;     unsigned int shift = 0;     /* Calculate required divisor (rounded) */     divisor = (master_data->spi_ipg_clk + baud / 2) / baud;     while (divisor >>= 1)         shift++;

As the comment says, that ROUNDS the rate instead of making sure the result is lower.

It can't even round properly. It rounds down a bit, but rounds up to an extreme degree.

With a 54MHz "Reference Clock", asking for 10MHz results in 13.5MHz as does asking for 14MHz or 15MHz. Asking for 16MHz results in 27MHz! That's 70% high!

Part of the reason it is this bad is that it is treating the ECSPI on the i.MX53 the same as the CSPI, and the baud-rate divider on that only allows a division by a power of 2. The ECSPI allows division by powers of two as well as then dividing by "N" where "N" is 1 to 16, so it can get a lot closer to the requested rate. But the driver hasn't been written to support that.

The other SPI driver (used on 2.6.38 and on all newer 3.x versions) when asked for 10MHz rounds down to the nearest available, which is 9MHz or 54MHz/6.

But the most serious problem is providing a baud rate nearly up to DOUBLE the maximum requested!

Tom

0 项奖励
回复

2,593 次查看
igorpadykov
NXP Employee
NXP Employee

you are right, later kernels are better and fixed bugs of elders.

You can post patches/suggestions to contact given on below link (internally

Freescale BSP team will review these patches)

Submit i.MX53 &amp; i.MX28 Linux kernel patches

Best regards

igor

0 项奖励
回复