[PATCH v4 1/2] spi: implemented driver for Cirrus EP93xx SPI controller
Martin Guy
martinwguy at gmail.com
Tue Apr 20 19:54:56 EDT 2010
On 4/20/10, H Hartley Sweeten <hartleys at visionengravers.com> wrote:
> On Tuesday, April 20, 2010 8:12 AM, Mika Westerberg wrote:
> > This patch adds an SPI master driver for the Cirrus EP93xx SPI controller found
> > in EP93xx chips (EP9301, EP9302, EP9307, EP9312 and EP9315).
>
> I discovered one gotcha with this driver. Bear with me through this...
>
> 1. ep93xx_spi_process_message is called by the workqueue worker function to handle
> a spi_message queued in by the ep93xx_spi_transfer function. Before starting
> the actual transfer the chip select to the device is asserted.
> 2. ep93xx_spi_process_transfer processes each transfer in the spi_message, one at a
> time, and does a wait_for_completion on each transfer.
> 3. When the entire spi_message has been transferred the chip select to the device
> is deasserted.
>
> The problem is if a hardware design uses the SFRM1 pin as part of the chip select
> logic. The EP93xx User's Guide states that "the SFRMOUT signal behaves as a slave
> Select" in Motorola SPI mode. This signal behaves differently depending on the
> SPI_MODE_* used.
>
> Modes 0 and 2:
> SFRMOUT is forced HIGH during idle periods.
> Start of transmission, SFRMOUT is driven LOW.
> Single word transmission, SFRMOUT is returned to its idle HIGH state one
> SCLKOUT period after the last bit has been captured.
> Back-to-back transmissions, SFRMOUT signal is pulsed HIGH between each
> data word transfer. On completion the SFRMOUT pin returns to its idle
> HIGH state one SCLKOUT period after the last bit has been captured.
>
> Modes 1 and 3:
> SFRMOUT is forced HIGH during idle periods.
> Start of transmission, SFRMOUT is driven LOW.
> Single word transmission, SFRMOUT is returned to its idle HIGH state one
> SCLKOUT period after the last bit has been captured.
> Back-to-back transmissions, SFRMOUT signal is held LOW between each
> data word transfer. On completion the SFRMOUT pin returns to its idle
> HIGH state one SCLKOUT period after the last bit has been captured.
>
> So, since each transfer does a wait_for_completion, all the data is transmitted
> which causes the SFRMOUT pin to go HIGH between each transfer in the message.
>
> For devices like the sst25lf040a SPI Flash on the EDB93xx boards this causes a
> problem. To read data from that device you need to send a two part message. The
> first part is a write transfer with the one byte command and three byte address.
> This is then followed by a read transfer to get the data. But since the SFRMOUT
> pin goes high this ends the command.
>
> The driver Ryan and I worked on actually does work with the sst25lf040a on the
> EDB93xx boards. But now that I know what the issue is, it was actually a race
> condition. Sometimes it worked and sometimes it didn't...
>
> I would think the Sim.One board (Martin?) would have the same issue with the mmc
> card since that design uses the SFRMOUT pin directly for the chip select.
>
> Is there anyway to keep the transfers going in a muiltipart message?
I just changed the SPI mode selection, which is in the board
definition file, from Mode 0 to Mode 3 (the two modes that sample data
on the rising clock edge, as required by MMC/SD). It dramatically
increases linear block read throughput:
MMC: from 307kB/sec to 353kB/sec
SD: from 317 to 365
SD MLC: from 327 to 378
with 82000 interrupts per second and 60% cpu usage
presumably because the poor card isn't being deselected once every byte.
M
More information about the linux-arm-kernel
mailing list