ti-qspi controller provides mmap port to read data from SPI flashes.
mmap port is enabled in QSPI_SPI_SWITCH_REG. ctrl module register may
also need to be accessed for some SoCs. The QSPI_SPI_SETUP_REGx needs to
be populated with flash specific information like read opcode, read
mode(quad, dual, normal), address width and dummy bytes. Once,
controller is in mmap mode, the whole flash memory is available as a
memory region at SoC specific address. This region can be accessed using
normal memcpy() (or mem-to-mem dma copy). The ti-qspi controller hardware
will internally communicate with SPI flash over SPI bus and get the
requested data.
Implement spi_flash_read() callback to support mmap read over SPI
flash devices. With this, the read throughput increases from ~100kB/s to
~2.5 MB/s.
Signed-off-by: Vignesh R <vigneshr@ti.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
there's no need to call pm_runtime_get_sync()
followed by pm_runtime_put(). We should, instead,
just call pm_runtime_put_sync() and pm_runtime_disable().
Signed-off-by: Felipe Balbi <balbi@ti.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Currently word completion interrupt is fired for transfer of every
word(8bit to 128bit in size). This adds a lot of overhead, and decreases
r/w throughput. It hardly takes 3us(@48MHz) for 128bit r/w to complete,
hence its better to poll on word complete bit to be set in
QSPI_SPI_STATUS_REG instead of using interrupts.
This increases the throughput by 30% in both read and write case.
So, switch to polling mode instead of interrupts to determine completion
of word transfer.
Signed-off-by: Vignesh R <vigneshr@ti.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Writing invalid command to QSPI_SPI_CMD_REG will terminate current
transfer and de-assert the chip select. This has to be done before
calling spi_finalize_current_message(). Because
spi_finalize_current_message() will mark the end of current message
transfer and schedule the next transfer. If the chipselect is not
de-asserted before calling spi_finalize_current_message() then the next
transfer will overlap with the previous transfer leading to data
corruption.
__spi_pump_message() can be called either from kthread worker context or
directly from the calling process's context. It is possible that these
two calls can race against each other. But race is serialized by
checking whether master->cur_msg == NULL (pointer to msg being handled
by transfer_one() at present). The master->cur_msg is set to NULL when
spi_finalize_current_message() is called on that message, which means
calling spi_finalize_current_message() allows __spi_sync() to pump next
message in calling process context.
Now if spi-ti-qspi calls spi_finalize_current_message() before we
terminate transfer at hardware side, if __spi_pump_message() is called
from process context then the successive transactions can overlap.
Fix this by moving writing invalid command to QSPI_SPI_CMD_REG to
before calling spi_finalize_current_message() call.
Cc: stable@vger.kernel.org # v3.12+
Signed-off-by: Vignesh R <vigneshr@ti.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
TI QSPI has four 32 bit data regsiters which can be used to transfer 16
bytes of data at once. The register group QSPI_SPI_DATA_REG_3,
QSPI_SPI_DATA_REG_2, QSPI_SPI_DATA_REG_1 and QSPI_SPI_DATA_REG is
treated as a single 128-bit word for shifting data in and out. The bit
at QSPI_SPI_DATA_REG_3[31] position is the first bit to be shifted out
in case of 128 bit transfer mode. Therefore the first byte to be written
to flash should be at QSPI_SPI_DATA_REG_3[31-25] position.
Instead of writing 1 byte at a time when interacting with spi-nor flash,
make use of all the four registers so that 16 bytes can be transferred
in one go. This reduces number of register writes and Word Complete
interrupts for a given transfer message size, thereby increasing the
write performance.
Without this patch the raw flash write speed is ~100KB/s, with this
patch the write speed increases to ~400 kB/s on DRA74 EVM.
Signed-off-by: Vignesh R <vigneshr@ti.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Data corruption is seen while reading/writing large data from/to qspi
device because the data register is over written or read before data
is ready which is denoted by busy bit in status register. SO adding
a busy bit check before writing/reading data to/from qspi device.
Signed-off-by: Mugunthan V N <mugunthanvnm@ti.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
return type of wait_for_completion_timeout is unsigned long not int, this
patch uses the return value of wait_for_completion_timeout in the condition
directly rather than assigning it to an incorrect type variable.
Signed-off-by: Nicholas Mc Guire <hofrat@osadl.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
mmap resource requirement is only for memory mapped operations.
If the user does not populate mmap resource, dont call return,
instead we go on for normal spi mode operations.
Signed-off-by: Sourav Poddar <sourav.poddar@ti.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
The purpose of commit 1e8a52e18c
"spi: By default setup spi_masters with 1 chipselect and dynamics bus number"
is to avoid setting default value for bus_num and num_chipselect in spi master
drivers. So let's remove the duplicate code.
Signed-off-by: Axel Lin <axel.lin@ingics.com>
Acked-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Acked-By: David Daney <david.daney@cavium.com>
Acked-by: Stephen Warren <swarren@nvidia.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
The driver name in current code looks like a compatible string which is not
the naming convention for platform drivers.
Fix it and also add modalias since this driver can be built as a module.
Signed-off-by: Axel Lin <axel.lin@ingics.com>
Acked-by: Sourav Poddar <sourav.poddar@ti.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
Make the unit of wlen to be byte, and simplify the code to avoid duplicate
code for different wlen cases.
Signed-off-by: Axel Lin <axel.lin@ingics.com>
Acked-by: Sourav Poddar <sourav.poddar@ti.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
Now platform_get_drvdata() returns the address of qspi rather than master.
Also drop unneeded spi_unregister_master() call in ti_qspi_remove() because
we use devm_spi_register_master() in probe.
commit cbcabb7a30 "spi/qspi: Fix qspi remove path" assumes
platform_get_drvdata() returns address of master. However,
commit 160a061301 "spi/qspi: set correct platform drvdata in ti_qspi_probe()"
pass qspi to platform_set_drvdata().
Signed-off-by: Axel Lin <axel.lin@ingics.com>
Reviewed-by: Sourav Poddar <sourav.poddar@ti.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
Due to the following commit
commit 160a061301
Author: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
Date: Mon Nov 11 14:13:41 2013 +0800
spi/qspi: set correct platform drvdata in ti_qspi_probe()
The ti_qspi_remove() use the platform drvdata as a type of
struct ti_qspi, we should pass correct platform drvdata to
platform_set_drvdata() in ti_qspi_probe().
Signed-off-by: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
Signed-off-by: Mark Brown <broonie@linaro.org>
platform_set_drvdata was changed in the probe, so we need to
correspondingly change deferencing of qspi in runtime resume
path. Else, this will lead to a NULL dereference pointer.
Based on v3.13-rc3
Signed-off-by: Sourav Poddar <sourav.poddar@ti.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
Modify the qspi driver to parse reg information by name.
If "reg names" is not found, then revert back to normal
get resource.
Signed-off-by: Sourav Poddar <sourav.poddar@ti.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
There is a bug in qspi removal path, as a result of which
qspi cannot be removed when used as a module. The patch
solves the bug and qspi can be removed cleanly.
The bugs fixed are:
-pm_runtime used around register access.
- pm_runtime_disable need to be done before removal.
- spi_unregister_master need to be called to unregister
the spi device.
Tested on DRA7 board.
Signed-off-by: Sourav Poddar <sourav.poddar@ti.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
clean up pm_runtime error check in accordance with rest of the check in
the driver.
Signed-off-by: Sourav Poddar <sourav.poddar@ti.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
The ti_qspi_remove() use the platform drvdata as a type of
struct ti_qspi, we should pass correct platform drvdata to
platform_set_drvdata() in ti_qspi_probe().
Signed-off-by: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
Signed-off-by: Mark Brown <broonie@linaro.org>
The here used irq and threaded irq handler is a complete non-sense. After
the status register is read and the source disabled it schedules a thread
(the irq thread) to read the status from the variable, invoke complete()
and then renable the interrupt. Again: schedule a thread which invokes
_only_ complete().
This patch removes this non-sense and we remain with one handler which
invokes complete() if needed.
The device remove path should now disable the interupts.
This has been compile time tested.
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Tested-by: Sourav Poddar <sourav.poddar@ti.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
Add dual/quad read mode bit flag for the master controller.
These check will be used in the spi framework to determine
whether the master controller can do dual/quad read respectively.
Signed-off-by: Sourav Poddar <sourav.poddar@ti.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
Use devm_spi_register_master() to make cleanup paths simpler,
and remove unnecessary remove().
Signed-off-by: Jingoo Han <jg1.han@samsung.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
Add the missing unlock before return from function ti_qspi_start_transfer_one()
in the error handling case.
Signed-off-by: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
Signed-off-by: Mark Brown <broonie@linaro.org>
Fix module device table entry. Without this, there will
be a build failure while trying to build qspi as a module.
Signed-off-by: Sourav Poddar <sourav.poddar@ti.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
Support for multiple lines in SPI framework has been picked[1].
[1]: http://comments.gmane.org/gmane.linux.kernel.spi.devel/14420
Hence, adapting ti qspi driver to support multiple data lines for read.
Signed-off-by: Sourav Poddar <sourav.poddar@ti.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
The patch add basic support for the quad spi controller.
QSPI is a kind of spi module that allows single,
dual and quad read access to external spi devices. The module
has a memory mapped interface which provide direct interface
for accessing data form external spi devices.
The patch will configure controller clocks, device control
register and for defining low level transfer apis which
will be used by the spi framework to transfer data to
the slave spi device(flash in this case).
Test details:
-------------
Tested this on dra7 board.
Test1: Ran mtd_stesstest for 40000 iterations.
- All iterations went through without failure.
Test2: Use mtd utilities:
- flash_erase to erase the flash device
- mtd_debug read to read data back.
- mtd_debug write to write to the data flash.
diff between the write and read data shows zero.
Acked-by: Felipe Balbi<balbi@ti.com>
Reviewed-by: Felipe Balbi<balbi@ti.com>
Signed-off-by: Sourav Poddar <sourav.poddar@ti.com>
Signed-off-by: Mark Brown <broonie@linaro.org>