[PATCH v4 1/2] spi: implemented driver for Cirrus EP93xx SPI controller

H Hartley Sweeten hartleys at visionengravers.com
Tue Apr 20 20:11:05 EDT 2010


On Tuesday, April 20, 2010 4:55 PM, Martin Guy wrote:
> 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.

Yes, Mode 3 should perform better since the protocol is not enforcing the
chip select deassertion between every byte.

You should still be getting a chip select deassertion between every transfer
in a multipart message since the Sim.One uses the SFRM1 line for the chip select.
I haven't actually looked through the mmc_spi driver to see if this happens.

Is there any possibility you could look at the actual bus with a logic analyzer?

My concern with the comments above is that currently this driver will not work
on the EDB93xx boards with the SPI Flash device.  I did hack one of my boards
to remove the SFRM1 signal from the chip select and it does "fix" the problem.
But, that's kind of an ugly solution for most users.

Regards,
Hartley



More information about the linux-arm-kernel mailing list