We're working with an AT91SAM9263 Rev B in our design and I experienced
some inconsistency in spi-based touchscreen usage between our board and
the Atmel evaluation kit we have that runs on a Rev A chip.
The data was apparently delayed by 1 byte and got ridiculous data out of
the touchscreen driver, very strange. As everything looked normal in
the spi, touchscreen and dma logs, I contacted the Atmel support and
they triggered me on a new HW bug that appeared in the Rev B SPI
controller.
The problem is that the SPI controller on the Rev B needs that the
software reset is performed two times so that it's performed correctly.
Applying the patch below solves the issue on my Rev B board. I've tested
it as well on my Rev A evaluation kit and it has apparently no unwanted
side effect, things continue to work as expected.
Signed-off-by: Haavard Skinnemoen <haavard.skinnemoen@atmel.com>
Cc: David Brownell <david-b@pacbell.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
For some time my at91sam9260 board with JFFS2 on serial flash (m25p80)
would hang when accessing the serial flash and SPI bus. Slowing the SPI
clock down to 9 MHz reduced the occurrence of the hang from "always"
during boot to a nuisance level that allowed other SW development to
continue. Finally had to address this issue when an application stresses
the I/O to always cause a hang.
Hang seems to be caused by a missed SPI interrupt, so that the task ends
up waiting forever after calling spi_sync(). The fix has 2 parts. First
is to halt the DMA engine before the "current" PDC registers are loaded.
This ensures that the "next" registers are loaded before the DMA operation
takes off. The second part of the fix is a kludge that adds a
"completion" interrupt in case the ENDRX interrupt for the last segment of
the DMA chaining operation was missed.
The patch allows the SPI clock for the serial flash to be increased from 9
MHz to 15 MHz (or more?). No hangs or SPI overruns were encountered.
Haavard: while this patch does indeed improve things, I still see overruns
and CRC errors on my NGW100 board when running the DataFlash at 10 MHz.
However, I think some improvement is better than nothing, so I'm passing
this on for inclusion in 2.6.27.
Signed-off-by: Gerard Kam <gerardk5@verizon.net>
Signed-off-by: Haavard Skinnemoen <haavard.skinnemoen@atmel.com>
Cc: David Brownell <david-b@pacbell.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Add per-device dma_mapping_ops support for CONFIG_X86_64 as POWER
architecture does:
This enables us to cleanly fix the Calgary IOMMU issue that some devices
are not behind the IOMMU (http://lkml.org/lkml/2008/5/8/423).
I think that per-device dma_mapping_ops support would be also helpful for
KVM people to support PCI passthrough but Andi thinks that this makes it
difficult to support the PCI passthrough (see the above thread). So I
CC'ed this to KVM camp. Comments are appreciated.
A pointer to dma_mapping_ops to struct dev_archdata is added. If the
pointer is non NULL, DMA operations in asm/dma-mapping.h use it. If it's
NULL, the system-wide dma_ops pointer is used as before.
If it's useful for KVM people, I plan to implement a mechanism to register
a hook called when a new pci (or dma capable) device is created (it works
with hot plugging). It enables IOMMUs to set up an appropriate
dma_mapping_ops per device.
The major obstacle is that dma_mapping_error doesn't take a pointer to the
device unlike other DMA operations. So x86 can't have dma_mapping_ops per
device. Note all the POWER IOMMUs use the same dma_mapping_error function
so this is not a problem for POWER but x86 IOMMUs use different
dma_mapping_error functions.
The first patch adds the device argument to dma_mapping_error. The patch
is trivial but large since it touches lots of drivers and dma-mapping.h in
all the architecture.
This patch:
dma_mapping_error() doesn't take a pointer to the device unlike other DMA
operations. So we can't have dma_mapping_ops per device.
Note that POWER already has dma_mapping_ops per device but all the POWER
IOMMUs use the same dma_mapping_error function. x86 IOMMUs use device
argument.
[akpm@linux-foundation.org: fix sge]
[akpm@linux-foundation.org: fix svc_rdma]
[akpm@linux-foundation.org: build fix]
[akpm@linux-foundation.org: fix bnx2x]
[akpm@linux-foundation.org: fix s2io]
[akpm@linux-foundation.org: fix pasemi_mac]
[akpm@linux-foundation.org: fix sdhci]
[akpm@linux-foundation.org: build fix]
[akpm@linux-foundation.org: fix sparc]
[akpm@linux-foundation.org: fix ibmvscsi]
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Cc: Muli Ben-Yehuda <muli@il.ibm.com>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Avi Kivity <avi@qumranet.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Make the baud rate divisor calculation code a bit more readable and add a
few comments.
Also fix wrong debug information being displayed when !new_1 and
max_speed_hz == 0.
[david-b@pacbell.net: fix it]
Signed-off-by: Haavard Skinnemoen <haavard.skinnemoen@atmel.com>
Cc: "Janesh Ramakrishnan" <jramakrishnan@neuropace.com>
Acked-by David Brownell <david-b@pacbell.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
A spi transfer with zero length is not invalid. For example, such
transfer (len == 0 && delay_usecs != 0) can be used to achieve delay
before first CLK edge after chipselect assertion.
Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
Cc: Haavard Skinnemoen <hskinnemoen@atmel.com>
Cc: David Brownell <david-b@pacbell.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Since 43cc71eed1, the platform modalias is
prefixed with "platform:". Add MODULE_ALIAS() to the hotpluggable SPI
platform drivers, to allow module auto loading.
[dbrownell@users.sourceforge.net: more drivers: registration fixes]
Signed-off-by: Kay Sievers <kay.sievers@vrfy.org>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
The atmel_spi driver does not initialize clock polarity correctly (except for
at91rm9200 CS0 channel) in some case.
The atmel_spi driver uses gpio-controlled chipselect. OTOH spi clock signal
is controlled by CSRn.CPOL bit, but this register controls clock signal
correctly only in 'real transfer' duration. At the time of cs_activate()
call, CSRn.CPOL will be initialized correctly, but the controller do not know
which channel is to be used next, so clock signal will stay at the inactive
state of last transfer. If clock polarity of new transfer and last transfer
was differ, new transfer will start with wrong clock signal state.
For example, if you started SPI MODE 2 or 3 transfer after SPI MODE 0 or 1
transfer, the clock signal state at the assertion of chipselect will be low.
Of course this will violates SPI transfer.
This patch is short term solution for this problem. It makes all CSRn.CPOL
match for the transfer before activating chipselect. For longer term, the
best fix might be to let NPCS0 stay selected permanently in MR and overwrite
CSR0 with to the new slave's settings before asserting CS.
Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
Acked-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
Cc: David Brownell <david-b@pacbell.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
In atmel_spi_next_xfer, xfer can be NULL because the next transfer may
already have been submitted to the PDC (using DMA chaining). This can
cause an oops, since the debug message assumed it was never null. The
fix changes how those debug messages are issued, ensuring that one is
issued each time a transfer is started instead of once per call.
Also, properly indent the "can this transfer be chained" test so it's
not hidden as if it were non-conditional code.
Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Add support for chained transfers in the atmel_spi driver, letting the DMA
controller switch to the next buffer pair without CPU intervention. This
reduced I/O latencies by about 2% in one bulk I/O test. It should also help
work around several interrelated errata affecting chipselect 0 on at91rm9200
chips.
Almost all of the changes are in the reworked atmel_spi_next_xfer() function.
That's now called with the driver in one of three states:
1. It isn't transferring anything (in which case the first transfer
of the current message is going to be sent)
2. It has finished transfering a non-chainable transfer (in which
case it will go to the next transfer in the message)
3. It has finished transfering a chained transfer (in which case the
next transfer is already queued)
After that it will queue the next transfer if it can be chained.
Signed-off-by: Szilveszter Ordog <slipszi@gmail.com>
Acked-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Don't insert (undesirable) delays between consecutive words (DLYBCT) or when
activating chipselects (DLYBS).
Removing the between-word delays improves the performance of bulk transfers
(such as mtd_dataflash, m25p80, mmc_spi) significantly. In one test, the
improvement was a factor of more than eight!
(The large DLYBCT value came from the legacy at91 SPI driver, and it's not
clear why it used such a huge value.)
Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
We have a wifi module connected to the spi bus and got sometimes FIFO
overrun errors on the spi bus.
After some investigation i found that the driver loads the TCR (transmit
count) register before the RCR (receive count). When the transfer list is
not empty the atmel_spi_next_message is called while tx and rx are enabled.
As soon as the TCR is loaded, hardware starts transfer and causes a rx
fifo overrun because the RCR is not loaded yet.
Load the RCR before the TCR. After this patch the fifo overrun disapears
at out setup.
Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
Signed-off-by: Rini van Zetten <rini@arvoo.nl>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Make the atmel_spi driver label GPIOs according to the device for which
they're acting as a chipselect. This way the debugfs dump of gpio state is
more informative.
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Cc: Haavard Skinnemoen <hskinnemoen@atmel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Make the SPI framework and drivers stop using class_device. Update docs
accordingly ... highlighting just which sysfs paths should be
"safe"/stable.
Signed-off-by: Tony Jones <tonyj@suse.de>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Cc: Greg KH <greg@kroah.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Fix cut 'n paste bug in Atmel SPI driver.
Signed-off-by: Andrew Victor <andrew@sanpeople.com>
Acked-by: David Brownell <david-b@pacbell.net>
Acked-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Update chipselect handling for atmel_spi:
* Teach it how to leave chipselect active between messages; this
helps various drivers work better.
* Cope with at91rm0200 errata: nCS0 can't be managed with GPIOs.
The MR.PCS value is now updated whenever a chipselect changes.
(This requires SPI pinmux init for that controller to change,
and also testing on rm9200; doesn't break at91sam9 or avr32.)
* Fix minor glitches: spi_setup() must leave chipselects inactive,
as must removal of the spi_device.
Also tweak diagnostic messaging to be a bit more useful.
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Acked-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Minor updates to atmel_spi:
- DMA:
* Comments to explain the DMA policies
* Report any mapping errors from spi_transfer()
* Remove extra loop for DMA mapping
- Diagnostics: report minimum clock rate, if we need to reject a
spi_setup() request because that rate is too low.
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Acked-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Minor SPI controller driver updates: make the setup() methods reject
spi->mode bits they don't support, by masking aginst the inverse of bits
they *do* support. This insures against misbehavior later when new mode
bits get added.
Most controllers can't support SPI_LSB_FIRST; more handle SPI_CS_HIGH.
Support for all four SPI clock/transfer modes is routine.
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
When either rx_buf or tx_buf is not being used, i.e. for plain read- or
write operations, the atmel_spi uses a fixed-size DMA buffer instead. If
the transfer is longer than the size of this buffer, it is split into
multiple DMA transfers.
When the transfer is split like this, the atmel_spi driver ends up using
the same DMA address again and again even for the buffer that came from the
user, which is of course wrong. Fix this by adding the number of bytes
already transferred to the DMA address so that the data ends up in the
right place.
Thanks to Wu Xuan for discovering this bug.
Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Now that the cpu_is_xxx() macros are available both on AVR32 and AT91, we can
remove a couple of #ifdefs from this driver. One of them is actually wrong --
new_1 should be set on AVR32 but isn't. This causes the bus clock to run at
twice the speed it is configured to.
Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
Cc: David Brownell <david-b@pacbell.net>
Acked-by: Andrew Victor <andrew@sanpeople.com>
Cc: Nicolas Ferre <nicolas.ferre@rfo.atmel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
It's been pointed out that output GPIOs should have an initial value, to
avoid signal glitching ... among other things, it can be some time before
a driver is ready. This patch corrects that oversight, fixing
- documentation
- platforms supporting the GPIO interface
- users of that call (just one for now, others are pending)
There's only one user of this call for now since most platforms are still
using non-generic GPIO setup code, which in most cases already couples the
initial value with its "set output mode" request.
Note that most platforms are clear about the hardware letting the output
value be set before the pin direction is changed, but the s3c241x docs are
vague on that topic ... so those chips might not avoid the glitches.
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Acked-by: Andrew Victor <andrew@sanpeople.com>
Acked-by: Milan Svoboda <msvoboda@ra.rockwell.com>
Acked-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
Cc: Russell King <rmk@arm.linux.org.uk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
The signature of the per-device cleanup() routine changed to remove its
const-ness. Three new SPI controller drivers now need that change, to
eliminate build warnings.
This also fixes a build bug with atmel_spi on AT91 systems.
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Driver for the Atmel on-chip SPI master controller.
Tested primarily on AVR32/AT32AP7000/ATSTK1000 using mtd_dataflash and the
jffs2 filesystem. Should also work fine on various AT91 ARM-based chips
like AT91SAM926x and AT91RM9200.
Hardware documentation can be found in the AT32AP7000 data sheet, or its
AT91 siblings, which can be downloaded from
http://www.atmel.com/dyn/products/datasheets.asp?family_id=682
Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>