Mediatek SPI DMA only works when tx and rx buffer addresses are 4-byte
aligned.
Unaligned DMA transactions appeared to work previously, since we the
spi core was incorrectly using the spi_master device for dma, which
had a 0 dma_mask, and therefore the swiotlb dma map operations were
falling back to using bounce buffers. Since each DMA transaction would
use its own buffer, the mapped starting address of each transaction was
always aligned. When doing real DMA, the mapped address will share the
alignment of the raw tx/rx buffer provided by the SPI user, which may or
may not be aligned.
If a buffer is not aligned, we cannot use DMA, and must use FIFO based
transaction instead.
So, this patch implements a scheme that allows using the FIFO for
arbitrary length transactions (larger than the 32-byte FIFO size) by
reloading the FIFO in the interrupt handler.
Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
Cc: Leilk Liu <leilk.liu@mediatek.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
The call to spi_master_put() in mtk_spi_remove() is redundant since
the master is registered using devm_spi_register_master() and no
reference hold by using spi_master_get() in mtk_spi_remove().
This is detected by Coccinelle semantic patch.
Signed-off-by: Wei Yongjun <weiyj.lk@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
This patch merge all identical compat into on mtk_common_compat
and used for all compatible soc.
Signed-off-by: Leilk Liu <leilk.liu@mediatek.com>
Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
In the case where transfer length is not a multiple of 4, KASAN
reports 2 out-of-bounds memory accesses:
- mtk_spi_interrupt: ioread32_rep writes past the end of
trans->rx_buf.
- mtk_spi_fifo_transfer: iowrite32_rep reads past the end of
xfer->tx_buf.
Fix this by using memcpy on the remainder of the bytes.
Signed-off-by: Nicolas Boichat <drinkcat@chromium.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
mtk_spi_probe() calls pm_runtime_enable(), after
pm_runtime_enable() is called, it should call
pm_runtime_disable() in the failure flow.
Signed-off-by: Leilk Liu <leilk.liu@mediatek.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
It's not need to re-read and re-write SPI_CMD_REG, so remove it.
Signed-off-by: Leilk Liu <leilk.liu@mediatek.com>
Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
When only one device is present, it is not necessary to specify
cs_gpios, as the CS line can be controlled by the hardware
module.
Without this patch, older device tree bindings used before
37457607 "spi: mediatek: mt8173 spi multiple devices support"
would cause a panic on boot. This fixes the crash, and
re-introduces backward compatibility.
Signed-off-by: Nicolas Boichat <drinkcat@chromium.org>
Acked-by: Leilk Liu <leilk.liu@mediatek.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
mt8173 IC spi HW has 4 gpio group, it's possible to support
max <= 4 slave devices, even mtk spi HW is not congruent to spi core.
1. When a device do a spi_message transfer, spi HW should know
which pad-group this device is on, and then writes pad-select
register.
2. Mtk pad-select register just selects which MISO pin HW will
receive data. For example, pad-select=1(select spi1 pins), HW just
receives data from spi1 MISO, but it still send waveform to all 4
group cs/clk/mosi. If cs pin in other groups is still spi mode,
after spi1 is selected(by active cs pin), devices on other group
will also be selected.
Signed-off-by: Leilk Liu <leilk.liu@mediatek.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
controller_data is related with device, so move to master->setup
function.
Signed-off-by: Leilk Liu <leilk.liu@mediatek.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
mtk_spi_config() and mtk_spi_prepare_message() both initialize
spi register, so remove mtk_spi_config() and init all register
in mtk_spi_prepare_message().
Signed-off-by: Leilk Liu <leilk.liu@mediatek.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Commit adcbcfea15 ("spi: mediatek: fix spi clock usage error")
added a new sel_clk but introduced bugs in the error paths since
the wrong struct clk pointers are passed to PTR_ERR().
Fixes: adcbcfea15 ("spi: mediatek: fix spi clock usage error")
Signed-off-by: Javier Martinez Canillas <javier@osg.samsung.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Mediatek spi HW can't set cs inactive(keep cs high) directly.
Instead, it supplies pause mode to do it indirectly. If driver
unsets SPI_CMD_PAUSE_MODE in CMD_REG, it also needs to reset
internal state machine to let cs inactive at once.
Signed-off-by: Leilk Liu <leilk.liu@mediatek.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
This patch removes clk_disable_unprepare() in mtk_spi_remove().
clk_disable_prepare/unprepare must be balance, spi-clk is disabled
in mtk_spi_probe, so not needs to disable again.
Signed-off-by: Leilk Liu <leilk.liu@mediatek.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
enable pause interrupt should use SPI_CMD_PAUSE_IE MACRO,
so fix it.
Signed-off-by: Leilk Liu <leilk.liu@mediatek.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
This patch replaces *_time name in mtk_spi_prepare_transfer().
Signed-off-by: Leilk Liu <leilk.liu@mediatek.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
this patch replaces int with u32, deletes TAB, and defines
MTK_SPI_PAUSE_INT_STATUS marco.
Signed-off-by: Leilk Liu <leilk.liu@mediatek.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
mediatek spi driver uses readl/writel, so add linux/io.h,
even so it's implicitly imported by spi/spi.h
Signed-off-by: Leilk Liu <leilk.liu@mediatek.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
This patch removes SPI_CMD_*_OFFSET defines, and uses the BIT(x)
defines instead.
Signed-off-by: Leilk Liu <leilk.liu@mediatek.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
TX_ENDIAN/RX_ENDIAN bits define whether to reverse the endian
order of the data DMA from/to memory. The endian order should
keep the same with cpu endian.
Signed-off-by: Leilk Liu <leilk.liu@mediatek.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
clock in prepare_hardware/unprepare_hardware is redundant
with pm_runtime, so remove them.
Signed-off-by: Leilk Liu <leilk.liu@mediatek.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
writel() already does a cpu_to_le32 conversion, so
remove cpu_to_le32().
Signed-off-by: Leilk Liu <leilk.liu@mediatek.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
This patch fixes endian warnings detected by sparse:
- sparse: incorrect type in argument 1 (different base types)
expected unsigned int [unsigned] val
got restricted __le32 [usertype] <noident>
- sparse: incorrect type in argument 1 (different base types)
expected unsigned int [unsigned] val
got restricted __le32 [usertype] <noident>
Signed-off-by: Leilk Liu <leilk.liu@mediatek.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Remove extra space and make the alias matches driver name.
Signed-off-by: Axel Lin <axel.lin@ingics.com>
Signed-off-by: Mark Brown <broonie@kernel.org>