Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 2 Sep 2012 13:38:06 -0600
From:      Warner Losh <imp@bsdimp.com>
To:        Ian Lepore <freebsd@damnhippie.dyndns.org>
Cc:        freebsd-arch@freebsd.org, Luiz Otavio O Souza <loos.br@gmail.com>
Subject:   Re: spibus access serialization
Message-ID:  <3C91462E-1423-4AFC-B4C7-6239E698A98E@bsdimp.com>
In-Reply-To: <1346602529.1140.563.camel@revolution.hippie.lan>
References:  <B54C4C9A-76F4-45CC-94C3-628DDF901051@gmail.com> <A0F87D2D-B916-4FB5-9FDF-62807DED9A7E@bsdimp.com> <1346602529.1140.563.camel@revolution.hippie.lan>

next in thread | previous in thread | raw e-mail | index | archive | help

On Sep 2, 2012, at 10:15 AM, Ian Lepore wrote:

> On Sun, 2012-09-02 at 08:47 -0600, Warner Losh wrote:
>> On Sep 2, 2012, at 6:37 AM, Luiz Otavio O Souza wrote:
>>=20
>>> Hi,
>>>=20
>>> I've some embedded systems with spi devices that share the same =
spibus and because of that i'm working to get some kind of access =
serialization on spibus and also protection to devices which need a =
series of spi transfers to achieve some goal.
>>>=20
>>> The SPI usage (with all the patches applied) goes like this:
>>>=20
>>> /* Wait until the spibus is free. When free, acquire the bus and =
select the device */
>>> SPIBUS_ACQUIRE_BUS(spibus, device);
>>=20
>> Does it do this with a sleep?
>>=20
>>> /* Program the CPLD to read data from NAND */
>>> SPIBUS_TRANSFER(spibus, device, &cmd);
>>>=20
>>> /* Read 'n' bytes from CPLD */
>>> SPIBUS_TRANSFER(spibus, device, &cmd);
>>>=20
>>> /* Release the spibus and deselect the device */
>>> SPIBUS_RELEASE_BUS(spibus, device);
>>>=20
>>> While today everything is done inside SPIBUS_TRANSFER().
>>>=20
>>> The patch spibus-01.diff adds the bus methods and the default =
methods.
>>>=20
>>> The spibus-02-devices.diff adds the needed glue to all spi devices =
(dev/flash/at45d.c, dev/flash/mx25l.c, arm/lpc/ssd1289.c, =
mips/atheros/pcf2123_rtc.c). As the default methods are just nops, there =
are no functional changes.
>>>=20
>>> On spibus-03-controllers.diff we finally add the serialization =
methods to spi controllers (mips/atheros/ar71xx_spi.c and =
arm/lpc/lpc_spi.c) and change the device CS to happen on bus acquire and =
release and not on start and end of each transfer.
>>>=20
>>> The spi controller on arm/at91/at91_spi.c wasn't changed because =
looks like it will be need to move the device CS control from the =
controller and use it as a GPIO pin. I need to read more of at91 code =
before i can suggest some change there. Until there it will work just as =
now (no serialization and selecting/deselecting the device within each =
transfer).
>>=20
>> The at91_spi controller controls which CS line is asserted.  So long =
as you don't change the bits in the registers, it will stay asserted.  I =
think it can fit with this scheme.  I'll have to take a closer look.  =
All my AT91 devices have only one chip on the spi bus.
>=20
> Unfortunately, the atmel SPI controller will de-assert the chip select
> when the transmit register (or PDC) runs out of data.  It's a bug that
> may only affect rm9200; I haven't checked the errata and docs for the
> sam9 series to see if they fixed it.

Yes, that's been fixed (which is why I didn't think it would be a =
problem, but it is).

> The way to fix the problem is indeed to take over the handling of chip
> selects in the driver, by taking the pins away from the device and
> managing them as GPIOs.  Doing that is on my to-do list, but I've been
> waiting for some resolution of the "how do we manage device/gpio pin
> setup across the atmel SoC family" questions.

That's the question still, alas.  I've been looking at how FDT does it =
in Linux land, and they punt on this issue.  We'll likely have to put =
some effort into defining these things with atmel's FDT efforts.  Their =
FDT comes close by defining groups, but doesn't seem to take it down to =
the individual pin to signal mapping.

Otherwise we'll have to fall back to arrays of pins that somehow get =
associated with the device...

> This auto-deassert in rm9200 is also the bug that causes us to run the
> SPI bus at roughly 1/20th of its rated speed, to ensure that we never
> get a spurios chip de-select in the middle of a transfer due to
> momentary PDC bus starvation.

Yes.  The SAM9 processors have a new bit, CSAAT, which forces the line =
to be asserted until you deassert it, not just during data transfers.  A =
quick grep of the code indicates that we don't use it, but I haven't =
checked in detail...

> Speaking of SPI bus speed, that's the other wart in our SPI support.  =
We
> need a speed limit member in the spi request structure, so that =
drivers
> of individual devices on the bus can indicate the limit for their
> specific devices.  I'd be happy to see that get added sooner rather =
than
> later, even if it takes a while to get all the low-level drivers
> supporting it.  I think the new field in the struct should indicate =
the
> fastest speed in Hz that the device can handle the bus running, with
> zero meaning no limit.

Yes.  And SPI mode too.  These items should be programmed when the bus =
is requested, imho, but perhaps there's a reason not to do this.

Warner=



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?3C91462E-1423-4AFC-B4C7-6239E698A98E>