tegrakernel/kernel/kernel-4.9/drivers/spi/spi-tegra124-slave.c

2292 lines
64 KiB
C
Raw Normal View History

2022-02-16 09:13:02 -06:00
/*
* SPI driver for NVIDIA's Tegra124 SPI Controller.
*
* Copyright (c) 2013-2018, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/clk.h>
#include <linux/reset.h>
#include <linux/completion.h>
#include <linux/delay.h>
#include <linux/dmaengine.h>
#include <linux/dma-mapping.h>
#include <linux/dmapool.h>
#include <linux/err.h>
#include <linux/of_gpio.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi-tegra.h>
#include <linux/clk/tegra.h>
#define SPI_COMMAND1 0x000
#define SPI_BIT_LENGTH(x) (((x) & 0x1f) << 0)
#define SPI_PACKED (1 << 5)
#define SPI_TX_EN (1 << 11)
#define SPI_RX_EN (1 << 12)
#define SPI_BOTH_EN_BYTE (1 << 13)
#define SPI_BOTH_EN_BIT (1 << 14)
#define SPI_LSBYTE_FE (1 << 15)
#define SPI_LSBIT_FE (1 << 16)
#define SPI_BIDIROE (1 << 17)
#define SPI_IDLE_SDA_DRIVE_LOW (0 << 18)
#define SPI_IDLE_SDA_DRIVE_HIGH (1 << 18)
#define SPI_IDLE_SDA_PULL_LOW (2 << 18)
#define SPI_IDLE_SDA_PULL_HIGH (3 << 18)
#define SPI_IDLE_SDA_MASK (3 << 18)
#define SPI_CS_SS_VAL (1 << 20)
#define SPI_CS_SW_HW (1 << 21)
/* SPI_CS_POL_INACTIVE bits are default high */
#define SPI_CS_POL_INACTIVE 22
#define SPI_CS_POL_INACTIVE_0 (1 << 22)
#define SPI_CS_POL_INACTIVE_1 (1 << 23)
#define SPI_CS_POL_INACTIVE_2 (1 << 24)
#define SPI_CS_POL_INACTIVE_3 (1 << 25)
#define SPI_CS_POL_INACTIVE_MASK (0xF << 22)
#define SPI_CS_SEL_0 (0 << 26)
#define SPI_CS_SEL_1 (1 << 26)
#define SPI_CS_SEL_2 (2 << 26)
#define SPI_CS_SEL_3 (3 << 26)
#define SPI_CS_SEL_MASK (3 << 26)
#define SPI_CS_SEL(x) (((x) & 0x3) << 26)
#define SPI_CS(x) (((x) >> 26) & 0x3)
#define SPI_CONTROL_MODE_0 (0 << 28)
#define SPI_CONTROL_MODE_1 (1 << 28)
#define SPI_CONTROL_MODE_2 (2 << 28)
#define SPI_CONTROL_MODE_3 (3 << 28)
#define SPI_CONTROL_MODE_MASK (3 << 28)
#define SPI_MODE_SEL(x) (((x) & 0x3) << 28)
#define SPI_MODE(x) (((x) >> 28) & 0x3)
#define SPI_M_S (1 << 30)
#define SPI_PIO (1 << 31)
#define SPI_CS_TIMING2 0x00C
#define SPI_TRANS_STATUS 0x010
#define SPI_BLK_CNT(val) (((val) >> 0) & 0xFFFF)
#define SPI_SLV_IDLE_COUNT(val) (((val) >> 16) & 0xFF)
#define SPI_RDY (1 << 30)
#define SPI_FIFO_STATUS 0x014
#define SPI_RX_FIFO_EMPTY (1 << 0)
#define SPI_RX_FIFO_FULL (1 << 1)
#define SPI_TX_FIFO_EMPTY (1 << 2)
#define SPI_TX_FIFO_FULL (1 << 3)
#define SPI_RX_FIFO_UNF (1 << 4)
#define SPI_RX_FIFO_OVF (1 << 5)
#define SPI_TX_FIFO_UNF (1 << 6)
#define SPI_TX_FIFO_OVF (1 << 7)
#define SPI_ERR (1 << 8)
#define SPI_TX_FIFO_FLUSH (1 << 14)
#define SPI_RX_FIFO_FLUSH (1 << 15)
#define SPI_TX_FIFO_EMPTY_COUNT(val) (((val) >> 16) & 0x7F)
#define SPI_RX_FIFO_FULL_COUNT(val) (((val) >> 23) & 0x7F)
#define SPI_FRAME_END (1 << 30)
#define SPI_CS_INACTIVE (1 << 31)
#define IS_SPI_CS_INACTIVE(val) (val >> 31)
#define SPI_FIFO_ERROR (SPI_RX_FIFO_UNF | \
SPI_RX_FIFO_OVF | SPI_TX_FIFO_UNF | SPI_TX_FIFO_OVF)
#define SPI_FIFO_EMPTY (SPI_RX_FIFO_EMPTY | SPI_TX_FIFO_EMPTY)
#define SPI_TX_DATA 0x018
#define SPI_RX_DATA 0x01C
#define SPI_DMA_CTL 0x020
#define SPI_TX_TRIG_1 (0 << 15)
#define SPI_TX_TRIG_4 (1 << 15)
#define SPI_TX_TRIG_8 (2 << 15)
#define SPI_TX_TRIG_16 (3 << 15)
#define SPI_TX_TRIG_MASK (3 << 15)
#define SPI_TX_TRIG(val) (((val) >> 15) & 0x3)
#define SPI_RX_TRIG_1 (0 << 19)
#define SPI_RX_TRIG_4 (1 << 19)
#define SPI_RX_TRIG_8 (2 << 19)
#define SPI_RX_TRIG_16 (3 << 19)
#define SPI_RX_TRIG_MASK (3 << 19)
#define SPI_RX_TRIG(val) (((val) >> 19) & 0x3)
#define SPI_IE_TX (1 << 28)
#define SPI_IE_RX (1 << 29)
#define SPI_CONT (1 << 30)
#define SPI_DMA (1 << 31)
#define SPI_DMA_EN SPI_DMA
#define SPI_DMA_BLK 0x024
#define SPI_DMA_BLK_SET(x) (((x) & 0xFFFF) << 0)
#define SPI_TX_FIFO 0x108
#define SPI_RX_FIFO 0x188
#define SPI_INTR_MASK 0x18c
#define SPI_INTR_RX_FIFO_UNF_MASK (1 << 25)
#define SPI_INTR_RX_FIFO_OVF_MASK (1 << 26)
#define SPI_INTR_TX_FIFO_UNF_MASK (1 << 27)
#define SPI_INTR_TX_FIFO_OVF_MASK (1 << 28)
#define SPI_INTR_RDY_MASK (1 << 29)
#define SPI_INTR_FRAME_END_MASK (1 << 30)
#define SPI_INTR_CS_MASK (1 << 31)
#define SPI_MISC_REG 0x194
#define SPI_MISC_EXT_CLK_EN (1 << 30)
#define SPI_MISC_CLKEN_OVERRIDE (1 << 31)
#define MAX_CHIP_SELECT 4
#define SPI_FIFO_DEPTH 64
#define DATA_DIR_TX (1 << 0)
#define DATA_DIR_RX (1 << 1)
#define SPI_DMA_TIMEOUT (msecs_to_jiffies(1000))
#define DEFAULT_SPI_DMA_BUF_LEN (256*1024)
#define TX_FIFO_EMPTY_COUNT_MAX SPI_TX_FIFO_EMPTY_COUNT(0x40)
#define RX_FIFO_FULL_COUNT_ZERO SPI_RX_FIFO_FULL_COUNT(0)
#define MAX_HOLD_CYCLES 16
#define SPI_DEFAULT_SPEED 25000000
#define SPI_FIFO_DEPTH 64
#define SPI_FIFO_FLUSH_MAX_DELAY 2000
#define MAX_PACKETS (1 << 16)
/* multiplication facotr for slave timeout, See code below */
#define DELAY_MUL_FACTOR 1000
#define PROFILE_SPI_SLAVE /* profile spi sw overhead */
#define VERBOSE_DUMP_REGS /* register dumps */
#define TEGRA_SPI_SLAVE_DEBUG /* to enable debug interfaces, sysfs ... */
#define dump_xfer(_t, _x) \
dev_dbg(((_t))->dev, "%s%s len:%d bpw:%d %dus %dHz", \
(_x)->rx_buf ? "Rx" : "", (_x)->tx_buf ? "Tx" : "", \
(_x)->len, (_x)->bits_per_word & 0xff, \
(_x)->delay_usecs & 0xffff, (_x)->speed_hz);
#define dump_sw_state(_t, _f, ...) \
do { \
dev_dbg((_t)->dev, _f, __VA_ARGS__); \
dev_dbg((_t)->dev, "[SW] cntrlr: %dHz bypw:%d dma?:%d dir?:%d " \
"dmasz:%d rx-trig:%d vlen?:%d pack?:%d force_unp?:%d\n",\
(_t)->cur_speed, (_t)->bytes_per_word, \
(_t)->is_curr_dma_xfer, (_t)->cur_direction, \
(_t)->curr_dma_words, (_t)->rx_trig_words, \
(_t)->variable_length_transfer, (_t)->is_packed, \
(_t)->force_unpacked_mode); \
} while (0)
#ifdef VERBOSE_DUMP_REGS
#define dump_regs(_log, _t, _f, ...) \
do { \
uint32_t fifo, cmd, dma_ctl, dma_blk, trans; \
fifo = tegra_spi_readl((_t), SPI_FIFO_STATUS); \
cmd = tegra_spi_readl((_t), SPI_COMMAND1); \
dma_ctl = tegra_spi_readl((_t), SPI_DMA_CTL); \
dma_blk = tegra_spi_readl((_t), SPI_DMA_BLK); \
trans = tegra_spi_readl((_t), SPI_TRANS_STATUS); \
dev_##_log(&((_t)->master->dev), _f, ##__VA_ARGS__); \
dev_##_log(&((_t)->master->dev), \
" CMD[%08x]: %s %s M%d CS%d [%c%c%c%c] %s " \
"%s %s %s %s %db " \
"TRANS[%08x]:%s I:%d B:%d\n" \
" FIFO[%08x]:RxF:%d TxE:%d Err[%s%s%s] " \
"RxSTA[%s%s%s%s] TxSTA[%s%s%s%s]" \
"DMA[%08x]:%s %s %s %s " \
"RxTr:%d TxTr:%d B:%d\n", \
/* command */ \
cmd, \
cmd & SPI_PIO ? "Go" : "", \
cmd & SPI_M_S ? "Ma" : "Sl", \
SPI_MODE(cmd), SPI_CS(cmd), \
(cmd & SPI_CS_POL_INACTIVE_0) ? 'H' : 'L', \
(cmd & SPI_CS_POL_INACTIVE_1) ? 'H' : 'L', \
(cmd & SPI_CS_POL_INACTIVE_2) ? 'H' : 'L', \
(cmd & SPI_CS_POL_INACTIVE_3) ? 'H' : 'L', \
(cmd & SPI_LSBYTE_FE) ? "LSB" : "MSB", \
(cmd & SPI_LSBIT_FE) ? "LSb" : "MSb", \
(cmd & SPI_RX_EN) ? "Rx" : "", \
(cmd & SPI_TX_EN) ? "Tx" : "", \
(cmd & SPI_PACKED) ? "Pa" : "Un", \
(SPI_BIT_LENGTH(cmd) + 1), \
/* transfer status */ \
trans, \
(trans & SPI_RDY) ? "RDY" : "BSY", \
SPI_SLV_IDLE_COUNT(trans), \
SPI_BLK_CNT(trans), \
/* fifo */ \
fifo, \
SPI_RX_FIFO_FULL_COUNT(fifo), \
SPI_TX_FIFO_EMPTY_COUNT(fifo), \
(fifo & SPI_CS_INACTIVE) ? "Cs" : "", \
(fifo & SPI_FRAME_END) ? "Fe" : "" , \
(fifo & SPI_FIFO_ERROR) ? "Er" : "" , \
(fifo & SPI_RX_FIFO_OVF) ? "O" : "" , \
(fifo & SPI_RX_FIFO_UNF) ? "U" : "" , \
(fifo & SPI_RX_FIFO_FULL) ? "F" : "" , \
(fifo & SPI_RX_FIFO_EMPTY) ? "E" : "" , \
(fifo & SPI_TX_FIFO_OVF) ? "O" : "" , \
(fifo & SPI_TX_FIFO_UNF) ? "U" : "" , \
(fifo & SPI_TX_FIFO_FULL) ? "F" : "" , \
(fifo & SPI_TX_FIFO_EMPTY) ? "E" : "" , \
/* dma ctl */ \
dma_ctl, \
(dma_ctl & SPI_DMA_EN) ? "De" : "", \
(dma_ctl & SPI_CONT) ? "Co" : "", \
(dma_ctl & SPI_IE_RX) ? "RxIE" : "", \
(dma_ctl & SPI_IE_TX) ? "TxIE" : "", \
SPI_RX_TRIG(dma_ctl), \
SPI_TX_TRIG(dma_ctl), \
/* dma blk */ \
SPI_DMA_BLK_SET(dma_blk)); \
} while (0)
#else
#define dump_regs(_log, _t, _f, ...) \
dev_##_log(&((_t)->master->dev), _f, ##__VA_ARGS__);
#endif
#define print_fifo_word(_m, _t, _c, _x) \
dev_dbg((_t)->dev, \
"%s[%d] %02lx %02lx %02lx %02lx\n", \
(_m), (_c), \
(_x) & 0xff, ((_x) >> 8) & 0xff, \
((_x) >> 16) & 0xff, ((_x) >> 24) & 0xff);
/* convert size in fifo bytes to number of packets */
/* for unpacked, each packet occupies 4 bytes, i.e., a fifo word
* for packed the each fifo word can be occupied by multiple packets
* as number of bytes in each packet.
*/
#define fifo_bytes_to_packets(_t, _sz) \
((_t)->is_packed ? (_sz)/(_t)->bytes_per_word : (_sz)/4);
struct tegra_spi_chip_data {
bool intr_mask_reg;
bool mask_cs_inactive_intr;
bool new_features;
};
struct tegra_spi_data {
struct device *dev;
struct spi_master *master;
spinlock_t lock;
struct clk *clk;
struct reset_control *rstc;
void __iomem *base;
phys_addr_t phys;
unsigned irq;
bool clock_always_on;
u32 spi_max_frequency;
u32 cur_speed;
unsigned min_div;
struct spi_device *cur_spi;
unsigned words_per_32bit;
/* bypw, rounding to nearest byte, irrespective of packed/unpacked */
unsigned bytes_per_word;
unsigned curr_dma_words;
unsigned cur_direction;
unsigned dma_buf_size;
unsigned max_buf_size;
bool is_curr_dma_xfer;
bool variable_length_transfer;
/* Slave Ready Polarity (true: Active High, false: Active Low) */
int gpio_slave_ready;
bool slave_ready_active_high;
struct completion rx_dma_complete;
struct completion tx_dma_complete;
u32 tx_status;
u32 rx_status;
bool reset_ctrl_status;
u32 status_reg;
bool is_packed;
u32 command1_reg;
u32 dma_control_reg;
u32 def_command1_reg;
struct completion xfer_completion;
struct spi_transfer *curr_xfer;
struct dma_chan *rx_dma_chan;
u32 *rx_dma_buf;
dma_addr_t rx_dma_phys;
struct dma_async_tx_descriptor *rx_dma_desc;
struct dma_chan *tx_dma_chan;
u32 *tx_dma_buf;
dma_addr_t tx_dma_phys;
struct dma_async_tx_descriptor *tx_dma_desc;
const struct tegra_spi_chip_data *chip_data;
struct tegra_spi_device_controller_data cdata[MAX_CHIP_SELECT];
spi_callback spi_slave_ready_callback;
spi_callback spi_slave_isr_callback;
void *client_data;
atomic_t isr_expected;
u32 words_to_transfer;
int curr_rx_pos;
/* common variable for tx and rx to update the actual length */
int curr_pos;
int rx_dma_len;
int rem_len;
int rx_trig_words;
int force_unpacked_mode;
bool lsbyte_first;
#ifdef PROFILE_SPI_SLAVE
ktime_t start_time;
ktime_t end_time;
int profile_size;
#endif
};
static int tegra_spi_runtime_suspend(struct device *dev);
static int tegra_spi_runtime_resume(struct device *dev);
static int tegra_spi_validate_request(struct spi_device *spi,
struct tegra_spi_data *tspi, struct spi_transfer *t);
static int tegra_spi_ext_clk_enable(bool enable, struct tegra_spi_data *tspi);
#ifdef TEGRA_SPI_SLAVE_DEBUG
static ssize_t force_unpacked_mode_set(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct tegra_spi_data *tspi;
struct spi_master *master = dev_get_drvdata(dev);
if (master) {
tspi = spi_master_get_devdata(master);
if (tspi && count) {
tspi->force_unpacked_mode = ((buf[0] - '0') > 0);
return count;
}
}
return -ENODEV;
}
static ssize_t force_unpacked_mode_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct tegra_spi_data *tspi;
struct spi_master *master = dev_get_drvdata(dev);
if (master) {
tspi = spi_master_get_devdata(master);
return sprintf(buf, "%d", tspi->force_unpacked_mode);
}
return -ENODEV;
}
static DEVICE_ATTR(force_unpacked_mode, 0644, force_unpacked_mode_show,
force_unpacked_mode_set);
#endif
static inline unsigned long tegra_spi_readl(struct tegra_spi_data *tspi,
unsigned long reg)
{
return readl(tspi->base + reg);
}
static inline void tegra_spi_writel(struct tegra_spi_data *tspi,
unsigned long val, unsigned long reg)
{
writel(val, tspi->base + reg);
/* TODO: remove the forced fence read below */
/* Read back register to make sure that register writes completed */
if (reg != SPI_TX_FIFO)
readl(tspi->base + SPI_COMMAND1);
}
static inline void tegra_spi_fence(struct tegra_spi_data *tspi)
{
/* Read back register to make sure that register writes completed */
readl(tspi->base + SPI_COMMAND1);
}
/* FIXME: the name of the function */
int tegra124_spi_slave_register_callback(struct spi_device *spi,
spi_callback func_ready, spi_callback func_isr, void *client_data)
{
struct tegra_spi_data *tspi = spi_master_get_devdata(spi->master);
/* Expect atleast one callback function. */
if ((!tspi) || (!func_ready && !func_isr))
return -EINVAL;
tspi->spi_slave_ready_callback = func_ready;
tspi->spi_slave_isr_callback = func_isr;
tspi->client_data = client_data;
return 0;
}
EXPORT_SYMBOL_GPL(tegra124_spi_slave_register_callback);
static void tegra_spi_clear_status(struct tegra_spi_data *tspi)
{
unsigned long val;
/* Write 1 to clear status register */
val = tegra_spi_readl(tspi, SPI_TRANS_STATUS);
tegra_spi_writel(tspi, val, SPI_TRANS_STATUS);
if (tspi->chip_data->intr_mask_reg) {
val = tegra_spi_readl(tspi, SPI_INTR_MASK);
if (!(val & SPI_INTR_RDY_MASK)) {
val |= (SPI_INTR_CS_MASK |
SPI_INTR_FRAME_END_MASK |
SPI_INTR_RDY_MASK |
SPI_INTR_RX_FIFO_UNF_MASK |
SPI_INTR_TX_FIFO_UNF_MASK |
SPI_INTR_RX_FIFO_OVF_MASK |
SPI_INTR_TX_FIFO_OVF_MASK);
tegra_spi_writel(tspi, val, SPI_INTR_MASK);
}
}
/* Clear fifo status error if any */
val = tegra_spi_readl(tspi, SPI_FIFO_STATUS);
tegra_spi_writel(tspi, val &
(SPI_FRAME_END | SPI_CS_INACTIVE | SPI_ERR |
SPI_TX_FIFO_UNF | SPI_TX_FIFO_OVF |
SPI_RX_FIFO_OVF | SPI_RX_FIFO_UNF),
SPI_FIFO_STATUS);
}
static void reset_controller(struct tegra_spi_data *tspi)
{
if (!tspi->reset_ctrl_status)
return;
/* TODO: Debug the reset sequence */
if (tspi->is_curr_dma_xfer &&
(tspi->cur_direction & DATA_DIR_TX))
dmaengine_terminate_all(tspi->tx_dma_chan);
if (tspi->is_curr_dma_xfer &&
(tspi->cur_direction & DATA_DIR_RX))
dmaengine_terminate_all(tspi->rx_dma_chan);
wmb(); /* barrier for dma terminate to happen */
reset_control_reset(tspi->rstc);
/* restore default value */
tegra_spi_writel(tspi, tspi->def_command1_reg, SPI_COMMAND1);
/* set CS inactive b/w packets to mask CS_INACTIVE interrupts */
if (tspi->chip_data->mask_cs_inactive_intr)
tegra_spi_writel(tspi, 0, SPI_CS_TIMING2);
tegra_spi_clear_status(tspi);
tegra_spi_writel(tspi, tspi->dma_control_reg, SPI_DMA_CTL);
dump_regs(dbg, tspi, "after controller reset");
tspi->reset_ctrl_status = false;
}
static unsigned tegra_spi_calculate_curr_xfer_param(
struct spi_device *spi, struct tegra_spi_data *tspi,
struct spi_transfer *t)
{
unsigned remain_len = t->len;
unsigned max_word;
unsigned bits_per_word;
unsigned max_len;
unsigned total_fifo_words;
bits_per_word = t->bits_per_word ? t->bits_per_word :
spi->bits_per_word;
tspi->bytes_per_word = (bits_per_word - 1) / 8 + 1;
if (!tspi->force_unpacked_mode &&
(bits_per_word == 8 || bits_per_word == 16)) {
tspi->is_packed = 1;
tspi->words_per_32bit = 32/bits_per_word;
} else {
tspi->is_packed = 0;
tspi->words_per_32bit = 1;
}
if (tspi->is_packed) {
max_len = min(remain_len, tspi->max_buf_size);
tspi->curr_dma_words = max_len/tspi->bytes_per_word;
total_fifo_words = (max_len + 3)/4;
} else {
max_word = (remain_len - 1) / tspi->bytes_per_word + 1;
max_word = min(max_word, tspi->max_buf_size/4);
tspi->curr_dma_words = max_word;
total_fifo_words = max_word;
}
return total_fifo_words;
}
static unsigned tegra_spi_fill_tx_fifo_from_client_txbuf(
struct tegra_spi_data *tspi, struct spi_transfer *t)
{
unsigned nbytes;
unsigned tx_empty_count;
unsigned max_n_32bit;
unsigned i, count;
unsigned long x;
unsigned int written_words;
unsigned fifo_words_left;
u8 *tx_buf = (u8 *)t->tx_buf;
tx_empty_count = SPI_TX_FIFO_EMPTY_COUNT(
tegra_spi_readl(tspi, SPI_FIFO_STATUS));
if (tspi->is_packed) {
fifo_words_left = tx_empty_count * tspi->words_per_32bit;
written_words = min(fifo_words_left, tspi->curr_dma_words);
nbytes = written_words * tspi->bytes_per_word;
max_n_32bit = DIV_ROUND_UP(nbytes, 4);
for (count = 0; count < max_n_32bit; count++) {
x = 0;
for (i = 0; (i < 4) && nbytes; i++, nbytes--)
x |= (*tx_buf++) << (i*8);
print_fifo_word("TxFIFO", tspi, count, x);
tegra_spi_writel(tspi, x, SPI_TX_FIFO);
}
} else {
max_n_32bit = min(tspi->curr_dma_words, tx_empty_count);
written_words = max_n_32bit;
nbytes = written_words * tspi->bytes_per_word;
for (count = 0; count < max_n_32bit; count++) {
x = 0;
for (i = 0; nbytes && (i < tspi->bytes_per_word);
i++, nbytes--)
x |= ((*tx_buf++) << i*8);
print_fifo_word("TxFIFO", tspi, count, x);
tegra_spi_writel(tspi, x, SPI_TX_FIFO);
}
}
return written_words;
}
/* FIFO mode rx data copy from SPI-FIFO to client buffer */
static unsigned int tegra_spi_read_rx_fifo_to_client_rxbuf(
struct tegra_spi_data *tspi, struct spi_transfer *t)
{
unsigned rx_full_count;
unsigned i, count;
unsigned long x;
unsigned recv_len, npackets;
u8 *rx_buf = (u8 *)t->rx_buf + tspi->curr_rx_pos;
rx_full_count = SPI_RX_FIFO_FULL_COUNT(
tegra_spi_readl(tspi, SPI_FIFO_STATUS));
/* actual bytes to be copied */
npackets = fifo_bytes_to_packets(tspi, rx_full_count*4);
npackets = min(npackets, tspi->words_to_transfer);
recv_len = npackets * tspi->bytes_per_word;
if (tspi->is_packed) {
int j = recv_len;
if (rx_full_count != DIV_ROUND_UP(tspi->words_to_transfer *
tspi->bytes_per_word, 4))
dump_regs(dbg, tspi,
"fifo-cnt[%d] != trans-cnt[%d]",
rx_full_count, tspi->words_to_transfer);
for (count = 0; j && count < rx_full_count; count++) {
x = tegra_spi_readl(tspi, SPI_RX_FIFO);
print_fifo_word("RxFIFO", tspi, count, x);
for (i = 0; j && (i < 4); i++, j--)
*rx_buf++ = (x >> i*8) & 0xFF;
}
} else {
unsigned int bits_per_word;
bits_per_word = t->bits_per_word ? t->bits_per_word :
tspi->cur_spi->bits_per_word;
if (rx_full_count != tspi->words_to_transfer)
dump_regs(dbg, tspi,
"fifo-cnt[%d] != trans-cnt[%d]",
rx_full_count, tspi->words_to_transfer);
rx_full_count = min(rx_full_count, tspi->words_to_transfer);
for (count = 0; count < rx_full_count; count++) {
x = tegra_spi_readl(tspi, SPI_RX_FIFO);
print_fifo_word("RxFIFO", tspi, count, x);
for (i = 0; (i < tspi->bytes_per_word); i++)
*rx_buf++ = (x >> (i*8)) & 0xFF;
}
}
tspi->words_to_transfer -= npackets;
tspi->rem_len -= recv_len;
tspi->curr_rx_pos += recv_len;
return recv_len;
}
static void tegra_spi_copy_client_txbuf_to_spi_txbuf(
struct tegra_spi_data *tspi, struct spi_transfer *t)
{
unsigned len;
/* Make the dma buffer to read by cpu */
dma_sync_single_for_cpu(tspi->dev, tspi->tx_dma_phys,
tspi->dma_buf_size, DMA_TO_DEVICE);
if (tspi->is_packed) {
len = tspi->curr_dma_words * tspi->bytes_per_word;
memcpy(tspi->tx_dma_buf, t->tx_buf, len);
} else {
unsigned int i;
unsigned int count;
u8 *tx_buf = (u8 *)t->tx_buf;
unsigned consume = tspi->curr_dma_words * tspi->bytes_per_word;
unsigned int x;
for (count = 0; count < tspi->curr_dma_words; count++) {
x = 0;
for (i = 0; consume && (i < tspi->bytes_per_word);
i++, consume--)
x |= ((*tx_buf++) << i * 8);
tspi->tx_dma_buf[count] = x;
}
}
/* Make the dma buffer to read by dma */
dma_sync_single_for_device(tspi->dev, tspi->tx_dma_phys,
tspi->dma_buf_size, DMA_TO_DEVICE);
}
static unsigned int tegra_spi_copy_spi_rxbuf_to_client_rxbuf(
struct tegra_spi_data *tspi, struct spi_transfer *t)
{
unsigned dma_bytes, npackets;
/* Make the dma buffer to read by cpu */
dma_sync_single_for_cpu(tspi->dev, tspi->rx_dma_phys,
tspi->dma_buf_size, DMA_FROM_DEVICE);
dma_bytes = tspi->words_to_transfer * tspi->bytes_per_word;
npackets = tspi->words_to_transfer;
if (tspi->is_packed) {
memcpy(t->rx_buf, tspi->rx_dma_buf, dma_bytes);
} else {
unsigned int i;
unsigned int count;
unsigned char *rx_buf = t->rx_buf;
unsigned int x;
unsigned int bits_per_word;
bits_per_word = t->bits_per_word ? t->bits_per_word :
tspi->cur_spi->bits_per_word;
/* copy received dma words to rx client buffer */
for (count = 0; count < tspi->words_to_transfer; count++) {
x = tspi->rx_dma_buf[count];
for (i = 0; (i < tspi->bytes_per_word); i++)
*rx_buf++ = (x >> (i*8)) & 0xFF;
}
}
tspi->words_to_transfer -= npackets;
tspi->rem_len -= npackets*tspi->bytes_per_word;
tspi->curr_rx_pos += npackets*tspi->bytes_per_word;
if (tspi->words_to_transfer)
dma_bytes += tegra_spi_read_rx_fifo_to_client_rxbuf(tspi, t);
/* Make the dma buffer to read by dma */
dma_sync_single_for_device(tspi->dev, tspi->rx_dma_phys,
tspi->dma_buf_size, DMA_FROM_DEVICE);
return dma_bytes;
}
static void tegra_spi_rx_dma_complete(void *args)
{
struct tegra_spi_data *tspi = args;
dev_dbg(tspi->dev, "rx-dma-complete\n");
complete(&tspi->rx_dma_complete);
/* TODO: how to get transfer size from dma */
}
static void tegra_spi_tx_dma_complete(void *args)
{
struct tegra_spi_data *tspi = args;
dev_dbg(tspi->dev, "tx-dma-complete\n");
complete(&tspi->tx_dma_complete);
}
static int tegra_spi_start_tx_dma(struct tegra_spi_data *tspi, int len)
{
reinit_completion(&tspi->tx_dma_complete);
dev_dbg(tspi->dev, "Starting tx dma for len:%d\n", len);
tspi->tx_dma_desc = dmaengine_prep_slave_single(tspi->tx_dma_chan,
tspi->tx_dma_phys, len, DMA_MEM_TO_DEV,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!tspi->tx_dma_desc) {
dev_err(tspi->dev, "Not able to get desc for Tx\n");
return -EIO;
}
tspi->tx_dma_desc->callback = tegra_spi_tx_dma_complete;
tspi->tx_dma_desc->callback_param = tspi;
dmaengine_submit(tspi->tx_dma_desc);
dma_async_issue_pending(tspi->tx_dma_chan);
return 0;
}
static int tegra_spi_start_rx_dma(struct tegra_spi_data *tspi, int len)
{
reinit_completion(&tspi->rx_dma_complete);
tspi->rx_dma_len = len;
dev_dbg(tspi->dev, "Starting rx dma for len:%d\n", len);
tspi->rx_dma_desc = dmaengine_prep_slave_single(tspi->rx_dma_chan,
tspi->rx_dma_phys, len, DMA_DEV_TO_MEM,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!tspi->rx_dma_desc) {
dev_err(tspi->dev, "Not able to get desc for Rx\n");
return -EIO;
}
tspi->rx_dma_desc->callback = tegra_spi_rx_dma_complete;
tspi->rx_dma_desc->callback_param = tspi;
dmaengine_submit(tspi->rx_dma_desc);
dma_async_issue_pending(tspi->rx_dma_chan);
return 0;
}
static int check_and_clear_fifo(struct tegra_spi_data *tspi)
{
unsigned long status;
int cnt = SPI_FIFO_FLUSH_MAX_DELAY;
/* Make sure that Rx and Tx fifo are empty */
status = tegra_spi_readl(tspi, SPI_FIFO_STATUS);
if ((status & SPI_FIFO_EMPTY) != SPI_FIFO_EMPTY) {
/* flush the fifo */
status |= (SPI_RX_FIFO_FLUSH | SPI_TX_FIFO_FLUSH);
tegra_spi_writel(tspi, status, SPI_FIFO_STATUS);
do {
status = tegra_spi_readl(tspi, SPI_FIFO_STATUS);
if ((status & SPI_FIFO_EMPTY) == SPI_FIFO_EMPTY)
return 0;
udelay(1);
} while (cnt--);
dev_err(tspi->dev,
"Rx/Tx fifo are not empty status 0x%08lx\n", status);
return -EIO;
}
return 0;
}
static inline void tegra_spi_slave_busy(struct tegra_spi_data *tspi)
{
int deassert_val;
if (tspi->slave_ready_active_high)
deassert_val = 0;
else
deassert_val = 1;
/* Deassert ready line to indicate Busy */
if (gpio_is_valid(tspi->gpio_slave_ready))
gpio_set_value(tspi->gpio_slave_ready, deassert_val);
}
static inline void tegra_spi_slave_ready(struct tegra_spi_data *tspi)
{
int assert_val;
if (tspi->slave_ready_active_high)
assert_val = 1;
else
assert_val = 0;
/* Assert ready line to indicate Ready */
if (gpio_is_valid(tspi->gpio_slave_ready))
gpio_set_value(tspi->gpio_slave_ready, assert_val);
}
static inline int tegra_spi_ext_clk_enable(bool enable,
struct tegra_spi_data *tspi)
{
unsigned long misc_reg = 0;
int ret = 0;
if (tspi->chip_data->new_features) {
/* Enable external clock bit in SPI_MISC_REG */
if (enable)
misc_reg |= SPI_MISC_EXT_CLK_EN;
else
misc_reg &= (~SPI_MISC_EXT_CLK_EN);
tegra_spi_writel(tspi, misc_reg, SPI_MISC_REG);
}
return ret;
}
static int tegra_spi_start_dma_based_transfer(
struct tegra_spi_data *tspi, struct spi_transfer *t)
{
unsigned long val, flags;
unsigned long intr_mask;
unsigned int len;
int ret = 0;
int maxburst = 0;
struct dma_slave_config dma_sconfig;
/* Make sure that Rx and Tx fifo are empty */
ret = check_and_clear_fifo(tspi);
if (ret != 0)
return ret;
val = SPI_DMA_BLK_SET(tspi->curr_dma_words - 1);
tegra_spi_writel(tspi, val, SPI_DMA_BLK);
val = 0; /* Reset the variable for reuse */
if (tspi->is_packed)
len = DIV_ROUND_UP(tspi->curr_dma_words * tspi->bytes_per_word,
4) * 4;
else
len = tspi->curr_dma_words * 4;
if (!tspi->rx_trig_words) {
/* Set attention level based on length of transfer */
if (len & 0xF) {
val |= SPI_TX_TRIG_1 | SPI_RX_TRIG_1;
maxburst = 1;
} else if (((len) >> 4) & 0x1) {
val |= SPI_TX_TRIG_4 | SPI_RX_TRIG_4;
maxburst = 4;
} else {
val |= SPI_TX_TRIG_8 | SPI_RX_TRIG_8;
maxburst = 8;
}
} else { /* dt can override the trigger */
if (tspi->rx_trig_words == 4) {
val |= SPI_TX_TRIG_4 | SPI_RX_TRIG_4;
maxburst = 4;
} else if (tspi->rx_trig_words == 8) {
val |= SPI_TX_TRIG_8 | SPI_RX_TRIG_8;
maxburst = 8;
}
}
if (tspi->variable_length_transfer &&
tspi->chip_data->new_features &&
(tspi->cur_direction & DATA_DIR_RX)) {
val &= ~SPI_RX_TRIG_MASK;
val |= SPI_RX_TRIG_1;
}
if (tspi->chip_data->intr_mask_reg) {
if ((tspi->cur_direction & DATA_DIR_TX) ||
(tspi->cur_direction & DATA_DIR_RX)) {
intr_mask = tegra_spi_readl(tspi, SPI_INTR_MASK);
intr_mask &= ~(SPI_INTR_CS_MASK |
SPI_INTR_RDY_MASK |
SPI_INTR_RX_FIFO_UNF_MASK |
SPI_INTR_TX_FIFO_UNF_MASK |
SPI_INTR_RX_FIFO_OVF_MASK |
SPI_INTR_TX_FIFO_OVF_MASK);
tegra_spi_writel(tspi, intr_mask, SPI_INTR_MASK);
}
} else if (!tspi->chip_data->new_features) {
if (tspi->cur_direction & DATA_DIR_TX)
val |= SPI_IE_TX;
if (tspi->cur_direction & DATA_DIR_RX)
val |= SPI_IE_RX;
}
tegra_spi_writel(tspi, val, SPI_DMA_CTL);
tspi->dma_control_reg = val;
if (tspi->cur_direction & DATA_DIR_TX) {
dma_sconfig.dst_addr = tspi->phys + SPI_TX_FIFO;
dma_sconfig.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
dma_sconfig.dst_maxburst = maxburst;
dmaengine_slave_config(tspi->tx_dma_chan, &dma_sconfig);
tegra_spi_copy_client_txbuf_to_spi_txbuf(tspi, t);
ret = tegra_spi_start_tx_dma(tspi, len);
if (ret < 0) {
dev_err(tspi->dev,
"Starting tx dma failed, err %d\n", ret);
return ret;
}
}
if (tspi->cur_direction & DATA_DIR_RX) {
/* Make the dma buffer to read by dma */
dma_sync_single_for_device(tspi->dev, tspi->rx_dma_phys,
tspi->dma_buf_size, DMA_FROM_DEVICE);
dma_sconfig.src_addr = tspi->phys + SPI_RX_FIFO;
dma_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
if (tspi->variable_length_transfer &&
tspi->chip_data->new_features)
dma_sconfig.src_maxburst = 1;
else
dma_sconfig.src_maxburst = maxburst;
dmaengine_slave_config(tspi->rx_dma_chan, &dma_sconfig);
/* align Rx Dma to receive size */
ret = tegra_spi_start_rx_dma(tspi,
(len >> tspi->rx_trig_words) << tspi->rx_trig_words);
if (ret < 0) {
dev_err(tspi->dev,
"Starting rx dma failed, err %d\n", ret);
if (tspi->cur_direction & DATA_DIR_TX)
dmaengine_terminate_all(tspi->tx_dma_chan);
return ret;
}
}
tspi->is_curr_dma_xfer = true;
tspi->dma_control_reg = val;
val |= SPI_DMA_EN;
dump_regs(dbg, tspi, "Before DMA EN");
/* atomically set both sw/hw isr enable */
spin_lock_irqsave(&tspi->lock, flags);
atomic_set(&tspi->isr_expected, 1);
wmb(); /* to complete the register writes and the atomic var update */
tegra_spi_writel(tspi, val, SPI_DMA_CTL);
tegra_spi_fence(tspi);
spin_unlock_irqrestore(&tspi->lock, flags);
ret = tegra_spi_ext_clk_enable(true, tspi);
return ret;
}
static int tegra_spi_start_cpu_based_transfer(
struct tegra_spi_data *tspi, struct spi_transfer *t)
{
unsigned long val, flags;
unsigned long intr_mask;
unsigned cur_words;
int ret;
ret = check_and_clear_fifo(tspi);
if (ret != 0)
return ret;
if (tspi->cur_direction & DATA_DIR_TX)
cur_words = tegra_spi_fill_tx_fifo_from_client_txbuf(tspi, t);
else
cur_words = tspi->curr_dma_words;
val = SPI_DMA_BLK_SET(cur_words - 1);
tegra_spi_writel(tspi, val, SPI_DMA_BLK);
val = 0;
if (tspi->chip_data->intr_mask_reg) {
if ((tspi->cur_direction & DATA_DIR_TX) ||
(tspi->cur_direction & DATA_DIR_RX)) {
intr_mask = tegra_spi_readl(tspi, SPI_INTR_MASK);
intr_mask &= ~(SPI_INTR_CS_MASK |
SPI_INTR_RDY_MASK |
SPI_INTR_RX_FIFO_UNF_MASK |
SPI_INTR_TX_FIFO_UNF_MASK |
SPI_INTR_RX_FIFO_OVF_MASK |
SPI_INTR_TX_FIFO_OVF_MASK);
tegra_spi_writel(tspi, intr_mask, SPI_INTR_MASK);
}
} else {
if (tspi->cur_direction & DATA_DIR_TX)
val |= SPI_IE_TX;
if (tspi->cur_direction & DATA_DIR_RX)
val |= SPI_IE_RX;
}
tegra_spi_writel(tspi, val, SPI_DMA_CTL);
tspi->dma_control_reg = val;
tspi->is_curr_dma_xfer = false;
val = tspi->command1_reg;
val |= SPI_PIO;
dump_regs(dbg, tspi, "Before PIO EN");
/* atomically set both sw/hw isr enable */
spin_lock_irqsave(&tspi->lock, flags);
atomic_set(&tspi->isr_expected, 1);
wmb(); /* to complete the register writes and the atomic var update */
tegra_spi_writel(tspi, val, SPI_COMMAND1);
tegra_spi_fence(tspi);
spin_unlock_irqrestore(&tspi->lock, flags);
ret = tegra_spi_ext_clk_enable(true, tspi);
return ret;
}
static int tegra_spi_init_dma_param(struct tegra_spi_data *tspi,
bool dma_to_memory)
{
struct dma_chan *dma_chan;
u32 *dma_buf;
dma_addr_t dma_phys;
int ret;
struct dma_slave_config dma_sconfig;
dma_chan = dma_request_slave_channel_reason(tspi->dev,
dma_to_memory ? "rx" : "tx");
if (IS_ERR(dma_chan)) {
ret = PTR_ERR(dma_chan);
if (ret != -EPROBE_DEFER)
dev_err(tspi->dev,
"Dma channel is not available: %d\n", ret);
return ret;
}
dma_buf = dma_alloc_coherent(tspi->dev, tspi->dma_buf_size,
&dma_phys, GFP_KERNEL);
if (!dma_buf) {
dev_err(tspi->dev, "Not able to allocate the dma buffer\n");
dma_release_channel(dma_chan);
return -ENOMEM;
}
if (dma_to_memory) {
dma_sconfig.src_addr = tspi->phys + SPI_RX_FIFO;
dma_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
dma_sconfig.src_maxburst = tspi->rx_trig_words;
} else {
dma_sconfig.dst_addr = tspi->phys + SPI_TX_FIFO;
dma_sconfig.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
dma_sconfig.dst_maxburst = tspi->rx_trig_words;
}
ret = dmaengine_slave_config(dma_chan, &dma_sconfig);
if (ret)
goto scrub;
if (dma_to_memory) {
tspi->rx_dma_chan = dma_chan;
tspi->rx_dma_buf = dma_buf;
tspi->rx_dma_phys = dma_phys;
} else {
tspi->tx_dma_chan = dma_chan;
tspi->tx_dma_buf = dma_buf;
tspi->tx_dma_phys = dma_phys;
}
return 0;
scrub:
dma_free_coherent(tspi->dev, tspi->dma_buf_size, dma_buf, dma_phys);
dma_release_channel(dma_chan);
return ret;
}
static void tegra_spi_deinit_dma_param(struct tegra_spi_data *tspi,
bool dma_to_memory)
{
u32 *dma_buf;
dma_addr_t dma_phys;
struct dma_chan *dma_chan;
if (dma_to_memory) {
dma_buf = tspi->rx_dma_buf;
dma_chan = tspi->rx_dma_chan;
dma_phys = tspi->rx_dma_phys;
tspi->rx_dma_chan = NULL;
tspi->rx_dma_buf = NULL;
} else {
dma_buf = tspi->tx_dma_buf;
dma_chan = tspi->tx_dma_chan;
dma_phys = tspi->tx_dma_phys;
tspi->tx_dma_buf = NULL;
tspi->tx_dma_chan = NULL;
}
if (!dma_chan)
return;
dma_free_coherent(tspi->dev, tspi->dma_buf_size, dma_buf, dma_phys);
dma_release_channel(dma_chan);
}
static int tegra_spi_validate_request(struct spi_device *spi,
struct tegra_spi_data *tspi, struct spi_transfer *t)
{
int req_mode;
req_mode = spi->mode & 0x3;
if ((req_mode == SPI_MODE_0) || (req_mode == SPI_MODE_2)) {
if (t->tx_buf) {
/* Tx is not supported in mode 0 and mode 2 */
dev_err(tspi->dev, "Tx is not supported in mode %d\n",
req_mode);
return -EINVAL;
}
}
/* Check that the all words are available */
if (t->len % tspi->bytes_per_word != 0) {
dev_dbg(tspi->dev, "length is not a multiple of bypw\n");
return -EINVAL;
}
/* the transfer needs to be completed in one go */
if (t->len > tspi->dma_buf_size) {
dev_dbg(tspi->dev, "message size is greater than dma size\n");
return -EMSGSIZE;
}
/* In unpacked mode, a fifo-word (4 bytes) is used to store a word
* irrespective of bytes-per-word setting. This means that the
* DMA transfers a FIFO word to dma buffer occuping 4 bytes and
* hence the total number of packets possible is 1/4th of dma buff size
*/
if (!tspi->is_packed &&
((t->len / tspi->bytes_per_word) > tspi->dma_buf_size / 4)) {
dev_dbg(tspi->dev, "Num words is greater than dma size\n");
return -EMSGSIZE;
}
/* the total number of packets should be less than max dma packets */
if ((t->len / tspi->bytes_per_word) > MAX_PACKETS) {
dev_dbg(tspi->dev, "Num packets is greater than 64K\n");
return -EMSGSIZE;
}
return 0;
}
static void set_best_clk_source(struct spi_device *spi,
unsigned long rate)
{
long new_rate;
unsigned long err_rate, crate, prate;
unsigned int cdiv, fin_err = rate;
int ret;
struct clk *pclk, *fpclk = NULL;
const char *pclk_name, *fpclk_name = NULL;
struct device_node *node;
struct property *prop;
struct tegra_spi_data *tspi = spi_master_get_devdata(spi->master);
node = spi->master->dev.of_node;
if (!of_property_count_strings(node, "nvidia,clk-parents"))
return;
/* when parent of a clk changes divider is not changed
* set a min div with which clk will not cross max rate
*/
if (!tspi->min_div) {
of_property_for_each_string(node, "nvidia,clk-parents",
prop, pclk_name) {
pclk = clk_get(tspi->dev, pclk_name);
if (IS_ERR(pclk))
continue;
prate = clk_get_rate(pclk);
crate = tspi->spi_max_frequency;
cdiv = DIV_ROUND_UP(prate, crate);
if (cdiv > tspi->min_div)
tspi->min_div = cdiv;
}
}
pclk = clk_get_parent(tspi->clk);
crate = clk_get_rate(tspi->clk);
prate = clk_get_rate(pclk);
if (!crate)
return;
cdiv = DIV_ROUND_UP(prate, crate);
if (cdiv < tspi->min_div) {
crate = DIV_ROUND_UP(prate, tspi->min_div);
clk_set_rate(tspi->clk, crate);
}
of_property_for_each_string(node, "nvidia,clk-parents",
prop, pclk_name) {
pclk = clk_get(tspi->dev, pclk_name);
if (IS_ERR(pclk))
continue;
ret = clk_set_parent(tspi->clk, pclk);
if (ret < 0) {
dev_warn(tspi->dev,
"Error in setting parent clk src %s: %d\n",
pclk_name, ret);
continue;
}
new_rate = clk_round_rate(tspi->clk, rate);
if (new_rate < 0)
continue;
err_rate = abs(new_rate - rate);
if (err_rate < fin_err) {
fpclk = pclk;
fin_err = err_rate;
fpclk_name = pclk_name;
}
}
if (fpclk) {
dev_dbg(tspi->dev, "Setting clk_src %s\n",
fpclk_name);
clk_set_parent(tspi->clk, fpclk);
}
}
static int tegra_spi_start_transfer_one(struct spi_device *spi,
struct spi_transfer *t, bool is_first_of_msg,
bool is_single_xfer)
{
struct tegra_spi_data *tspi = spi_master_get_devdata(spi->master);
struct tegra_spi_device_controller_data *cdata = spi->controller_data;
u32 speed;
u32 core_speed;
u8 bits_per_word;
unsigned total_fifo_words;
int ret;
unsigned long command1;
int req_mode;
bits_per_word = t->bits_per_word;
speed = t->speed_hz ? t->speed_hz : spi->max_speed_hz;
/* Set slave controller clk 1.5 times the bus frequency */
if (!speed)
speed = tspi->spi_max_frequency;
if (tspi->chip_data->new_features) {
/* In case of new feature, all DMA interfaces are async.
* so only 1.5x freq ration required
Set speed to 2x to avoid border cases where actual
clock is not same requested rate*/
core_speed = (speed * 2);
} else {
/* To maintain min 1.5x and max 4x ratio between
* slave core clk and interface clk */
core_speed = speed * 3;
}
if (core_speed > tspi->spi_max_frequency)
core_speed = tspi->spi_max_frequency;
if (core_speed < ((speed * 3) >> 1)) {
dev_err(tspi->dev, "Cannot set requested clk freq %d\n", speed);
return -EINVAL;
}
if (core_speed != tspi->cur_speed) {
set_best_clk_source(spi, core_speed);
ret = clk_set_rate(tspi->clk, core_speed);
if (ret) {
dev_err(tspi->dev, "Failed to set clk freq %d\n", ret);
return -EINVAL;
}
tspi->cur_speed = core_speed;
}
tspi->cur_spi = spi;
tspi->curr_xfer = t;
tspi->curr_rx_pos = 0;
tspi->curr_pos = 0;
tspi->tx_status = 0;
tspi->rx_status = 0;
total_fifo_words = tegra_spi_calculate_curr_xfer_param(spi, tspi, t);
ret = tegra_spi_validate_request(spi, tspi, t);
if (ret < 0)
return ret;
if (is_first_of_msg) {
tegra_spi_clear_status(tspi);
command1 = tspi->def_command1_reg;
command1 |= SPI_BIT_LENGTH(bits_per_word - 1);
command1 &= ~SPI_CONTROL_MODE_MASK;
req_mode = spi->mode & 0x3;
if (req_mode == SPI_MODE_0)
command1 |= SPI_CONTROL_MODE_0;
else if (req_mode == SPI_MODE_1)
command1 |= SPI_CONTROL_MODE_1;
else if (req_mode == SPI_MODE_2)
command1 |= SPI_CONTROL_MODE_2;
else if (req_mode == SPI_MODE_3)
command1 |= SPI_CONTROL_MODE_3;
tegra_spi_writel(tspi, command1, SPI_COMMAND1);
tspi->variable_length_transfer = false;
if (cdata && cdata->variable_length_transfer)
tspi->variable_length_transfer = true;
} else {
command1 = tspi->command1_reg;
command1 &= ~SPI_BIT_LENGTH(~0);
command1 |= SPI_BIT_LENGTH(bits_per_word - 1);
}
if (spi->mode & SPI_LSB_FIRST)
command1 |= SPI_LSBIT_FE;
else
command1 &= ~SPI_LSBIT_FE;
if (tspi->is_packed)
command1 |= SPI_PACKED;
command1 &= ~(SPI_CS_SEL_MASK | SPI_TX_EN | SPI_RX_EN);
tspi->cur_direction = 0;
if (t->rx_buf) {
command1 |= SPI_RX_EN;
tspi->cur_direction |= DATA_DIR_RX;
}
if (t->tx_buf) {
command1 |= SPI_TX_EN;
tspi->cur_direction |= DATA_DIR_TX;
}
command1 |= SPI_CS_SEL(spi->chip_select);
tegra_spi_writel(tspi, command1, SPI_COMMAND1);
tspi->command1_reg = command1;
dev_dbg(tspi->dev, "The def 0x%x and written 0x%lx\n",
tspi->def_command1_reg, command1);
if (total_fifo_words > SPI_FIFO_DEPTH)
ret = tegra_spi_start_dma_based_transfer(tspi, t);
else
ret = tegra_spi_start_cpu_based_transfer(tspi, t);
tegra_spi_slave_ready(tspi);
/* Inform client that we are ready now. */
if (tspi->spi_slave_ready_callback)
tspi->spi_slave_ready_callback(tspi->client_data);
return ret;
}
static struct tegra_spi_device_controller_data
*tegra_spi_get_cdata_dt(struct spi_device *spi,
struct tegra_spi_data *tspi)
{
struct tegra_spi_device_controller_data *cdata;
struct device_node *slave_np, *data_np;
int ret;
slave_np = spi->dev.of_node;
if (!slave_np) {
dev_dbg(&spi->dev, "device node not found\n");
return NULL;
}
data_np = of_get_child_by_name(slave_np, "controller-data");
if (!data_np) {
dev_dbg(&spi->dev, "child node 'controller-data' not found\n");
return NULL;
}
cdata = &tspi->cdata[spi->chip_select];
memset(cdata, 0, sizeof(*cdata));
ret = of_property_read_bool(data_np, "nvidia,variable-length-transfer");
if (ret)
cdata->variable_length_transfer = 1;
tspi->lsbyte_first =
of_property_read_bool(data_np, "nvidia,lsbyte-first");
of_node_put(data_np);
return cdata;
}
static int tegra_spi_setup(struct spi_device *spi)
{
struct tegra_spi_data *tspi = spi_master_get_devdata(spi->master);
struct tegra_spi_device_controller_data *cdata = spi->controller_data;
unsigned long val;
unsigned long flags;
int ret;
unsigned int cs_pol_bit[MAX_CHIP_SELECT] = {
SPI_CS_POL_INACTIVE_0,
SPI_CS_POL_INACTIVE_1,
SPI_CS_POL_INACTIVE_2,
SPI_CS_POL_INACTIVE_3,
};
dev_dbg(&spi->dev, "setup %d bpw, %scpol, %scpha, %dHz\n",
spi->bits_per_word,
spi->mode & SPI_CPOL ? "" : "~",
spi->mode & SPI_CPHA ? "" : "~",
spi->max_speed_hz);
if (!cdata) {
cdata = tegra_spi_get_cdata_dt(spi, tspi);
spi->controller_data = cdata;
}
/* Set speed to the spi max fequency if spi device has not set */
spi->max_speed_hz = spi->max_speed_hz ? : tspi->spi_max_frequency;
ret = pm_runtime_get_sync(tspi->dev);
if (ret < 0) {
dev_err(tspi->dev, "pm runtime failed, e = %d\n", ret);
return ret;
}
spin_lock_irqsave(&tspi->lock, flags);
val = tspi->def_command1_reg;
if (spi->mode & SPI_CS_HIGH)
val &= ~cs_pol_bit[spi->chip_select];
else
val |= cs_pol_bit[spi->chip_select];
if (tspi->lsbyte_first)
val |= SPI_LSBYTE_FE;
tspi->def_command1_reg = val;
tegra_spi_writel(tspi, tspi->def_command1_reg, SPI_COMMAND1);
spin_unlock_irqrestore(&tspi->lock, flags);
pm_runtime_put(tspi->dev);
return 0;
}
static void handle_cpu_based_err_xfer(struct tegra_spi_data *tspi)
{
if (tspi->tx_status || tspi->rx_status) {
dump_regs(err_ratelimited, tspi,
"cpu-xfer-err [status:%08x]", tspi->status_reg);
tspi->reset_ctrl_status = true;
}
}
static void handle_dma_based_err_xfer(struct tegra_spi_data *tspi)
{
int err = 0;
/* Abort dmas if any error */
if (tspi->cur_direction & DATA_DIR_TX) {
if (tspi->tx_status) {
dmaengine_terminate_all(tspi->tx_dma_chan);
dump_regs(err_ratelimited, tspi,
"tx-dma-err [status:%08x]", tspi->status_reg);
err += 1;
}
}
if (tspi->cur_direction & DATA_DIR_RX) {
if (tspi->rx_status) {
dmaengine_terminate_all(tspi->rx_dma_chan);
dump_regs(err_ratelimited, tspi,
"rx-dma-err [status:%08x]", tspi->status_reg);
err += 2;
}
}
if (err)
tspi->reset_ctrl_status = true;
}
static int tegra_spi_wait_on_message_xfer(struct tegra_spi_data *tspi)
{
long ret;
unsigned long timeout;
/* delay_usecs is used as timeout for slave, value of 0 is inf wait.
* since delay_usecs will be too small for practical use (65ms max)
* a multiplier of 1000 is used to make as msecs.
*/
timeout = tspi->curr_xfer->delay_usecs ?
usecs_to_jiffies(tspi->curr_xfer->delay_usecs *
DELAY_MUL_FACTOR) : MAX_SCHEDULE_TIMEOUT;
/* wait for spi isr */
ret = wait_for_completion_interruptible_timeout(
&tspi->xfer_completion, timeout);
if (ret <= 0) {
/* interrupted-wait/late interrupt is considered spurious */
atomic_set(&tspi->isr_expected, 0);
if (ret == -ERESTARTSYS) {
flush_signals(current);
dev_warn(tspi->dev, "waiting for master was interrupted\n");
}
if (ret == 0)
dev_info(tspi->dev, "Timeout waiting for master\n");
dump_regs(dbg, tspi, "spi-int-timeout [ret:%ld]", ret);
if (tspi->is_curr_dma_xfer &&
(tspi->cur_direction & DATA_DIR_TX))
dmaengine_terminate_all(tspi->tx_dma_chan);
if (tspi->is_curr_dma_xfer &&
(tspi->cur_direction & DATA_DIR_RX))
dmaengine_terminate_all(tspi->rx_dma_chan);
/* resetting controller to unarm spi */
tspi->reset_ctrl_status = true;
ret = -EIO;
return ret;
}
/* interrupt came and status in tspi->status_reg */
if (tspi->cur_direction & DATA_DIR_TX)
tspi->tx_status = tspi->status_reg &
(SPI_TX_FIFO_UNF | SPI_TX_FIFO_OVF);
if (tspi->cur_direction & DATA_DIR_RX)
tspi->rx_status = tspi->status_reg &
(SPI_RX_FIFO_OVF | SPI_RX_FIFO_UNF);
/* workaround when number of packets is 64K. The transfer status
* field is 16bit and zero based count (0...2^16-1) and hence for 64K
* the counter resets to 0. Hence for a transfer, if count is
* reported as zero, expected is 64K and there is no error, then
* we correct it to 64K. Packets greater than 64K is not allowed.
*/
tspi->words_to_transfer =
(tspi->words_to_transfer == 0 &&
tspi->curr_xfer->len == MAX_PACKETS) ?
MAX_PACKETS : tspi->words_to_transfer;
/* check if required bytes where transferred */
if (!tspi->variable_length_transfer &&
tspi->words_to_transfer !=
tspi->curr_xfer->len/tspi->bytes_per_word) {
dump_regs(err_ratelimited, tspi,
"transferred[%d] != requested[%d]",
tspi->words_to_transfer,
tspi->curr_xfer->len/tspi->bytes_per_word);
tspi->tx_status = SPI_TX_FIFO_UNF;
tspi->rx_status = SPI_RX_FIFO_OVF;
}
/* cs inactive intr while it is masked, mark as error */
if (tspi->chip_data->mask_cs_inactive_intr &&
(tspi->status_reg & SPI_CS_INACTIVE)) {
dev_dbg(tspi->dev, "cs inactive intr, status_reg = 0x%x\n",
tspi->status_reg);
tspi->tx_status = SPI_TX_FIFO_UNF;
tspi->rx_status = SPI_RX_FIFO_OVF;
}
if (!tspi->is_curr_dma_xfer)
handle_cpu_based_err_xfer(tspi);
else
handle_dma_based_err_xfer(tspi);
/* truncate in case we received more than requested */
tspi->words_to_transfer = min(tspi->words_to_transfer,
tspi->curr_xfer->len/tspi->bytes_per_word);
return (tspi->tx_status || tspi->rx_status) ? -EIO : 0;
}
static int tegra_spi_handle_message(struct tegra_spi_data *tspi,
struct spi_transfer *xfer)
{
int ret = 0;
long wait_status;
unsigned pending_rx_word_count;
unsigned long fifo_status;
unsigned long word_tfr_status;
unsigned long actual_words_xferrd;
/* we are here, so no io-error and received the expected num bytes
* expect in variable length case where received <= expected
*/
if (!tspi->is_curr_dma_xfer) {
if (tspi->cur_direction & DATA_DIR_RX)
tegra_spi_read_rx_fifo_to_client_rxbuf(tspi, xfer);
} else {
if (tspi->cur_direction & DATA_DIR_TX) {
if ((IS_SPI_CS_INACTIVE(tspi->status_reg)) &&
tspi->variable_length_transfer) {
/* Check for TX DMA completion. If the TX DMA
* is already completed, No need to terminate
* the DMA xfer.
*/
wait_status = try_wait_for_completion(
&tspi->tx_dma_complete);
if (!wait_status) {
dev_dbg(tspi->dev,
"terminating tx dma\n");
dmaengine_terminate_all(
tspi->tx_dma_chan);
async_tx_ack(tspi->tx_dma_desc);
} else
dev_dbg(tspi->dev,
"received tx dma completion\n");
tspi->reset_ctrl_status = true;
} else {
wait_status =
wait_for_completion_interruptible_timeout(
&tspi->tx_dma_complete,
SPI_DMA_TIMEOUT);
if (wait_status <= 0) {
dmaengine_terminate_all(
tspi->tx_dma_chan);
dump_regs(dbg, tspi,
"tx-dma-timeout [wait:%ld]",
wait_status);
tspi->reset_ctrl_status = true;
ret = -EIO;
return ret;
}
}
}
if (tspi->cur_direction & DATA_DIR_RX) {
if (tspi->variable_length_transfer) {
dmaengine_terminate_all(tspi->rx_dma_chan);
async_tx_ack(tspi->rx_dma_desc);
fifo_status =
tegra_spi_readl(tspi, SPI_FIFO_STATUS);
pending_rx_word_count =
SPI_RX_FIFO_FULL_COUNT(fifo_status);
word_tfr_status =
DIV_ROUND_UP(tspi->words_to_transfer ,
tspi->words_per_32bit);
if (word_tfr_status < pending_rx_word_count) {
dmaengine_terminate_all(
tspi->rx_dma_chan);
dump_regs(err_ratelimited, tspi,
"available bytes less than expected");
tspi->reset_ctrl_status = true;
ret = -EIO;
return ret;
}
actual_words_xferrd =
word_tfr_status - pending_rx_word_count;
while (pending_rx_word_count > 0) {
tspi->rx_dma_buf[actual_words_xferrd] =
tegra_spi_readl(tspi,
SPI_RX_FIFO);
actual_words_xferrd++;
pending_rx_word_count--;
}
} else {
wait_status =
wait_for_completion_interruptible_timeout(
&tspi->rx_dma_complete,
SPI_DMA_TIMEOUT);
if (wait_status <= 0) {
dmaengine_terminate_all(
tspi->rx_dma_chan);
dump_regs(dbg, tspi,
"rx-dma-timeout [wait:%ld]",
wait_status);
tspi->reset_ctrl_status = true;
ret = -EIO;
return ret;
}
}
tegra_spi_copy_spi_rxbuf_to_client_rxbuf(tspi, xfer);
}
}
/* For TX direction, It might be possible that CS deassert happens
* before the tranfer completion(variable length case). In this scenario
* actual transferred data is less than the requested data. So to update
* the curr_pos(and finally xfer->len) read the data transfer count from
* SPI_TRANS_STATUS and update the xfer->len accordingly.
*
* In case of RX direction, tspi->curr_rx_pos contains actual received
* data. We can directly use it to update the xfer->len.
*/
if (tspi->cur_direction & DATA_DIR_TX) {
tspi->curr_pos += tspi->words_to_transfer * tspi->bytes_per_word;
tspi->rem_len -= tspi->curr_pos;
}
if (tspi->cur_direction & DATA_DIR_RX)
tspi->curr_pos = tspi->curr_rx_pos;
/* If external master de-asserts the CS randomly
and after that is SW wants to do a fresh transfer,
SW needs to apply controller reset to flush the fifos
and internal pipeline as controller might have
fetched more data from memory by then. */
if (tspi->curr_pos == xfer->len ||
(IS_SPI_CS_INACTIVE(tspi->status_reg) &&
tspi->variable_length_transfer)) {
xfer->len = tspi->curr_pos;
if ((IS_SPI_CS_INACTIVE(tspi->status_reg))
&& tspi->variable_length_transfer
&& tspi->chip_data->new_features
&& (tspi->cur_direction & DATA_DIR_TX)) {
tspi->reset_ctrl_status = true;
}
}
return ret;
}
static int tegra_spi_transfer_one_message(struct spi_master *master,
struct spi_message *msg)
{
bool is_first_msg = true;
int single_xfer;
struct tegra_spi_data *tspi = spi_master_get_devdata(master);
struct spi_transfer *xfer;
struct spi_device *spi = msg->spi;
int ret;
msg->status = 0;
msg->actual_length = 0;
ret = pm_runtime_get_sync(tspi->dev);
if (ret < 0) {
dev_err(tspi->dev, "runtime PM get failed: %d\n", ret);
msg->status = ret;
spi_finalize_current_message(master);
return ret;
}
/* allow SIGINT for interrupting the sleep */
allow_signal(SIGINT);
/* Fix me - Implement proper sequnce for CDC */
tegra_spi_ext_clk_enable(false, tspi);
reset_controller(tspi);
tegra_spi_writel(tspi, tspi->def_command1_reg, SPI_COMMAND1);
single_xfer = list_is_singular(&msg->transfers);
list_for_each_entry(xfer, &msg->transfers, transfer_list) {
reinit_completion(&tspi->xfer_completion);
tspi->rem_len = xfer->len;
tspi->words_to_transfer = 0;
dump_xfer(tspi, xfer);
/* program hardware */
ret = tegra_spi_start_transfer_one(spi, xfer,
is_first_msg, single_xfer);
if (ret < 0) {
dev_err(tspi->dev,
"spi can not start transfer, err %d\n", ret);
goto exit;
}
is_first_msg = false;
/* wait for spi-interrupt and handle transfer error */
ret = tegra_spi_wait_on_message_xfer(tspi);
if (ret) {
tegra_spi_slave_busy(tspi);
goto exit;
}
/* unpack and copy data to client */
ret = tegra_spi_handle_message(tspi, xfer);
if (ret < 0)
goto exit;
if (tspi->variable_length_transfer)
msg->actual_length += xfer->len;
else
msg->actual_length += (xfer->len - tspi->rem_len);
#ifdef PROFILE_SPI_SLAVE
{
ktime_t time;
tspi->end_time = ktime_get();
tspi->profile_size = xfer->len - tspi->rem_len;
time = ktime_sub(tspi->end_time, tspi->start_time);
dev_dbg(tspi->dev,
"Profile: size=%dB time-from-spi-int=%lldns\n",
tspi->profile_size, time.tv64);
}
#endif
if (tspi->rem_len)
dump_sw_state(tspi,
"Error transfer was truncated [rem:%d]",
tspi->rem_len);
/* checks for any error after s/w handling the transfer */
ret = tegra_spi_readl(tspi, SPI_FIFO_STATUS);
if (ret &
(SPI_FRAME_END | SPI_CS_INACTIVE | SPI_ERR |
SPI_TX_FIFO_UNF | SPI_TX_FIFO_OVF |
SPI_RX_FIFO_OVF | SPI_RX_FIFO_UNF))
dump_regs(dbg, tspi, "sw-handle-error");
if (!(ret & SPI_FIFO_EMPTY))
dump_regs(dbg, tspi, "rx/tx fifo are not empty");
}
ret = 0;
exit:
tegra_spi_writel(tspi, tspi->def_command1_reg, SPI_COMMAND1);
pm_runtime_put(tspi->dev);
msg->status = ret;
spi_finalize_current_message(master);
return ret;
}
static irqreturn_t tegra_spi_isr(int irq, void *context_data)
{
struct tegra_spi_data *tspi = context_data;
unsigned long status_reg;
status_reg = tegra_spi_readl(tspi, SPI_FIFO_STATUS);
dump_regs(dbg, tspi, "@isr");
tegra_spi_clear_status(tspi);
/* if isr was not expected */
if (!atomic_xchg(&tspi->isr_expected, 0)) {
dev_err_ratelimited(tspi->dev,
"spurious interrupt, status_reg = 0x%x\n",
tspi->status_reg);
return IRQ_NONE;
}
#ifdef PROFILE_SPI_SLAVE
tspi->start_time = ktime_get();
#endif
tspi->status_reg = status_reg;
tspi->words_to_transfer = SPI_BLK_CNT(
tegra_spi_readl(tspi, SPI_TRANS_STATUS));
tegra_spi_slave_busy(tspi);
/* Inform client about controller interrupt. */
if (tspi->spi_slave_isr_callback)
tspi->spi_slave_isr_callback(tspi->client_data);
complete(&tspi->xfer_completion);
return IRQ_HANDLED;
}
static struct tegra_spi_platform_data *tegra_spi_parse_dt(
struct platform_device *pdev)
{
struct tegra_spi_platform_data *pdata;
const unsigned int *prop;
struct device_node *np = pdev->dev.of_node;
enum of_gpio_flags gpio_flags;
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata) {
dev_err(&pdev->dev, "Memory alloc for pdata failed\n");
return NULL;
}
prop = of_get_property(np, "spi-max-frequency", NULL);
if (prop)
pdata->spi_max_frequency = be32_to_cpup(prop);
prop = of_get_property(np, "nvidia,rx-trigger-words", NULL);
if (prop)
pdata->rx_trig_words = be32_to_cpup(prop);
prop = of_get_property(np, "nvidia,least-significant-bit", NULL);
if (prop)
pdata->ls_bit = (be32_to_cpup(prop)) & 0x1;
if (of_find_property(np, "nvidia,clock-always-on", NULL))
pdata->is_clkon_always = true;
pdata->gpio_slave_ready =
of_get_named_gpio_flags(np, "nvidia,slave-ready-gpio", 0,
&gpio_flags);
if (gpio_flags & OF_GPIO_ACTIVE_LOW)
pdata->slave_ready_active_high = false;
else
pdata->slave_ready_active_high = true;
return pdata;
}
static struct tegra_spi_chip_data tegra124_spi_chip_data = {
.intr_mask_reg = false,
.mask_cs_inactive_intr = true,
.new_features = false,
};
static struct tegra_spi_chip_data tegra210_spi_chip_data = {
.intr_mask_reg = true,
.mask_cs_inactive_intr = false,
.new_features = false,
};
static struct tegra_spi_chip_data tegra186_spi_chip_data = {
.intr_mask_reg = true,
.mask_cs_inactive_intr = false,
.new_features = true,
};
static struct of_device_id tegra_spi_of_match[] = {
{
.compatible = "nvidia,tegra124-spi-slave",
.data = &tegra124_spi_chip_data,
}, {
.compatible = "nvidia,tegra210-spi-slave",
.data = &tegra210_spi_chip_data,
}, {
.compatible = "nvidia,tegra186-spi-slave",
.data = &tegra186_spi_chip_data,
},
{}
};
MODULE_DEVICE_TABLE(of, tegra_spi_of_match);
static int tegra_spi_probe(struct platform_device *pdev)
{
struct spi_master *master;
struct tegra_spi_data *tspi;
struct resource *r;
struct tegra_spi_platform_data *pdata = pdev->dev.platform_data;
const struct of_device_id *match;
const struct tegra_spi_chip_data *chip_data = &tegra124_spi_chip_data;
int ret, spi_irq;
int bus_num;
int deassert_val;
if (pdev->dev.of_node) {
bus_num = of_alias_get_id(pdev->dev.of_node, "spi");
if (bus_num < 0) {
dev_warn(&pdev->dev,
"Dynamic bus number will be registerd\n");
bus_num = -1;
}
} else {
bus_num = pdev->id;
}
if (!pdata && pdev->dev.of_node)
pdata = tegra_spi_parse_dt(pdev);
if (!pdata) {
dev_err(&pdev->dev, "No platform data, exiting\n");
return -ENODEV;
}
if (!pdata->spi_max_frequency)
pdata->spi_max_frequency = 25000000; /* 25MHz */
if (pdata->rx_trig_words != 0 &&
pdata->rx_trig_words != 4 && pdata->rx_trig_words != 8)
pdata->rx_trig_words = 0;
master = spi_alloc_master(&pdev->dev, sizeof(*tspi));
if (!master) {
dev_err(&pdev->dev, "master allocation failed\n");
return -ENOMEM;
}
/* the spi->mode bits understood by this driver: */
master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST;
/* supported bpw 8-32 */
master->bits_per_word_mask = (u32) ~(BIT(0)|BIT(1)|
BIT(2)|BIT(3)|BIT(4)|BIT(5)|BIT(6));
master->setup = tegra_spi_setup;
master->transfer_one_message = tegra_spi_transfer_one_message;
master->num_chipselect = MAX_CHIP_SELECT;
master->bus_num = bus_num;
dev_set_drvdata(&pdev->dev, master);
tspi = spi_master_get_devdata(master);
tspi->master = master;
tspi->clock_always_on = pdata->is_clkon_always;
tspi->rx_trig_words = pdata->rx_trig_words;
tspi->dev = &pdev->dev;
dev_dbg(&pdev->dev, "rx-trigger:%d clock-always-on:%d\n",
tspi->rx_trig_words, tspi->clock_always_on);
if (pdev->dev.of_node) {
match = of_match_device(tegra_spi_of_match,
&pdev->dev);
if (match)
chip_data = match->data;
}
tspi->chip_data = chip_data;
tspi->gpio_slave_ready = pdata->gpio_slave_ready;
if (gpio_is_valid(tspi->gpio_slave_ready))
if (gpio_cansleep(tspi->gpio_slave_ready)) {
dev_err(&pdev->dev, "Slave Ready GPIO %d is unusable as it can sleep\n",
tspi->gpio_slave_ready);
ret = -EINVAL;
goto exit_free_master;
}
tspi->slave_ready_active_high = pdata->slave_ready_active_high;
if (gpio_is_valid(tspi->gpio_slave_ready)) {
ret = devm_gpio_request(&pdev->dev,
tspi->gpio_slave_ready, "gpio-spi-slave-ready");
if (!ret) {
if (tspi->slave_ready_active_high)
deassert_val = 0;
else
deassert_val = 1;
gpio_direction_output(tspi->gpio_slave_ready,
deassert_val);
} else {
dev_err(&pdev->dev, "Slave Ready GPIO %d is busy\n",
tspi->gpio_slave_ready);
goto exit_free_master;
}
}
spin_lock_init(&tspi->lock);
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!r) {
dev_err(&pdev->dev, "No IO memory resource\n");
ret = -ENODEV;
goto exit_free_master;
}
tspi->phys = r->start;
tspi->base = devm_ioremap_resource(&pdev->dev, r);
if (IS_ERR(tspi->base)) {
dev_err(&pdev->dev,
"Cannot request memregion/iomap dma address\n");
ret = PTR_ERR(tspi->base);
goto exit_free_master;
}
tspi->rstc = devm_reset_control_get(&pdev->dev, "spi");
if (IS_ERR(tspi->rstc)) {
dev_err(&pdev->dev, "Reset control is not found\n");
return PTR_ERR(tspi->rstc);
}
atomic_set(&tspi->isr_expected, 0);
spi_irq = platform_get_irq(pdev, 0);
tspi->irq = spi_irq;
ret = request_irq(tspi->irq, tegra_spi_isr, 0,
dev_name(&pdev->dev), tspi);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to register ISR for IRQ %d\n",
tspi->irq);
goto exit_free_master;
}
tspi->clk = devm_clk_get(&pdev->dev, "spi");
if (IS_ERR(tspi->clk)) {
dev_err(&pdev->dev, "can not get clock\n");
ret = PTR_ERR(tspi->clk);
goto exit_free_irq;
}
tspi->max_buf_size = SPI_FIFO_DEPTH << 2;
tspi->dma_buf_size = DEFAULT_SPI_DMA_BUF_LEN;
tspi->spi_max_frequency = pdata->spi_max_frequency;
ret = tegra_spi_init_dma_param(tspi, true);
if (ret < 0) {
if (ret == -EPROBE_DEFER)
/* GPCDMA is not available at this point.
* probe will be deferred */
dev_info(&pdev->dev,
"Probe Deferred, ret %d\n", ret);
else
dev_err(&pdev->dev,
"RxDma Init failed, err %d\n", ret);
goto exit_free_irq;
}
ret = tegra_spi_init_dma_param(tspi, false);
if (ret < 0) {
dev_err(&pdev->dev, "TxDma Init failed, err %d\n", ret);
goto exit_rx_dma_free;
}
tspi->max_buf_size = tspi->dma_buf_size;
init_completion(&tspi->tx_dma_complete);
init_completion(&tspi->rx_dma_complete);
init_completion(&tspi->xfer_completion);
if (tspi->clock_always_on) {
ret = clk_prepare_enable(tspi->clk);
if (ret < 0) {
dev_err(tspi->dev, "clk_prepare failed: %d\n", ret);
goto exit_deinit_dma;
}
}
tspi->reset_ctrl_status = false;
pm_runtime_enable(&pdev->dev);
if (!pm_runtime_enabled(&pdev->dev)) {
ret = tegra_spi_runtime_resume(&pdev->dev);
if (ret)
goto exit_pm_disable;
}
ret = pm_runtime_get_sync(&pdev->dev);
if (ret < 0) {
dev_err(&pdev->dev, "pm runtime get failed, e = %d\n", ret);
goto exit_pm_disable;
}
reset_control_reset(tspi->rstc);
tegra_spi_ext_clk_enable(false, tspi);
tspi->def_command1_reg = SPI_CS_SW_HW | SPI_CS_POL_INACTIVE_0 |
SPI_CS_POL_INACTIVE_1 | SPI_CS_POL_INACTIVE_2 |
SPI_CS_POL_INACTIVE_3 | SPI_CS_SS_VAL | SPI_CONTROL_MODE_1;
tegra_spi_writel(tspi, tspi->def_command1_reg, SPI_COMMAND1);
/* set CS inactive b/w packets to mask CS_INACTIVE interrupts */
if (tspi->chip_data->mask_cs_inactive_intr)
tegra_spi_writel(tspi, 0, SPI_CS_TIMING2);
pm_runtime_put(&pdev->dev);
master->dev.of_node = pdev->dev.of_node;
ret = spi_register_master(master);
if (ret < 0) {
dev_err(&pdev->dev, "can not register to master err %d\n", ret);
goto exit_pm_disable;
}
#ifdef TEGRA_SPI_SLAVE_DEBUG
ret = device_create_file(&pdev->dev, &dev_attr_force_unpacked_mode);
if (ret != 0)
goto exit_unregister_master;
return ret;
exit_unregister_master:
spi_unregister_master(master);
#endif
return ret;
exit_pm_disable:
pm_runtime_disable(&pdev->dev);
if (!pm_runtime_status_suspended(&pdev->dev))
tegra_spi_runtime_suspend(&pdev->dev);
if (tspi->clock_always_on)
clk_disable_unprepare(tspi->clk);
exit_deinit_dma:
tegra_spi_deinit_dma_param(tspi, false);
exit_rx_dma_free:
tegra_spi_deinit_dma_param(tspi, true);
exit_free_irq:
free_irq(spi_irq, tspi);
exit_free_master:
spi_master_put(master);
return ret;
}
static int tegra_spi_remove(struct platform_device *pdev)
{
struct spi_master *master = dev_get_drvdata(&pdev->dev);
struct tegra_spi_data *tspi = spi_master_get_devdata(master);
#ifdef TEGRA_SPI_SLAVE_DEBUG
device_remove_file(&pdev->dev, &dev_attr_force_unpacked_mode);
#endif
free_irq(tspi->irq, tspi);
spi_unregister_master(master);
if (tspi->tx_dma_chan)
tegra_spi_deinit_dma_param(tspi, false);
if (tspi->rx_dma_chan)
tegra_spi_deinit_dma_param(tspi, true);
pm_runtime_disable(&pdev->dev);
if (!pm_runtime_status_suspended(&pdev->dev))
tegra_spi_runtime_suspend(&pdev->dev);
if (tspi->clock_always_on)
clk_disable_unprepare(tspi->clk);
return 0;
}
#ifdef CONFIG_PM_SLEEP
static int tegra_spi_suspend(struct device *dev)
{
struct spi_master *master = dev_get_drvdata(dev);
struct tegra_spi_data *tspi = spi_master_get_devdata(master);
int ret;
ret = spi_master_suspend(master);
if (tspi->clock_always_on)
clk_disable_unprepare(tspi->clk);
return ret;
}
static int tegra_spi_resume(struct device *dev)
{
struct spi_master *master = dev_get_drvdata(dev);
struct tegra_spi_data *tspi = spi_master_get_devdata(master);
int ret;
if (tspi->clock_always_on) {
ret = clk_prepare_enable(tspi->clk);
if (ret < 0) {
dev_err(tspi->dev, "clk_prepare failed: %d\n", ret);
return ret;
}
}
ret = pm_runtime_get_sync(dev);
if (ret < 0) {
dev_err(dev, "pm runtime failed, e = %d\n", ret);
return ret;
}
tegra_spi_writel(tspi, tspi->command1_reg, SPI_COMMAND1);
pm_runtime_put(dev);
return spi_master_resume(master);
}
#endif
static int tegra_spi_runtime_suspend(struct device *dev)
{
struct spi_master *master = dev_get_drvdata(dev);
struct tegra_spi_data *tspi = spi_master_get_devdata(master);
/* Flush all write which are in PPSB queue by reading back */
tegra_spi_readl(tspi, SPI_COMMAND1);
clk_disable_unprepare(tspi->clk);
return 0;
}
static int tegra_spi_runtime_resume(struct device *dev)
{
struct spi_master *master = dev_get_drvdata(dev);
struct tegra_spi_data *tspi = spi_master_get_devdata(master);
int ret;
ret = clk_prepare_enable(tspi->clk);
if (ret < 0) {
dev_err(tspi->dev, "clk_prepare failed: %d\n", ret);
return ret;
}
return 0;
}
static const struct dev_pm_ops tegra_spi_pm_ops = {
SET_RUNTIME_PM_OPS(tegra_spi_runtime_suspend,
tegra_spi_runtime_resume, NULL)
SET_SYSTEM_SLEEP_PM_OPS(tegra_spi_suspend, tegra_spi_resume)
};
static struct platform_driver tegra_spi_driver = {
.driver = {
.name = "spi-tegra124-slave",
.owner = THIS_MODULE,
.pm = &tegra_spi_pm_ops,
.of_match_table = of_match_ptr(tegra_spi_of_match),
},
.probe = tegra_spi_probe,
.remove = tegra_spi_remove,
};
module_platform_driver(tegra_spi_driver);
MODULE_ALIAS("platform:spi-tegra124");
MODULE_DESCRIPTION("NVIDIA Tegra124 SPI Controller Driver");
MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com> Yousuf A <yousufa@nvidia.com>");
MODULE_LICENSE("GPL v2");