tegrakernel/kernel/kernel-4.9/drivers/spi/spi-tegra210-qspi.c

2441 lines
66 KiB
C
Raw Normal View History

2022-02-16 09:13:02 -06:00
/*
* QSPI driver for NVIDIA's Tegra210 QUAD SPI Controller.
*
* Copyright (c) 2013-2021, 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.
*/
#include <linux/clk.h>
#include <linux/completion.h>
#include <linux/delay.h>
#include <linux/dmaengine.h>
#include <linux/dma-mapping.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/reset.h>
#include <linux/spi/spi.h>
#include <linux/spi/qspi-tegra.h>
#include <linux/tegra_prod.h>
#define QSPI_COMMAND1 0x000
#define QSPI_BIT_LENGTH(x) (((x) & 0x1f) << 0)
#define QSPI_PACKED BIT(5)
#define QSPI_INTERFACE_WIDTH(x) (((x) & 0x03) << 7)
#define QSPI_INTERFACE_WIDTH_MASK (0x03 << 7)
#define QSPI_SDR_DDR_SEL BIT(9)
#define QSPI_TX_EN BIT(11)
#define QSPI_RX_EN BIT(12)
#define QSPI_CS_SW_VAL BIT(20)
#define QSPI_CS_SW_HW BIT(21)
#define QSPI_CONTROL_MODE_0 (0 << 28)
#define QSPI_CONTROL_MODE_3 (3 << 28)
#define QSPI_CONTROL_MODE_MASK (3 << 28)
#define QSPI_M_S BIT(30)
#define QSPI_PIO BIT(31)
#define QSPI_COMMAND2 0x004
#define QSPI_RX_TAP_DELAY(x) (((x) & 0xFF) << 0)
#define QSPI_TX_TAP_DELAY(x) (((x) & 0x1F) << 10)
#define QSPI_RX_EXT_TAP_DELAY(x) (((x) & 0xFF) << 24)
#define QSPI_SETUP_HOLD(setup, hold) \
(((setup) << 4) | ((hold) & 0x0F))
#define QSPI_CS_SETUP_HOLD(reg, cs, val) \
((((val) & 0xFFu) << ((cs) * 8)) | \
((reg) & ~(0xFFu << ((cs) * 8))))
#define QSPI_CS_TIMING1 0x008
#define QSPI_CS_TIMING2 0x00C
#define QSPI_CS_TIMING3 0x198
#define CYCLES_BETWEEN_PACKETS_0(x) (((x) & 0x1F) << 0)
#define CS_ACTIVE_BETWEEN_PACKETS_0 BIT(5)
#define QSPI_SET_CYCLES_BETWEEN_PACKETS(reg, cs, val) \
(reg = (((val) & 0xF) << ((cs) * 8)) | \
((reg) & ~(0xF << ((cs) * 8))))
#define QSPI_HALF_FULL_CYCLE_SAMPLE BIT(31)
#define QSPI_TRANS_STATUS 0x010
#define QSPI_BLK_CNT(val) (((val) >> 0) & 0xFFFF)
#define QSPI_RDY BIT(30)
#define QSPI_FIFO_STATUS 0x014
#define QSPI_RX_FIFO_EMPTY BIT(0)
#define QSPI_RX_FIFO_FULL BIT(1)
#define QSPI_TX_FIFO_EMPTY BIT(2)
#define QSPI_TX_FIFO_FULL BIT(3)
#define QSPI_RX_FIFO_UNF BIT(4)
#define QSPI_RX_FIFO_OVF BIT(5)
#define QSPI_TX_FIFO_UNF BIT(6)
#define QSPI_TX_FIFO_OVF BIT(7)
#define QSPI_ERR BIT(8)
#define QSPI_TX_FIFO_FLUSH BIT(14)
#define QSPI_RX_FIFO_FLUSH BIT(15)
#define QSPI_TX_FIFO_EMPTY_COUNT(val) (((val) >> 16) & 0x7F)
#define QSPI_RX_FIFO_FULL_COUNT(val) (((val) >> 23) & 0x7F)
#define QSPI_FIFO_ERROR (QSPI_RX_FIFO_UNF | \
QSPI_RX_FIFO_OVF | QSPI_TX_FIFO_UNF | QSPI_TX_FIFO_OVF)
#define QSPI_FIFO_EMPTY (QSPI_RX_FIFO_EMPTY | \
QSPI_TX_FIFO_EMPTY)
#define QSPI_TX_DATA 0x018
#define QSPI_MISC_REG 0x194
#define QSPI_NUM_DUMMY_CYCLE(x) (((x) & 0xFF) << 0)
#define QSPI_GLOBAL_CONFIG 0x1a4
#define QSPI_RX_DATA 0x01C
#define QSPI_DMA_CTL 0x020
#define QSPI_TX_TRIG(n) (((n) & 0x3) << 15)
#define QSPI_TX_TRIG_1 QSPI_TX_TRIG(0)
#define QSPI_TX_TRIG_4 QSPI_TX_TRIG(1)
#define QSPI_TX_TRIG_8 QSPI_TX_TRIG(2)
#define QSPI_TX_TRIG_16 QSPI_TX_TRIG(3)
#define QSPI_RX_TRIG(n) (((n) & 0x3) << 19)
#define QSPI_RX_TRIG_1 QSPI_RX_TRIG(0)
#define QSPI_RX_TRIG_4 QSPI_RX_TRIG(1)
#define QSPI_RX_TRIG_8 QSPI_RX_TRIG(2)
#define QSPI_RX_TRIG_16 QSPI_RX_TRIG(3)
#define QSPI_IE_TX BIT(28)
#define QSPI_IE_RX BIT(29)
#define QSPI_DMA BIT(31)
#define QSPI_DMA_EN QSPI_DMA
#define QSPI_DMA_BLK 0x024
#define QSPI_DMA_BLK_SET(x) (((x) & 0xFFFF) << 0)
#define QSPI_TX_FIFO 0x108
#define QSPI_RX_FIFO 0x188
#define QSPI_INTR_MASK 0x18c
#define QSPI_INTR_RX_FIFO_UNF_MASK BIT(25)
#define QSPI_INTR_RX_FIFO_OVF_MASK BIT(26)
#define QSPI_INTR_TX_FIFO_UNF_MASK BIT(27)
#define QSPI_INTR_TX_FIFO_OVF_MASK BIT(28)
#define QSPI_INTR_RDY_MASK BIT(29)
#define QSPI_INTR_RX_TX_FIFO_ERR (QSPI_INTR_RX_FIFO_UNF_MASK | \
QSPI_INTR_RX_FIFO_OVF_MASK | \
QSPI_INTR_TX_FIFO_UNF_MASK | \
QSPI_INTR_TX_FIFO_OVF_MASK)
#define QSPI_CMB_SEQ_CMD 0x19c
#define QSPI_COMMAND_VALUE_SET(X) (((x) & 0xFF) << 0)
#define QSPI_CMB_SEQ_CMD_CFG 0x1a0
#define QSPI_COMMAND_X1_X2_X4(x) (((x) & 0x3) << 13)
#define QSPI_COMMAND_X1_X2_X4_MASK (0x03 << 13)
#define QSPI_COMMAND_SDR_DDR BIT(12)
#define QSPI_COMMAND_SIZE_SET(x) (((x) & 0xFF) << 0)
#define QSPI_GLOBAL_CONFIG 0x1a4
#define QSPI_CMB_SEQ_EN BIT(0)
#define QSPI_CMB_SEQ_ADDR 0x1a8
#define QSPI_ADDRESS_VALUE_SET(X) (((x) & 0xFFFF) << 0)
#define QSPI_CMB_SEQ_ADDR_CFG 0x1ac
#define QSPI_ADDRESS_X1_X2_X4(x) (((x) & 0x3) << 13)
#define QSPI_ADDRESS_X1_X2_X4_MASK (0x03 << 13)
#define QSPI_ADDRESS_SDR_DDR BIT(12)
#define QSPI_ADDRESS_SIZE_SET(x) (((x) & 0xFF) << 0)
#define DATA_DIR_TX BIT(0)
#define DATA_DIR_RX BIT(1)
#define QSPI_DMA_TIMEOUT (msecs_to_jiffies(10000))
#define DEFAULT_SPI_DMA_BUF_LEN (64 * 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_PROD_NAME 15
/*
* NOTE: Actual chip has only one CS. Below is WAR to enable
* spidev and mtd layer register same time.
*/
#define MAX_CHIP_SELECT 2
#define QSPI_FIFO_DEPTH 64
#define QSPI_FIFO_FLUSH_MAX_DELAY 2000
#define CMD_TRANSFER 0
#define ADDR_TRANSFER 1
#define DATA_TRANSFER 2
static int rx_tap_delay = -1;
module_param(rx_tap_delay, int, 0444);
static int tx_tap_delay = -1;
module_param(tx_tap_delay, int, 0444);
struct tegra_qspi_data {
struct device *dev;
struct spi_master *master;
/* Lock fro register access */
spinlock_t lock;
struct clk *clk;
struct clk *sdr_ddr_clk;
struct reset_control *rstc;
void __iomem *base;
phys_addr_t phys;
unsigned irq;
bool enable_dma_support;
bool clock_always_on;
bool is_ddr_mode;
u8 bus_clk_div;
u32 qspi_max_frequency;
u32 cur_speed;
struct spi_device *cur_qspi;
unsigned cur_pos;
unsigned cur_len;
unsigned words_per_32bit;
unsigned bytes_per_word;
unsigned curr_dma_words;
unsigned cur_direction;
unsigned cur_rx_pos;
unsigned cur_tx_pos;
unsigned dma_buf_size;
unsigned max_buf_size;
bool is_curr_dma_xfer;
bool is_hw_based_cs;
bool dcycle_non_cmbseq_mode;
struct completion rx_dma_complete;
struct completion tx_dma_complete;
u32 tx_status;
u32 rx_status;
u32 status_reg;
bool is_packed;
unsigned long packed_size;
u32 command1_reg;
u32 dma_control_reg;
u32 def_command1_reg;
u32 def_command2_reg;
u32 qspi_cs_timing;
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;
struct tegra_prod *prod_list;
int qspi_enable_cmbseq_mode;
#ifdef QSPI_BRINGUP_BUILD
int qspi_force_unpacked_mode;
int qspi_enable_prod_override;
int qspi_force_pio_mode;
int qspi_force_dma_mode;
bool qspi_force_bus_speed;
#endif
};
static int tegra_qspi_runtime_suspend(struct device *dev);
static int tegra_qspi_runtime_resume(struct device *dev);
static int tegra_qspi_clk_enable(struct tegra_qspi_data *tqspi);
static void tegra_qspi_clk_disable(struct tegra_qspi_data *tqspi);
static struct tegra_qspi_device_controller_data
*tegra_qspi_get_cdata_dt(struct spi_device *spi);
static void set_best_clk_source(struct tegra_qspi_data *tqspi,
unsigned long rate);
static unsigned long tegra_qspi_readl(struct tegra_qspi_data *tqspi,
unsigned long reg)
{
return readl(tqspi->base + reg);
}
static void tegra_qspi_writel(struct tegra_qspi_data *tqspi,
unsigned long val, unsigned long reg)
{
writel(val, tqspi->base + reg);
/* Read back register to make sure that register writes completed */
if (reg != QSPI_TX_FIFO)
readl(tqspi->base + QSPI_COMMAND1);
}
#ifdef QSPI_BRINGUP_BUILD
static ssize_t force_unpacked_mode_set(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct spi_master *master = dev_get_drvdata(dev);
struct tegra_qspi_data *tqspi;
if (!master)
return -ENODEV;
tqspi = spi_master_get_devdata(master);
if (tqspi && count) {
tqspi->qspi_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 spi_master *master = dev_get_drvdata(dev);
struct tegra_qspi_data *tqspi;
if (!master)
return -ENODEV;
tqspi = spi_master_get_devdata(master);
return sprintf(buf, "%d", tqspi->qspi_force_unpacked_mode);
}
static DEVICE_ATTR(qspi_force_unpacked_mode, 0644, force_unpacked_mode_show,
force_unpacked_mode_set);
static ssize_t force_cmbseq_mode_set(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct spi_master *master = dev_get_drvdata(dev);
struct tegra_qspi_data *tqspi;
if (!master)
return -ENODEV;
tqspi = spi_master_get_devdata(master);
if (tqspi && count) {
tqspi->qspi_enable_cmbseq_mode = ((buf[0] - '0') > 0);
return count;
}
return -ENODEV;
}
static ssize_t force_cmbseq_mode_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct spi_master *master = dev_get_drvdata(dev);
struct tegra_qspi_data *tqspi;
if (!master)
return -ENODEV;
tqspi = spi_master_get_devdata(master);
return sprintf(buf, "%d", tqspi->qspi_enable_cmbseq_mode);
return -ENODEV;
}
static DEVICE_ATTR(qspi_enable_cmbseq_mode, 0644, force_cmbseq_mode_show,
force_cmbseq_mode_set);
static ssize_t enable_prod_override_set(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct spi_master *master = dev_get_drvdata(dev);
struct tegra_qspi_data *tqspi;
if (!master)
return -ENODEV;
tqspi = spi_master_get_devdata(master);
if (tqspi && count) {
tqspi->qspi_enable_prod_override = ((buf[0] - '0') > 0);
return count;
}
return -ENODEV;
}
static ssize_t enable_prod_override_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct spi_master *master = dev_get_drvdata(dev);
struct tegra_qspi_data *tqspi;
if (!master)
return -ENODEV;
tqspi = spi_master_get_devdata(master);
return sprintf(buf, "%d\n", tqspi->qspi_enable_prod_override);
return -ENODEV;
}
static DEVICE_ATTR(qspi_enable_prod_override, 0644, enable_prod_override_show,
enable_prod_override_set);
static ssize_t enable_clk_always_on_set(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct spi_master *master = dev_get_drvdata(dev);
struct tegra_qspi_data *tqspi;
if (!master)
return -ENODEV;
tqspi = spi_master_get_devdata(master);
if (tqspi && count) {
tqspi->clock_always_on = ((buf[0] - '0') > 0);
if (tqspi->clock_always_on)
tegra_qspi_clk_enable(tqspi);
else
tegra_qspi_clk_disable(tqspi);
return count;
}
return -ENODEV;
}
static ssize_t enable_clk_always_on_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct spi_master *master = dev_get_drvdata(dev);
struct tegra_qspi_data *tqspi;
if (!master)
return -ENODEV;
tqspi = spi_master_get_devdata(master);
return sprintf(buf, "%d\n", tqspi->clock_always_on);
return -ENODEV;
}
static DEVICE_ATTR(qspi_enable_clk_always_on, 0644, enable_clk_always_on_show,
enable_clk_always_on_set);
static ssize_t bus_speed_set(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct spi_master *master = dev_get_drvdata(dev);
struct tegra_qspi_data *tqspi;
int ret = 0;
long speed;
u32 actual_speed;
if (!master)
return -ENODEV;
tqspi = spi_master_get_devdata(master);
if (tqspi && count) {
ret = kstrtol(buf, 10, &speed);
if (ret != 0)
return -EINVAL;
if (speed == 0) {
tqspi->qspi_force_bus_speed = false;
return count;
}
if (speed > tqspi->qspi_max_frequency/tqspi->bus_clk_div)
return -EINVAL;
if (tqspi->cur_speed == speed)
return count;
tqspi->cur_speed = speed;
set_best_clk_source(tqspi, speed);
ret = clk_set_rate(tqspi->clk, speed*tqspi->bus_clk_div);
if (ret < 0) {
dev_err(tqspi->dev,
"Failed to set QSPI clock freq: %d\n",
ret);
return -EINVAL;
}
actual_speed = clk_get_rate(tqspi->clk)/tqspi->bus_clk_div;
if (actual_speed <= 0)
return -EINVAL;
ret = clk_set_rate(tqspi->sdr_ddr_clk, actual_speed);
if (ret < 0) {
dev_err(tqspi->dev,
"Failed to set QSPI OUT clock freq: %d\n",
ret);
return -EINVAL;
}
tqspi->qspi_force_bus_speed = true;
return count;
}
return -ENODEV;
}
static ssize_t bus_speed_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct spi_master *master = dev_get_drvdata(dev);
struct tegra_qspi_data *tqspi;
u32 actual_qspi_speed;
u32 actual_qspi_out_speed;
if (!master)
return -ENODEV;
tqspi = spi_master_get_devdata(master);
actual_qspi_speed = clk_get_rate(tqspi->clk);
actual_qspi_out_speed = clk_get_rate(tqspi->sdr_ddr_clk);
return sprintf(buf, "qspi:%d, qspi_out:%d\n",
actual_qspi_speed,
actual_qspi_out_speed);
return -ENODEV;
}
static DEVICE_ATTR(qspi_bus_speed, 0644, bus_speed_show,
bus_speed_set);
static ssize_t force_pio_mode_set(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct spi_master *master = dev_get_drvdata(dev);
struct tegra_qspi_data *tqspi;
if (!master)
return -ENODEV;
tqspi = spi_master_get_devdata(master);
if (tqspi && count) {
tqspi->qspi_force_pio_mode = ((buf[0] - '0') > 0);
return count;
}
return -ENODEV;
}
static ssize_t force_pio_mode_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct spi_master *master = dev_get_drvdata(dev);
struct tegra_qspi_data *tqspi;
if (!master)
return -ENODEV;
tqspi = spi_master_get_devdata(master);
return sprintf(buf, "%d\n", tqspi->qspi_force_pio_mode);
return -ENODEV;
}
static DEVICE_ATTR(qspi_force_pio_mode, 0644, force_pio_mode_show,
force_pio_mode_set);
static ssize_t force_dma_mode_set(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct spi_master *master = dev_get_drvdata(dev);
struct tegra_qspi_data *tqspi;
if (!master)
return -ENODEV;
tqspi = spi_master_get_devdata(master);
if (tqspi && count) {
tqspi->qspi_force_dma_mode = ((buf[0] - '0') > 0);
return count;
}
return -ENODEV;
}
static ssize_t force_dma_mode_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct spi_master *master = dev_get_drvdata(dev);
struct tegra_qspi_data *tqspi;
if (!master)
return -ENODEV;
tqspi = spi_master_get_devdata(master);
return sprintf(buf, "%d\n", tqspi->qspi_force_dma_mode);
return -ENODEV;
}
static DEVICE_ATTR(qspi_force_dma_mode, 0644, force_dma_mode_show,
force_dma_mode_set);
static struct attribute *tegra_qspi_attrs[] = {
&dev_attr_qspi_force_unpacked_mode.attr,
&dev_attr_qspi_enable_cmbseq_mode.attr,
&dev_attr_qspi_enable_prod_override.attr,
&dev_attr_qspi_enable_clk_always_on.attr,
&dev_attr_qspi_bus_speed.attr,
&dev_attr_qspi_force_pio_mode.attr,
&dev_attr_qspi_force_dma_mode.attr,
NULL,
};
ATTRIBUTE_GROUPS(tegra_qspi);
#endif
#ifdef QSPI_DUMP_REGISTERS
static void tegra_qspi_dump_regs(const char *heading,
struct tegra_qspi_data *tqspi)
{
u32 command1_reg;
u32 fifo_status_reg, misc_reg, gl_config_reg;
u32 dma_ctrl_reg, dma_blk_reg, intr_mask_reg;
u32 trans_status_reg;
u32 cmd_config;
u32 addr_config;
u32 addr_value;
u32 cmd_value;
cmd_value = tegra_qspi_readl(tqspi, QSPI_CMB_SEQ_CMD);
addr_value = tegra_qspi_readl(tqspi, QSPI_CMB_SEQ_ADDR);
cmd_config = tegra_qspi_readl(tqspi, QSPI_CMB_SEQ_CMD_CFG);
addr_config = tegra_qspi_readl(tqspi, QSPI_CMB_SEQ_ADDR_CFG);
command1_reg = tegra_qspi_readl(tqspi, QSPI_COMMAND1);
fifo_status_reg = tegra_qspi_readl(tqspi, QSPI_FIFO_STATUS);
dma_ctrl_reg = tegra_qspi_readl(tqspi, QSPI_DMA_CTL);
trans_status_reg = tegra_qspi_readl(tqspi, QSPI_TRANS_STATUS);
dma_blk_reg = tegra_qspi_readl(tqspi, QSPI_DMA_BLK);
intr_mask_reg = tegra_qspi_readl(tqspi, QSPI_INTR_MASK);
misc_reg = tegra_qspi_readl(tqspi, QSPI_MISC_REG);
gl_config_reg = tegra_qspi_readl(tqspi, QSPI_GLOBAL_CONFIG);
if (heading)
dev_info(tqspi->dev, "%s\n", heading);
dev_err(tqspi->dev, "CMD_0: \t\t\t0x%08lx\n", command1_reg);
dev_err(tqspi->dev, "FIFO_STS: \t\t\t0x%08x\n", fifo_status_reg);
dev_err(tqspi->dev, "DMA_CTL: \t\t\t0x%08lx\n", dma_ctrl_reg);
dev_err(tqspi->dev, "TRANS_STS: \t\t\t0x%08lx\n", trans_status_reg);
dev_err(tqspi->dev, "GLOBAL_CONFIG: \t\t\t0x%08lx\n", gl_config_reg);
dev_err(tqspi->dev, "DMA_BLK: \t\t\t0x%08lx\n", dma_blk_reg);
dev_err(tqspi->dev, "INTR: \t\t\t0x%08lx\n", intr_mask_reg);
dev_err(tqspi->dev, "MISC-REG: \t\t\t0x%08lx\n", misc_reg);
dev_err(tqspi->dev, "CMD_VAl: \t\t\t0x%08lx\n", cmd_value);
dev_err(tqspi->dev, "ADR_VAL: \t\t\t0x%08lx\n", addr_value);
dev_err(tqspi->dev, "CMD_CFG: \t\t\t0x%08lx\n", cmd_config);
dev_err(tqspi->dev, "ADR_CFG: \t\t\t0x%08lx\n", addr_config);
#else
static void tegra_qspi_dump_regs(const char *heading,
struct tegra_qspi_data *tqspi)
{}
#endif
static void tegra_qspi_clear_status(struct tegra_qspi_data *tqspi)
{
unsigned long val;
/* Write 1 to clear status register */
val = tegra_qspi_readl(tqspi, QSPI_TRANS_STATUS);
tegra_qspi_writel(tqspi, val, QSPI_TRANS_STATUS);
val = tegra_qspi_readl(tqspi, QSPI_INTR_MASK);
if (!(val & QSPI_INTR_RDY_MASK)) {
val |= (QSPI_INTR_RDY_MASK | QSPI_INTR_RX_TX_FIFO_ERR);
tegra_qspi_writel(tqspi, val, QSPI_INTR_MASK);
}
/* Clear fifo status error if any */
val = tegra_qspi_readl(tqspi, QSPI_FIFO_STATUS);
if (val & QSPI_ERR)
tegra_qspi_writel(tqspi, QSPI_ERR | QSPI_FIFO_ERROR,
QSPI_FIFO_STATUS);
}
static int check_and_clear_fifo(struct tegra_qspi_data *tqspi)
{
unsigned long status;
int cnt = QSPI_FIFO_FLUSH_MAX_DELAY;
/* Make sure that Rx and Tx fifo are empty */
status = tegra_qspi_readl(tqspi, QSPI_FIFO_STATUS);
if ((status & QSPI_FIFO_EMPTY) == QSPI_FIFO_EMPTY)
return 0;
/* flush the fifo */
status |= (QSPI_RX_FIFO_FLUSH | QSPI_TX_FIFO_FLUSH);
tegra_qspi_writel(tqspi, status, QSPI_FIFO_STATUS);
do {
status = tegra_qspi_readl(tqspi, QSPI_FIFO_STATUS);
if ((status & QSPI_FIFO_EMPTY) == QSPI_FIFO_EMPTY)
return 0;
udelay(1);
} while (cnt--);
dev_err(tqspi->dev, "Failed to flush Rx/Tx fifo(status 0x%08lx)\n",
status);
return -EIO;
}
static unsigned tegra_qspi_calculate_curr_xfer_param(
struct spi_device *spi, struct tegra_qspi_data *tqspi,
struct spi_transfer *t)
{
unsigned remain_len = t->len - tqspi->cur_pos;
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;
tqspi->bytes_per_word = (bits_per_word - 1) / 8 + 1;
#ifdef QSPI_BRINGUP_BUILD
if (!tqspi->qspi_force_unpacked_mode &&
(bits_per_word % 8 == 0) && (t->len > 3)) {
tqspi->is_packed = true;
tqspi->words_per_32bit = 32 / bits_per_word;
} else {
tqspi->is_packed = false;
tqspi->words_per_32bit = 1;
}
#else
if ((bits_per_word == 8 || bits_per_word == 16) && (t->len > 3)) {
tqspi->is_packed = true;
tqspi->words_per_32bit = 32 / bits_per_word;
} else {
tqspi->is_packed = false;
tqspi->words_per_32bit = 1;
}
#endif
if (tqspi->is_packed) {
max_len = min(remain_len, tqspi->max_buf_size);
tqspi->curr_dma_words = max_len / tqspi->bytes_per_word;
total_fifo_words = (max_len + 3) / 4;
#ifdef QSPI_BRINGUP_BUILD
if (tqspi->qspi_force_pio_mode)
if (tqspi->curr_dma_words > QSPI_FIFO_DEPTH) {
tqspi->curr_dma_words = QSPI_FIFO_DEPTH;
total_fifo_words = QSPI_FIFO_DEPTH;
}
#endif
} else {
max_word = (remain_len - 1) / tqspi->bytes_per_word + 1;
max_word = min(max_word, tqspi->max_buf_size / 4);
tqspi->curr_dma_words = max_word;
total_fifo_words = max_word;
#ifdef QSPI_BRINGUP_BUILD
if (tqspi->qspi_force_pio_mode)
if (tqspi->curr_dma_words > QSPI_FIFO_DEPTH) {
tqspi->curr_dma_words = QSPI_FIFO_DEPTH;
total_fifo_words = QSPI_FIFO_DEPTH;
}
#endif
}
return total_fifo_words;
}
static unsigned tegra_qspi_fill_tx_fifo_from_client_txbuf(
struct tegra_qspi_data *tqspi, struct spi_transfer *t)
{
unsigned nbytes;
unsigned tx_empty_count;
unsigned long fifo_status;
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 + tqspi->cur_tx_pos;
fifo_status = tegra_qspi_readl(tqspi, QSPI_FIFO_STATUS);
tx_empty_count = QSPI_TX_FIFO_EMPTY_COUNT(fifo_status);
if (tqspi->is_packed) {
fifo_words_left = tx_empty_count * tqspi->words_per_32bit;
written_words = min(fifo_words_left, tqspi->curr_dma_words);
nbytes = written_words * tqspi->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 |= (unsigned long)
(((unsigned)(*tx_buf++)) << (i * 8));
tegra_qspi_writel(tqspi, x, QSPI_TX_FIFO);
}
} else {
max_n_32bit = min(tqspi->curr_dma_words, tx_empty_count);
written_words = max_n_32bit;
nbytes = written_words * tqspi->bytes_per_word;
for (count = 0; count < max_n_32bit; count++) {
x = 0;
for (i = 0; nbytes && (i < tqspi->bytes_per_word);
i++, nbytes--)
x |= (unsigned long)
(((unsigned)(*tx_buf++)) << (i * 8));
tegra_qspi_writel(tqspi, x, QSPI_TX_FIFO);
}
}
tqspi->cur_tx_pos += written_words * tqspi->bytes_per_word;
return written_words;
}
static unsigned int tegra_qspi_read_rx_fifo_to_client_rxbuf(
struct tegra_qspi_data *tqspi, struct spi_transfer *t)
{
unsigned rx_full_count;
unsigned long fifo_status;
unsigned i, count;
unsigned long x;
unsigned int read_words = 0;
unsigned len;
u8 *rx_buf = (u8 *)t->rx_buf + tqspi->cur_rx_pos;
fifo_status = tegra_qspi_readl(tqspi, QSPI_FIFO_STATUS);
rx_full_count = QSPI_RX_FIFO_FULL_COUNT(fifo_status);
if (tqspi->is_packed) {
len = tqspi->curr_dma_words * tqspi->bytes_per_word;
for (count = 0; count < rx_full_count; count++) {
x = tegra_qspi_readl(tqspi, QSPI_RX_FIFO);
for (i = 0; len && (i < 4); i++, len--)
*rx_buf++ = (x >> i * 8) & 0xFF;
}
tqspi->cur_rx_pos += tqspi->curr_dma_words *
tqspi->bytes_per_word;
read_words += tqspi->curr_dma_words;
} else {
unsigned int bits_per_word;
bits_per_word = t->bits_per_word ? t->bits_per_word :
tqspi->cur_qspi->bits_per_word;
for (count = 0; count < rx_full_count; count++) {
x = tegra_qspi_readl(tqspi, QSPI_RX_FIFO);
for (i = 0; (i < tqspi->bytes_per_word); i++)
*rx_buf++ = (x >> (i * 8)) & 0xFF;
}
tqspi->cur_rx_pos += rx_full_count * tqspi->bytes_per_word;
read_words += rx_full_count;
}
return read_words;
}
static void tegra_qspi_copy_client_txbuf_to_qspi_txbuf(
struct tegra_qspi_data *tqspi, struct spi_transfer *t)
{
unsigned len;
/* Make the dma buffer to read by cpu */
dma_sync_single_for_cpu(tqspi->dev, tqspi->tx_dma_phys,
tqspi->dma_buf_size, DMA_TO_DEVICE);
if (tqspi->is_packed) {
len = tqspi->curr_dma_words * tqspi->bytes_per_word;
memcpy(tqspi->tx_dma_buf, t->tx_buf + tqspi->cur_pos, len);
} else {
unsigned int i;
unsigned int count;
u8 *tx_buf = (u8 *)t->tx_buf + tqspi->cur_tx_pos;
unsigned consume = tqspi->curr_dma_words *
tqspi->bytes_per_word;
for (count = 0; count < tqspi->curr_dma_words; count++) {
u32 x = 0;
for (i = 0; consume && (i < tqspi->bytes_per_word);
i++, consume--)
x |= ((*tx_buf++) << i * 8);
tqspi->tx_dma_buf[count] = x;
}
}
tqspi->cur_tx_pos += tqspi->curr_dma_words * tqspi->bytes_per_word;
/* Make the dma buffer to read by dma */
dma_sync_single_for_device(tqspi->dev, tqspi->tx_dma_phys,
tqspi->dma_buf_size, DMA_TO_DEVICE);
}
static void tegra_qspi_copy_qspi_rxbuf_to_client_rxbuf(
struct tegra_qspi_data *tqspi, struct spi_transfer *t)
{
unsigned len;
/* Make the dma buffer to read by cpu */
dma_sync_single_for_cpu(tqspi->dev, tqspi->rx_dma_phys,
tqspi->dma_buf_size, DMA_FROM_DEVICE);
if (tqspi->is_packed) {
len = tqspi->curr_dma_words * tqspi->bytes_per_word;
memcpy(t->rx_buf + tqspi->cur_rx_pos, tqspi->rx_dma_buf, len);
} else {
unsigned int i;
unsigned int count;
unsigned char *rx_buf = t->rx_buf + tqspi->cur_rx_pos;
unsigned int x;
unsigned int rx_mask, bits_per_word;
bits_per_word = t->bits_per_word ? t->bits_per_word :
tqspi->cur_qspi->bits_per_word;
rx_mask = (1ULL << bits_per_word) - 1;
for (count = 0; count < tqspi->curr_dma_words; count++) {
x = tqspi->rx_dma_buf[count];
x &= rx_mask;
for (i = 0; (i < tqspi->bytes_per_word); i++)
*rx_buf++ = (x >> (i * 8)) & 0xFF;
}
}
tqspi->cur_rx_pos += tqspi->curr_dma_words * tqspi->bytes_per_word;
/* Make the dma buffer to read by dma */
dma_sync_single_for_device(tqspi->dev, tqspi->rx_dma_phys,
tqspi->dma_buf_size, DMA_FROM_DEVICE);
}
static void tegra_qspi_dma_complete(void *args)
{
struct completion *dma_complete = args;
complete(dma_complete);
}
static int tegra_qspi_start_tx_dma(struct tegra_qspi_data *tqspi, int len)
{
reinit_completion(&tqspi->tx_dma_complete);
tqspi->tx_dma_desc = dmaengine_prep_slave_single(tqspi->tx_dma_chan,
tqspi->tx_dma_phys, len, DMA_MEM_TO_DEV,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!tqspi->tx_dma_desc) {
dev_err(tqspi->dev, "Failed to get Tx DMA Desc\n");
return -EIO;
}
tqspi->tx_dma_desc->callback = tegra_qspi_dma_complete;
tqspi->tx_dma_desc->callback_param = &tqspi->tx_dma_complete;
dmaengine_submit(tqspi->tx_dma_desc);
dma_async_issue_pending(tqspi->tx_dma_chan);
return 0;
}
static int tegra_qspi_start_rx_dma(struct tegra_qspi_data *tqspi, int len)
{
reinit_completion(&tqspi->rx_dma_complete);
tqspi->rx_dma_desc = dmaengine_prep_slave_single(tqspi->rx_dma_chan,
tqspi->rx_dma_phys, len, DMA_DEV_TO_MEM,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!tqspi->rx_dma_desc) {
dev_err(tqspi->dev, "Failed to get Rx Dma Desc\n");
return -EIO;
}
tqspi->rx_dma_desc->callback = tegra_qspi_dma_complete;
tqspi->rx_dma_desc->callback_param = &tqspi->rx_dma_complete;
dmaengine_submit(tqspi->rx_dma_desc);
dma_async_issue_pending(tqspi->rx_dma_chan);
return 0;
}
static int tegra_qspi_start_dma_based_transfer(
struct tegra_qspi_data *tqspi, struct spi_transfer *t)
{
unsigned long val, command1;
unsigned int len, intr_mask;
int ret = 0, maxburst;
struct dma_slave_config dma_sconfig;
/* Make sure that Rx and Tx fifo are empty */
ret = check_and_clear_fifo(tqspi);
if (ret != 0)
return ret;
/* TX_EN/RX_EN should not be set here */
command1 = tqspi->command1_reg;
tegra_qspi_writel(tqspi, command1, QSPI_COMMAND1);
val = QSPI_DMA_BLK_SET(tqspi->curr_dma_words - 1);
tegra_qspi_writel(tqspi, val, QSPI_DMA_BLK);
if (tqspi->is_packed)
len = DIV_ROUND_UP(tqspi->curr_dma_words *
tqspi->bytes_per_word, 4) * 4;
else
len = tqspi->curr_dma_words * 4;
val = 0;
/* Set attention level based on length of transfer */
if (len & 0xF) {
val |= QSPI_TX_TRIG_1 | QSPI_RX_TRIG_1;
maxburst = 1;
} else if (((len) >> 4) & 0x1) {
val |= QSPI_TX_TRIG_4 | QSPI_RX_TRIG_4;
maxburst = 4;
} else {
val |= QSPI_TX_TRIG_8 | QSPI_RX_TRIG_8;
maxburst = 8;
}
if ((tqspi->cur_direction & DATA_DIR_TX) ||
(tqspi->cur_direction & DATA_DIR_RX)) {
intr_mask = tegra_qspi_readl(tqspi, QSPI_INTR_MASK);
intr_mask &= ~(QSPI_INTR_RDY_MASK | QSPI_INTR_RX_TX_FIFO_ERR);
tegra_qspi_writel(tqspi, intr_mask, QSPI_INTR_MASK);
}
tegra_qspi_writel(tqspi, val, QSPI_DMA_CTL);
tqspi->dma_control_reg = val;
if (tqspi->cur_direction & DATA_DIR_TX) {
command1 |= QSPI_TX_EN;
dma_sconfig.dst_addr = tqspi->phys + QSPI_TX_FIFO;
dma_sconfig.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
dma_sconfig.dst_maxburst = maxburst;
dmaengine_slave_config(tqspi->tx_dma_chan, &dma_sconfig);
tegra_qspi_copy_client_txbuf_to_qspi_txbuf(tqspi, t);
ret = tegra_qspi_start_tx_dma(tqspi, len);
if (ret < 0) {
dev_err(tqspi->dev, "Failed to start Tx DMA: %d\n",
ret);
return ret;
}
}
if (tqspi->cur_direction & DATA_DIR_RX) {
command1 |= QSPI_RX_EN;
/* Make the dma buffer to read by dma */
dma_sync_single_for_device(tqspi->dev, tqspi->rx_dma_phys,
tqspi->dma_buf_size,
DMA_FROM_DEVICE);
dma_sconfig.src_addr = tqspi->phys + QSPI_RX_FIFO;
dma_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
dma_sconfig.src_maxburst = maxburst;
dmaengine_slave_config(tqspi->rx_dma_chan, &dma_sconfig);
ret = tegra_qspi_start_rx_dma(tqspi, len);
if (ret < 0) {
dev_err(tqspi->dev, "Failed to start Rx DMA: %d\n",
ret);
if (tqspi->cur_direction & DATA_DIR_TX)
dmaengine_terminate_all(tqspi->tx_dma_chan);
return ret;
}
}
tqspi->is_curr_dma_xfer = true;
tqspi->dma_control_reg = val;
val |= QSPI_DMA_EN;
/* TX_EN/RX_EN need to set after DMA_BLK to avoid spurious interrupt */
tegra_qspi_writel(tqspi, command1, QSPI_COMMAND1);
tegra_qspi_dump_regs("DMA Transfer started", tqspi);
tegra_qspi_writel(tqspi, val, QSPI_DMA_CTL);
return ret;
}
static int tegra_qspi_start_cpu_based_transfer(
struct tegra_qspi_data *tqspi, struct spi_transfer *t)
{
unsigned long val;
unsigned int cur_words, intr_mask;
int ret = 0;
/* Make sure Tx/Rx fifo is empty */
ret = check_and_clear_fifo(tqspi);
if (ret != 0)
return ret;
/* TX_EN/RX_EN should not be set here */
tegra_qspi_writel(tqspi, tqspi->command1_reg, QSPI_COMMAND1);
if (tqspi->cur_direction & DATA_DIR_TX)
cur_words = tegra_qspi_fill_tx_fifo_from_client_txbuf(tqspi, t);
else
cur_words = tqspi->curr_dma_words;
val = QSPI_DMA_BLK_SET(cur_words - 1);
tegra_qspi_writel(tqspi, val, QSPI_DMA_BLK);
val = 0;
if ((tqspi->cur_direction & DATA_DIR_TX) ||
(tqspi->cur_direction & DATA_DIR_RX)) {
intr_mask = tegra_qspi_readl(tqspi, QSPI_INTR_MASK);
intr_mask &= ~(QSPI_INTR_RDY_MASK | QSPI_INTR_RX_TX_FIFO_ERR);
tegra_qspi_writel(tqspi, intr_mask, QSPI_INTR_MASK);
}
tqspi->is_curr_dma_xfer = false;
val = tqspi->command1_reg;
/* TX_EN/RX_EN need to set after DMA_BLK to avoid spurious interrupt */
if (tqspi->cur_direction & DATA_DIR_RX)
val |= QSPI_RX_EN;
if (tqspi->cur_direction & DATA_DIR_TX)
val |= QSPI_TX_EN;
tegra_qspi_writel(tqspi, val, QSPI_COMMAND1);
tegra_qspi_dump_regs("CPU Transfer started", tqspi);
val |= QSPI_PIO;
tegra_qspi_writel(tqspi, val, QSPI_COMMAND1);
return 0;
}
static int tegra_qspi_init_dma_param(struct tegra_qspi_data *tqspi,
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(tqspi->dev,
dma_to_memory ?
"rx" : "tx");
if (IS_ERR(dma_chan)) {
ret = PTR_ERR(dma_chan);
dev_err(tqspi->dev, "Failed to get DMA channel, will retryi: %d\n",
ret);
return ret;
}
dma_buf = dma_alloc_coherent(tqspi->dev, tqspi->dma_buf_size,
&dma_phys, GFP_KERNEL);
if (!dma_buf) {
dev_err(tqspi->dev, "Failed to allocate coherant DMA buffer\n");
dma_release_channel(dma_chan);
return -ENOMEM;
}
if (dma_to_memory) {
dma_sconfig.src_addr = tqspi->phys + QSPI_RX_FIFO;
dma_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
dma_sconfig.src_maxburst = 0;
} else {
dma_sconfig.dst_addr = tqspi->phys + QSPI_TX_FIFO;
dma_sconfig.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
dma_sconfig.dst_maxburst = 0;
}
ret = dmaengine_slave_config(dma_chan, &dma_sconfig);
if (ret)
goto scrub;
if (dma_to_memory) {
tqspi->rx_dma_chan = dma_chan;
tqspi->rx_dma_buf = dma_buf;
tqspi->rx_dma_phys = dma_phys;
} else {
tqspi->tx_dma_chan = dma_chan;
tqspi->tx_dma_buf = dma_buf;
tqspi->tx_dma_phys = dma_phys;
}
return 0;
scrub:
dma_free_coherent(tqspi->dev, tqspi->dma_buf_size, dma_buf, dma_phys);
dma_release_channel(dma_chan);
return ret;
}
static void tegra_qspi_deinit_dma_param(struct tegra_qspi_data *tqspi,
bool dma_to_memory)
{
u32 *dma_buf;
dma_addr_t dma_phys;
struct dma_chan *dma_chan;
if (dma_to_memory) {
dma_buf = tqspi->rx_dma_buf;
dma_chan = tqspi->rx_dma_chan;
dma_phys = tqspi->rx_dma_phys;
tqspi->rx_dma_chan = NULL;
tqspi->rx_dma_buf = NULL;
} else {
dma_buf = tqspi->tx_dma_buf;
dma_chan = tqspi->tx_dma_chan;
dma_phys = tqspi->tx_dma_phys;
tqspi->tx_dma_buf = NULL;
tqspi->tx_dma_chan = NULL;
}
if (!dma_chan)
return;
dma_free_coherent(tqspi->dev, tqspi->dma_buf_size, dma_buf, dma_phys);
dma_release_channel(dma_chan);
}
static int tegra_qspi_validate_request(struct spi_device *spi,
struct tegra_qspi_data *tqspi,
struct spi_transfer *t,
bool is_ddr)
{
int req_mode;
req_mode = spi->mode & 0x3;
if ((req_mode == SPI_MODE_1) || (req_mode == SPI_MODE_2)) {
dev_err(tqspi->dev, "QSPI does not support mode %d\n",
req_mode);
return -EINVAL;
}
if ((req_mode == SPI_MODE_3) && is_ddr) {
dev_err(tqspi->dev, "DDR is not supported in mode 3\n");
return -EINVAL;
}
if ((t->bits_per_word != 8) && (t->bits_per_word != 16) &&
(t->bits_per_word != 32)) {
dev_err(tqspi->dev, "QSPI does not support bpw = %d\n",
t->bits_per_word);
return -EINVAL;
}
if (((t->bits_per_word == 16) && (t->len & 0x1)) ||
((t->bits_per_word == 32) && (t->len & 0x3))) {
dev_err(tqspi->dev, "QSPI: length %d and bits-per-word %d must align\n",
t->len, t->bits_per_word);
return -EINVAL;
}
return 0;
}
static bool tegra_qspi_tap(struct tegra_qspi_data *tqspi,
char *name, int tap, unsigned int mask, unsigned int shift, u32 *cmd2)
{
if (tap < 0)
return false;
if (tap & ~mask)
dev_warn(tqspi->dev, "%s (%d) should be within %d..%d range\n",
name, tap, 0, mask);
tap &= mask;
*cmd2 &= ~(mask << shift);
*cmd2 |= (tap << shift);
return true;
}
static void tegra_qspi_tap_delays(struct tegra_qspi_data *tqspi,
int tx_tap_delay, int rx_tap_delay)
{
u32 cmd2 = tegra_qspi_readl(tqspi, QSPI_COMMAND2);
bool changed = false;
if (tegra_qspi_tap(tqspi, "tx_tap_delay", tx_tap_delay, 0x1F, 10, &cmd2))
changed = true;
if (tegra_qspi_tap(tqspi, "rx_tap_delay", rx_tap_delay, 0xFF, 0, &cmd2))
changed = true;
if (changed) {
dev_info(tqspi->dev, "rx tap = %d, tx tap = %d, COMMAND2 = %08x\n",
rx_tap_delay, tx_tap_delay, cmd2);
tegra_qspi_writel(tqspi, cmd2, QSPI_COMMAND2);
}
}
static void tegra_qspi_set_gr_registers(struct tegra_qspi_data *tqspi)
{
char prod_name[MAX_PROD_NAME];
int clk_mhz;
int err;
#ifdef QSPI_BRINGUP_BUILD
if (tqspi->qspi_enable_prod_override)
return;
#endif
if (!tqspi->prod_list)
goto regs_por;
/* If available, initialise the config registers
* for QSPI with the values mentioned in prod list.
*/
err = tegra_prod_set_by_name(&tqspi->base, "prod", tqspi->prod_list);
if (err < 0)
dev_info_once(tqspi->dev,
"Prod config not found for QSPI: %d\n", err);
clk_mhz = tqspi->cur_speed / 1000000;
if (tqspi->is_ddr_mode)
sprintf(prod_name, "prod_c_ddr");
else
sprintf(prod_name, "prod_c_sdr");
err = tegra_prod_set_by_name(&tqspi->base, prod_name, tqspi->prod_list);
if (!err)
dev_info_once(tqspi->dev,
"Failed to apply prod name[%s] for qspi\n",
prod_name);
return;
regs_por:
/* If NOT defined in prod list or error in applying prod settings,
* then initialise golden registers with POR values.
*/
tegra_qspi_writel(tqspi, 0, QSPI_COMMAND2);
tegra_qspi_writel(tqspi, 0, QSPI_CS_TIMING1);
tegra_qspi_writel(tqspi, CS_ACTIVE_BETWEEN_PACKETS_0, QSPI_CS_TIMING2);
tegra_qspi_writel(tqspi, 0, QSPI_CS_TIMING3);
}
static int tegra_qspi_start_transfer_one(struct spi_device *spi,
struct spi_transfer *t,
bool is_first_of_msg,
bool is_single_xfer)
{
struct tegra_qspi_data *tqspi = spi_master_get_devdata(spi->master);
#ifndef QSPI_BRINGUP_BUILD
struct tegra_qspi_device_controller_data *cdata = spi->controller_data;
#endif
u32 speed = 0;
u32 actual_speed = 0;
u8 bits_per_word;
unsigned total_fifo_words;
int ret;
unsigned long command1;
int req_mode;
u8 bus_width = X1;
bool is_ddr = false;
u8 bus_clk_div = tqspi->bus_clk_div;
bits_per_word = t->bits_per_word;
tqspi->cur_qspi = spi;
tqspi->cur_pos = 0;
tqspi->cur_rx_pos = 0;
tqspi->cur_tx_pos = 0;
tqspi->curr_xfer = t;
tqspi->tx_status = 0;
tqspi->rx_status = 0;
total_fifo_words = tegra_qspi_calculate_curr_xfer_param(spi, tqspi, t);
#ifndef QSPI_BRINGUP_BUILD
if (cdata) {
if ((t->len - tqspi->cur_pos) > cdata->x1_len_limit)
speed = cdata->x4_bus_speed;
else {
is_ddr = false;
speed = cdata->x1_bus_speed;
}
bus_clk_div = cdata->bus_clk_div;
} else {
dev_err(tqspi->dev, "Controller Data is not available\n");
return -EINVAL;
}
#else
if (tqspi->qspi_force_bus_speed)
speed = tqspi->cur_speed;
else
speed = t->speed_hz;
#endif
if (bus_clk_div < 1 || bus_clk_div > 2)
bus_clk_div = tqspi->bus_clk_div;
/*
* NOTE:
* 1.Bus width can be x4 even for command/addr for QPI commands.
* So caller requested bus width should be considered.
* 2. is_ddr is not applicable for write. Write is always in SDR mode.
*/
is_ddr = get_sdr_ddr(t->delay_usecs);
bus_width = get_bus_width(t->delay_usecs);
ret = tegra_qspi_validate_request(spi, tqspi, t, is_ddr);
if (ret)
return ret;
if (!speed || speed > tqspi->qspi_max_frequency/bus_clk_div)
speed = tqspi->qspi_max_frequency/bus_clk_div;
if (speed != tqspi->cur_speed ||
bus_clk_div != tqspi->bus_clk_div) {
ret = clk_set_rate(tqspi->clk, speed*bus_clk_div);
if (ret < 0) {
dev_err(tqspi->dev,
"Failed to set QSPI clock freq: %d\n", ret);
return -EINVAL;
}
actual_speed = clk_get_rate(tqspi->clk)/bus_clk_div;
ret = clk_set_rate(tqspi->sdr_ddr_clk, actual_speed);
if (ret < 0) {
dev_err(tqspi->dev,
"Failed to set QSPI clock freq: %d\n", ret);
return -EINVAL;
}
tqspi->cur_speed = speed;
tqspi->bus_clk_div = bus_clk_div;
}
#if 0
if (is_ddr != tqspi->is_ddr_mode) {
actual_speed = clk_get_rate(tqspi->clk);
if (is_ddr)
ret = clk_set_rate(tqspi->sdr_ddr_clk,
(actual_speed >> 1));
else
ret = clk_set_rate(tqspi->sdr_ddr_clk, actual_speed);
if (ret < 0) {
dev_err(tqspi->dev, "Failed to set QSPI-out clock freq: %d\n",
ret);
return -EINVAL;
}
tqspi->is_ddr_mode = is_ddr;
}
#endif
if (is_first_of_msg) {
tegra_qspi_clear_status(tqspi);
command1 = tqspi->def_command1_reg;
command1 |= QSPI_BIT_LENGTH(bits_per_word - 1);
command1 &= ~QSPI_CONTROL_MODE_MASK;
req_mode = spi->mode & 0x3;
if (req_mode == SPI_MODE_0) {
command1 |= QSPI_CONTROL_MODE_0;
} else if (req_mode == SPI_MODE_3) {
command1 |= QSPI_CONTROL_MODE_3;
} else {
dev_err(tqspi->dev, "QSPI does not support mode %d\n",
req_mode);
return -EINVAL;
}
/* Programming mode first suggested by HW - Bug 200082074 */
tegra_qspi_writel(tqspi, command1, QSPI_COMMAND1);
/* Toggle CS to active state now */
if (spi->mode & SPI_CS_HIGH)
command1 |= QSPI_CS_SW_VAL;
else
command1 &= ~QSPI_CS_SW_VAL;
tegra_qspi_writel(tqspi, command1, QSPI_COMMAND1);
} else {
command1 = tqspi->command1_reg;
command1 &= ~QSPI_BIT_LENGTH(~0);
command1 |= QSPI_BIT_LENGTH(bits_per_word - 1);
}
command1 &= ~QSPI_SDR_DDR_SEL;
if (is_ddr)
command1 |= QSPI_SDR_DDR_SEL;
command1 &= ~QSPI_INTERFACE_WIDTH_MASK;
command1 |= QSPI_INTERFACE_WIDTH(bus_width);
command1 &= ~QSPI_PACKED;
if (tqspi->is_packed)
command1 |= QSPI_PACKED;
command1 &= ~(QSPI_TX_EN | QSPI_RX_EN);
tqspi->cur_direction = 0;
if (t->rx_buf)
tqspi->cur_direction |= DATA_DIR_RX;
if (t->tx_buf)
tqspi->cur_direction |= DATA_DIR_TX;
tqspi->command1_reg = command1;
#ifdef QSPI_BRINGUP_BUILD
if (tqspi->qspi_force_dma_mode) {
ret = tegra_qspi_start_dma_based_transfer(tqspi, t);
return ret;
}
if (tqspi->qspi_force_pio_mode) {
ret = tegra_qspi_start_cpu_based_transfer(tqspi, t);
return ret;
}
#endif
if (total_fifo_words > QSPI_FIFO_DEPTH)
ret = tegra_qspi_start_dma_based_transfer(tqspi, t);
else
ret = tegra_qspi_start_cpu_based_transfer(tqspi, t);
return ret;
}
static void tegra_qspi_clean(struct spi_device *spi)
{
kfree(spi->controller_data);
spi->controller_data = NULL;
}
static int tegra_qspi_setup(struct spi_device *spi)
{
struct tegra_qspi_data *tqspi = spi_master_get_devdata(spi->master);
struct tegra_qspi_device_controller_data *cdata = spi->controller_data;
unsigned long val;
unsigned long flags;
int ret;
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 (spi->chip_select >= MAX_CHIP_SELECT) {
dev_err(tqspi->dev, "QSPI Chip select %d is not supported\n",
spi->chip_select);
return -EINVAL;
}
if (!cdata) {
cdata = tegra_qspi_get_cdata_dt(spi);
spi->controller_data = cdata;
}
/* Set speed to the spi max fequency if qspi device has not set */
spi->max_speed_hz = spi->max_speed_hz ? : tqspi->qspi_max_frequency;
ret = pm_runtime_get_sync(tqspi->dev);
if (ret < 0) {
dev_err(tqspi->dev, "Failed to get runtime PM: %d\n", ret);
return ret;
}
spin_lock_irqsave(&tqspi->lock, flags);
/* keep default cs state to inactive */
val = tqspi->def_command1_reg;
if (spi->mode & SPI_CS_HIGH)
val &= ~QSPI_CS_SW_VAL;
else
val |= QSPI_CS_SW_VAL;
tqspi->def_command1_reg = val;
tegra_qspi_writel(tqspi, tqspi->def_command1_reg, QSPI_COMMAND1);
spin_unlock_irqrestore(&tqspi->lock, flags);
pm_runtime_mark_last_busy(tqspi->dev);
pm_runtime_put_autosuspend(tqspi->dev);
return 0;
}
static int tegra_qspi_cs_low(struct spi_device *spi, bool state)
{
struct tegra_qspi_data *tqspi = spi_master_get_devdata(spi->master);
int ret;
unsigned long val;
unsigned long flags;
if (spi->chip_select >= MAX_CHIP_SELECT) {
dev_err(tqspi->dev, "QSPI Chip select %d is not supported\n",
spi->chip_select);
return -EINVAL;
}
ret = pm_runtime_get_sync(tqspi->dev);
if (ret < 0) {
dev_err(tqspi->dev, "Failed to get runtime PM: %d\n", ret);
return ret;
}
spin_lock_irqsave(&tqspi->lock, flags);
val = tegra_qspi_readl(tqspi, QSPI_COMMAND1);
if (state)
val &= ~QSPI_CS_SW_VAL;
else
val |= QSPI_CS_SW_VAL;
tegra_qspi_writel(tqspi, val, QSPI_COMMAND1);
spin_unlock_irqrestore(&tqspi->lock, flags);
pm_runtime_mark_last_busy(tqspi->dev);
pm_runtime_put_autosuspend(tqspi->dev);
return 0;
}
static int tegra_qspi_combined_sequence_transfer(struct tegra_qspi_data *tqspi,
struct spi_message *msg)
{
bool is_first_msg = true, is_ddr = false;
int single_xfer;
struct spi_transfer *xfer;
struct spi_device *spi = msg->spi;
u8 transfer_phase = 0, bus_width = X1;
int ret;
u32 qspi_setting = 0;
u32 address_value = 0;
u32 cmd_config = 0, addr_config = 0;
u8 cmd_value = 0, len = 0, val = 0;
/* Enable Combined sequence mode */
val = tegra_qspi_readl(tqspi, QSPI_GLOBAL_CONFIG);
val |= QSPI_CMB_SEQ_EN;
tegra_qspi_writel(tqspi, val, QSPI_GLOBAL_CONFIG);
single_xfer = list_is_singular(&msg->transfers);
/* Process individual transfer list */
list_for_each_entry(xfer, &msg->transfers, transfer_list) {
if (transfer_phase == CMD_TRANSFER) {
/* Extract Command configuration and value */
qspi_setting = xfer->delay_usecs;
is_ddr = get_sdr_ddr(qspi_setting);
bus_width = get_bus_width(qspi_setting);
if (is_ddr)
cmd_config |= QSPI_COMMAND_SDR_DDR;
else
cmd_config &= ~QSPI_COMMAND_SDR_DDR;
cmd_config |= QSPI_COMMAND_X1_X2_X4(bus_width);
cmd_config |= QSPI_COMMAND_SIZE_SET(
(xfer->len * 8) - 1);
cmd_value = *((const u8 *)(xfer->tx_buf));
} else if (transfer_phase == ADDR_TRANSFER) {
/* Extract Address configuration and value */
qspi_setting = xfer->delay_usecs;
is_ddr = get_sdr_ddr(qspi_setting);
bus_width = get_bus_width(qspi_setting);
len = xfer->len;
if (is_ddr)
addr_config |= QSPI_ADDRESS_SDR_DDR;
else
addr_config &= ~QSPI_ADDRESS_SDR_DDR;
addr_config |= QSPI_ADDRESS_X1_X2_X4(bus_width);
addr_config |= QSPI_ADDRESS_SIZE_SET(
(xfer->len * 8) - 1);
address_value = *((const u32 *)(xfer->tx_buf));
} else {
/* Program Command, Address value in register */
tegra_qspi_writel(tqspi, cmd_value, QSPI_CMB_SEQ_CMD);
tegra_qspi_writel(tqspi, address_value,
QSPI_CMB_SEQ_ADDR);
/* Program Command and Address config in register */
tegra_qspi_writel(tqspi, cmd_config,
QSPI_CMB_SEQ_CMD_CFG);
tegra_qspi_writel(tqspi, addr_config,
QSPI_CMB_SEQ_ADDR_CFG);
reinit_completion(&tqspi->xfer_completion);
/* Start Data transfer */
ret = tegra_qspi_start_transfer_one(spi, xfer,
is_first_msg,
single_xfer);
if (ret < 0) {
dev_err(tqspi->dev, "Failed to start transfer-one: %d\n",
ret);
return ret;
}
is_first_msg = false;
ret = wait_for_completion_timeout
(&tqspi->xfer_completion,
QSPI_DMA_TIMEOUT);
if (WARN_ON(ret == 0)) {
dev_err(tqspi->dev, "QSPI Transfer failed with timeout: %d\n",
ret);
if (tqspi->is_curr_dma_xfer &&
(tqspi->cur_direction & DATA_DIR_TX))
dmaengine_terminate_all(
tqspi->tx_dma_chan);
if (tqspi->is_curr_dma_xfer &&
(tqspi->cur_direction & DATA_DIR_RX))
dmaengine_terminate_all(
tqspi->rx_dma_chan);
/* Reset controller if timeout happens */
reset_control_reset(tqspi->rstc);
ret = -EIO;
return ret;
}
if (tqspi->tx_status || tqspi->rx_status) {
dev_err(tqspi->dev, "QSPI Transfer failed\n");
tqspi->tx_status = 0;
tqspi->rx_status = 0;
ret = -EIO;
return ret;
}
}
msg->actual_length += xfer->len;
transfer_phase++;
}
return 0;
}
static int tegra_qspi_non_combined_sequence_transfer
(struct tegra_qspi_data *tqspi, struct spi_message *msg)
{
bool is_first_msg = true;
int single_xfer;
struct spi_transfer *xfer;
struct spi_device *spi = msg->spi;
int ret;
u8 val = 0;
val = tegra_qspi_readl(tqspi, QSPI_GLOBAL_CONFIG);
val &= ~QSPI_CMB_SEQ_EN;
tegra_qspi_writel(tqspi, val, QSPI_GLOBAL_CONFIG);
single_xfer = list_is_singular(&msg->transfers);
list_for_each_entry(xfer, &msg->transfers, transfer_list) {
reinit_completion(&tqspi->xfer_completion);
ret = tegra_qspi_start_transfer_one(spi, xfer,
is_first_msg,
single_xfer);
if (ret < 0) {
dev_err(tqspi->dev, "Failed to start transfer-one: %d\n",
ret);
return ret;
}
is_first_msg = false;
ret = wait_for_completion_timeout(&tqspi->xfer_completion,
QSPI_DMA_TIMEOUT);
if (WARN_ON(ret == 0)) {
dev_err(tqspi->dev, "QSPI Transfer failed with timeout\n");
if (tqspi->is_curr_dma_xfer &&
(tqspi->cur_direction & DATA_DIR_TX))
dmaengine_terminate_all(tqspi->tx_dma_chan);
if (tqspi->is_curr_dma_xfer &&
(tqspi->cur_direction & DATA_DIR_RX))
dmaengine_terminate_all(tqspi->rx_dma_chan);
/* Reset controller in case of timeout happens */
reset_control_reset(tqspi->rstc);
ret = -EIO;
return ret;
}
if (tqspi->tx_status || tqspi->rx_status) {
dev_err(tqspi->dev, "QSPI Transfer failed\n");
tqspi->tx_status = 0;
tqspi->rx_status = 0;
ret = -EIO;
return ret;
}
msg->actual_length += xfer->len;
}
return 0;
}
static int tegra_qspi_transfer_one_message(struct spi_master *master,
struct spi_message *msg)
{
struct tegra_qspi_data *tqspi = spi_master_get_devdata(master);
struct spi_transfer *xfer;
u8 count_number_of_transfers = 0;
int ret;
msg->status = 0;
msg->actual_length = 0;
ret = pm_runtime_get_sync(tqspi->dev);
if (ret < 0) {
dev_err(tqspi->dev, "Failed to get runtime PM: %d\n", ret);
msg->status = ret;
spi_finalize_current_message(master);
return ret;
}
list_for_each_entry(xfer, &msg->transfers, transfer_list) {
count_number_of_transfers++;
}
/*
* Do Combined sequence mode related processing if it is enabled in DT
* Support for Combined Sequence mode is available from T18X onwards
* Combined sequence mode is applicable for <CMD><ADDR><DATA> transfers
* Non combined mode transfer is used in other transfers
*/
if (tqspi->qspi_enable_cmbseq_mode && count_number_of_transfers == 3) {
tqspi->dcycle_non_cmbseq_mode = false;
ret = tegra_qspi_combined_sequence_transfer(tqspi, msg);
if (ret < 0) {
dev_err(tqspi->dev, "QSPI combined sequence transfer failed: %d\n",
ret);
goto exit;
}
} else {
tqspi->dcycle_non_cmbseq_mode = true;
ret = tegra_qspi_non_combined_sequence_transfer(tqspi, msg);
if (ret < 0) {
dev_err(tqspi->dev, "QSPI non-combined sequence transfer failed: %d\n",
ret);
goto exit;
}
}
ret = 0;
exit:
tegra_qspi_writel(tqspi, tqspi->def_command1_reg, QSPI_COMMAND1);
pm_runtime_mark_last_busy(tqspi->dev);
pm_runtime_put_autosuspend(tqspi->dev);
msg->status = ret;
spi_finalize_current_message(master);
return ret;
}
#ifdef QSPI_BRINGUP_BUILD
static void handle_combined_sequence(struct tegra_qspi_data *tqspi)
{
u8 val = 0;
/* clear combined sequence enable */
val = tegra_qspi_readl(tqspi, QSPI_GLOBAL_CONFIG);
val &= ~QSPI_CMB_SEQ_EN;
tegra_qspi_writel(tqspi, val, QSPI_GLOBAL_CONFIG);
}
#endif
static irqreturn_t handle_cpu_based_xfer(struct tegra_qspi_data *tqspi)
{
struct spi_transfer *t = tqspi->curr_xfer;
unsigned long flags;
spin_lock_irqsave(&tqspi->lock, flags);
if (tqspi->tx_status || tqspi->rx_status) {
dev_err(tqspi->dev, "CpuXfer ERROR, status 0x%08x\n",
tqspi->status_reg);
dev_err(tqspi->dev, "CpuXfer command1:dmacontro->0x%08x:0x%08x\n",
tqspi->command1_reg, tqspi->dma_control_reg);
reset_control_reset(tqspi->rstc);
complete(&tqspi->xfer_completion);
tqspi->tx_status = 0;
tqspi->rx_status = 0;
goto exit;
}
if (tqspi->cur_direction & DATA_DIR_RX)
tegra_qspi_read_rx_fifo_to_client_rxbuf(tqspi, t);
if (tqspi->cur_direction & DATA_DIR_TX)
tqspi->cur_pos = tqspi->cur_tx_pos;
else
tqspi->cur_pos = tqspi->cur_rx_pos;
if (tqspi->cur_pos >= t->len) {
complete(&tqspi->xfer_completion);
goto exit;
}
tegra_qspi_calculate_curr_xfer_param(tqspi->cur_qspi, tqspi, t);
tegra_qspi_start_cpu_based_transfer(tqspi, t);
exit:
spin_unlock_irqrestore(&tqspi->lock, flags);
return IRQ_HANDLED;
}
static irqreturn_t handle_dma_based_xfer(struct tegra_qspi_data *tqspi)
{
struct spi_transfer *t = tqspi->curr_xfer;
long wait_status;
int err = 0;
unsigned total_fifo_words;
unsigned long flags;
/* Abort dmas if any error */
if (tqspi->cur_direction & DATA_DIR_TX) {
if (tqspi->tx_status) {
dmaengine_terminate_all(tqspi->tx_dma_chan);
err += 1;
} else {
wait_status = wait_for_completion_interruptible_timeout(
&tqspi->tx_dma_complete,
QSPI_DMA_TIMEOUT);
if (wait_status <= 0) {
dmaengine_terminate_all(tqspi->tx_dma_chan);
dev_err(tqspi->dev, "TxDma Xfer failed\n");
err += 1;
}
}
}
if (tqspi->cur_direction & DATA_DIR_RX) {
if (tqspi->rx_status) {
dmaengine_terminate_all(tqspi->rx_dma_chan);
err += 2;
} else {
wait_status = wait_for_completion_interruptible_timeout(
&tqspi->rx_dma_complete, QSPI_DMA_TIMEOUT);
if (wait_status <= 0) {
dmaengine_terminate_all(tqspi->rx_dma_chan);
dev_err(tqspi->dev, "RxDma Xfer failed\n");
err += 2;
}
}
}
spin_lock_irqsave(&tqspi->lock, flags);
if (err) {
dev_err(tqspi->dev, "DmaXfer ERROR, status 0x%08x\n",
tqspi->status_reg);
dev_err(tqspi->dev, "DmaXfer command1:dmacontro->0x%08x:0x%08x\n",
tqspi->command1_reg, tqspi->dma_control_reg);
reset_control_reset(tqspi->rstc);
complete(&tqspi->xfer_completion);
tqspi->rx_status = 0;
tqspi->tx_status = 0;
spin_unlock_irqrestore(&tqspi->lock, flags);
return IRQ_HANDLED;
}
if (tqspi->cur_direction & DATA_DIR_RX)
tegra_qspi_copy_qspi_rxbuf_to_client_rxbuf(tqspi, t);
if (tqspi->cur_direction & DATA_DIR_TX)
tqspi->cur_pos = tqspi->cur_tx_pos;
else
tqspi->cur_pos = tqspi->cur_rx_pos;
if (tqspi->cur_pos >= t->len) {
complete(&tqspi->xfer_completion);
goto exit;
}
#ifdef QSPI_BRINGUP_BUILD
if (tqspi->qspi_force_dma_mode) {
err = tegra_qspi_start_dma_based_transfer(tqspi, t);
goto exit;
}
#endif
/* Continue transfer in current message */
total_fifo_words = tegra_qspi_calculate_curr_xfer_param(tqspi->cur_qspi,
tqspi, t);
if (total_fifo_words > QSPI_FIFO_DEPTH)
err = tegra_qspi_start_dma_based_transfer(tqspi, t);
else
err = tegra_qspi_start_cpu_based_transfer(tqspi, t);
exit:
spin_unlock_irqrestore(&tqspi->lock, flags);
return IRQ_HANDLED;
}
static irqreturn_t tegra_qspi_isr_thread(int irq, void *context_data)
{
struct tegra_qspi_data *tqspi = context_data;
#ifdef QSPI_BRINGUP_BUILD
if (tqspi->qspi_enable_cmbseq_mode)
handle_combined_sequence(tqspi);
#endif
if (!tqspi->is_curr_dma_xfer)
return handle_cpu_based_xfer(tqspi);
return handle_dma_based_xfer(tqspi);
}
static irqreturn_t tegra_qspi_isr(int irq, void *context_data)
{
struct tegra_qspi_data *tqspi = context_data;
tegra_qspi_dump_regs("From QSPI ISR", tqspi);
tqspi->status_reg = tegra_qspi_readl(tqspi, QSPI_FIFO_STATUS);
if (tqspi->cur_direction & DATA_DIR_TX)
tqspi->tx_status = tqspi->status_reg &
(QSPI_TX_FIFO_UNF | QSPI_TX_FIFO_OVF);
if (tqspi->cur_direction & DATA_DIR_RX)
tqspi->rx_status = tqspi->status_reg &
(QSPI_RX_FIFO_OVF | QSPI_RX_FIFO_UNF);
if (!(tqspi->cur_direction & DATA_DIR_TX) &&
!(tqspi->cur_direction & DATA_DIR_RX))
dev_err(tqspi->dev, "QSPI get spurious interrupt, Status = 0x%08x\n",
tqspi->status_reg);
tegra_qspi_clear_status(tqspi);
return IRQ_WAKE_THREAD;
}
static int tegra_qspi_clk_enable(struct tegra_qspi_data *tqspi)
{
int ret;
ret = clk_prepare_enable(tqspi->clk);
if (ret < 0) {
dev_err(tqspi->dev, "Failed to enable QSPI clock: %d\n", ret);
return ret;
}
ret = clk_prepare_enable(tqspi->sdr_ddr_clk);
if (ret < 0) {
dev_err(tqspi->dev, "Failed to enable QSPI-OUT clk: %d\n", ret);
clk_disable_unprepare(tqspi->clk);
return ret;
}
return ret;
}
static void tegra_qspi_clk_disable(struct tegra_qspi_data *tqspi)
{
clk_disable_unprepare(tqspi->sdr_ddr_clk);
clk_disable_unprepare(tqspi->clk);
}
static void set_best_clk_source(struct tegra_qspi_data *tqspi,
unsigned long rate)
{
long new_rate;
unsigned long err_rate;
unsigned int fin_err = rate;
int ret;
struct clk *pclk, *fpclk = NULL;
const char *pclk_name, *fpclk_name = NULL;
struct device_node *node = tqspi->dev->of_node;
struct property *prop;
if (!of_property_count_strings(node, "nvidia,clk-parents"))
return;
of_property_for_each_string(node, "nvidia,clk-parents",
prop, pclk_name) {
pclk = clk_get(tqspi->dev, pclk_name);
if (IS_ERR(pclk))
continue;
ret = clk_set_parent(tqspi->clk, pclk);
if (ret < 0) {
dev_warn(tqspi->dev, "Failed to set parent clk: %d\n",
ret);
continue;
}
new_rate = clk_round_rate(tqspi->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(tqspi->dev, "Setting clk_src %s\n", fpclk_name);
clk_set_parent(tqspi->clk, fpclk);
}
}
static struct tegra_qspi_device_controller_data *tegra_qspi_get_cdata_dt(
struct spi_device *spi)
{
struct tegra_qspi_device_controller_data *cdata = NULL;
struct device_node *np = spi->dev.of_node, *data_np = NULL;
u32 pval;
if (!np) {
dev_dbg(&spi->dev, "Device must have DT node handle\n");
return NULL;
}
data_np = of_get_child_by_name(np, "controller-data");
if (!data_np) {
dev_dbg(&spi->dev, "child node 'controller-data' not found\n");
return NULL;
}
cdata = kzalloc(sizeof(*cdata), GFP_KERNEL);
if (!cdata)
return NULL;
if (!of_property_read_u32(data_np, "nvidia,x1-len-limit", &pval))
cdata->x1_len_limit = pval;
if (!of_property_read_u32(data_np, "nvidia,x1-bus-speed", &pval))
cdata->x1_bus_speed = pval;
if (!of_property_read_u32(data_np, "nvidia,x1-dymmy-cycle", &pval))
cdata->x1_dymmy_cycle = pval;
if (!of_property_read_u32(data_np, "nvidia,x4-bus-speed", &pval))
cdata->x4_bus_speed = pval;
if (!of_property_read_u32(data_np, "nvidia,x4-dymmy-cycle", &pval))
cdata->x4_dymmy_cycle = pval;
if (!of_property_read_u32(data_np, "nvidia,x4-is-ddr", &pval))
cdata->x4_is_ddr = pval;
if (!of_property_read_u32(data_np, "nvidia,ifddr-div2-sdr", &pval))
cdata->ifddr_div2_sdr = pval;
if (!of_property_read_u32(data_np, "nvidia,ctrl-bus-clk-ratio",
&pval))
cdata->bus_clk_div = (u8)pval;
cdata->is_combined_seq_mode_en = of_property_read_bool(data_np,
"nvidia,combined-seq-mode-en");
/* Bus speed mentioned in device tree should be what is applied
* on interface. Earlier version used to apply half of the bus
* speed defined in device tree. To maintain backward compatibility
* with old device tree, applied bus speed is half of that defined in
* device tree if 'nvidia,ifddr-div2-sdr' is defined
*/
if (cdata->ifddr_div2_sdr && cdata->x1_bus_speed)
cdata->x1_bus_speed /= 2;
if (cdata->ifddr_div2_sdr && cdata->x4_bus_speed)
cdata->x4_bus_speed /= 2;
return cdata;
}
static void tegra_qspi_parse_dt(struct device *dev,
struct tegra_qspi_data *tqspi)
{
struct device_node *np = dev->of_node;
u32 pval;
int ret;
tqspi->enable_dma_support = of_property_read_bool(np, "dma-names");
ret = of_property_read_u32(np, "spi-max-frequency", &pval);
if (!ret)
tqspi->qspi_max_frequency = pval;
else
tqspi->qspi_max_frequency = 136000000; /* 136MHz */
tqspi->clock_always_on = of_property_read_bool(np,
"nvidia,clock-always-on");
}
static int tegra_qspi_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct spi_master *master;
struct tegra_qspi_data *tqspi;
struct resource *r;
int ret, qspi_irq;
u32 as_delay;
u32 actual_speed = 0;
master = spi_alloc_master(&pdev->dev, sizeof(*tqspi));
if (!master) {
dev_err(&pdev->dev, "SPI master allocation failed\n");
return -ENOMEM;
}
master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
master->setup = tegra_qspi_setup;
master->cleanup = tegra_qspi_clean;
master->transfer_one_message = tegra_qspi_transfer_one_message;
master->num_chipselect = MAX_CHIP_SELECT;
master->bus_num = -1;
master->spi_cs_low = tegra_qspi_cs_low;
dev_set_drvdata(&pdev->dev, master);
tqspi = spi_master_get_devdata(master);
tqspi->master = master;
tegra_qspi_parse_dt(&pdev->dev, tqspi);
tqspi->dev = &pdev->dev;
tqspi->prod_list = devm_tegra_prod_get(&pdev->dev);
if (IS_ERR(tqspi->prod_list)) {
dev_info(&pdev->dev, "Prod settings list not found\n");
tqspi->prod_list = NULL;
}
spin_lock_init(&tqspi->lock);
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!r) {
dev_err(&pdev->dev, "Failed to get IO memory\n");
ret = -ENODEV;
goto exit_free_master;
}
tqspi->phys = r->start;
tqspi->base = devm_ioremap_resource(&pdev->dev, r);
if (IS_ERR(tqspi->base)) {
ret = PTR_ERR(tqspi->base);
dev_err(dev, "Failed to request memregion/iomap address: %d\n",
ret);
goto exit_free_master;
}
tqspi->rstc = devm_reset_control_get(&pdev->dev, "qspi");
if (IS_ERR(tqspi->rstc)) {
ret = PTR_ERR(tqspi->rstc);
dev_err(&pdev->dev, "Failed to get reset control: %d\n", ret);
goto exit_free_master;
}
reset_control_reset(tqspi->rstc);
qspi_irq = platform_get_irq(pdev, 0);
tqspi->irq = qspi_irq;
ret = devm_request_threaded_irq(dev, tqspi->irq, tegra_qspi_isr,
tegra_qspi_isr_thread, IRQF_ONESHOT,
dev_name(&pdev->dev), tqspi);
if (ret < 0) {
dev_err(dev, "Failed to register interrupt: %d\n", tqspi->irq);
goto exit_free_master;
}
tqspi->clk = devm_clk_get(&pdev->dev, "qspi");
if (IS_ERR(tqspi->clk)) {
ret = PTR_ERR(tqspi->clk);
dev_err(&pdev->dev, "Failed to get QSPI clock: %d\n", ret);
goto exit_free_master;
}
tqspi->sdr_ddr_clk = devm_clk_get(&pdev->dev, "qspi_out");
if (IS_ERR(tqspi->sdr_ddr_clk)) {
ret = PTR_ERR(tqspi->sdr_ddr_clk);
dev_err(&pdev->dev, "Failed to get QSPI-OUT: %d\n", ret);
goto exit_free_master;
}
/* Set default mode to SDR */
tqspi->is_ddr_mode = false;
tqspi->max_buf_size = QSPI_FIFO_DEPTH << 2;
tqspi->dma_buf_size = DEFAULT_SPI_DMA_BUF_LEN;
if (tqspi->enable_dma_support) {
ret = tegra_qspi_init_dma_param(tqspi, true);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to initialise RxDma: %d\n",
ret);
goto exit_free_master;
}
ret = tegra_qspi_init_dma_param(tqspi, false);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to initialise TxDma: %d\n",
ret);
goto exit_rx_dma_free;
}
tqspi->max_buf_size = tqspi->dma_buf_size;
init_completion(&tqspi->tx_dma_complete);
init_completion(&tqspi->rx_dma_complete);
}
init_completion(&tqspi->xfer_completion);
if (tqspi->clock_always_on) {
ret = tegra_qspi_clk_enable(tqspi);
if (ret < 0)
goto exit_deinit_dma;
}
ret = of_property_read_u32(dev->of_node, "qspi-autosuspend-delay",
&as_delay);
if (ret)
as_delay = 3000; /* defalut autosuspend delay */
pm_runtime_set_autosuspend_delay(&pdev->dev, as_delay);
pm_runtime_use_autosuspend(&pdev->dev);
pm_runtime_enable(&pdev->dev);
if (!pm_runtime_enabled(&pdev->dev)) {
ret = tegra_qspi_runtime_resume(&pdev->dev);
if (ret)
goto exit_pm_disable;
}
ret = pm_runtime_get_sync(&pdev->dev);
if (ret < 0) {
dev_err(tqspi->dev, "Failed to get runtime PM: %d\n", ret);
goto exit_pm_disable;
}
set_best_clk_source(tqspi, tqspi->qspi_max_frequency);
ret = clk_set_rate(tqspi->clk, tqspi->qspi_max_frequency);
if (ret) {
dev_err(dev, "Failed to set qspi clk freq %d\n", ret);
goto exit_pm_disable;
}
tqspi->cur_speed = tqspi->qspi_max_frequency;
actual_speed = clk_get_rate(tqspi->clk);
if (actual_speed > 0) {
ret = clk_set_rate(tqspi->sdr_ddr_clk, actual_speed >> 1);
if (ret) {
dev_err(dev, "Failed to set qspi_out clk freq %d\n",
ret);
goto exit_pm_disable;
}
tqspi->bus_clk_div = 2;
}
tqspi->def_command1_reg = QSPI_M_S | QSPI_CS_SW_HW | QSPI_CS_SW_VAL;
tegra_qspi_writel(tqspi, tqspi->def_command1_reg, QSPI_COMMAND1);
tqspi->def_command2_reg = tegra_qspi_readl(tqspi, QSPI_COMMAND2);
tegra_qspi_set_gr_registers(tqspi);
tegra_qspi_tap_delays(tqspi, tx_tap_delay, rx_tap_delay);
pm_runtime_mark_last_busy(&pdev->dev);
pm_runtime_put_autosuspend(&pdev->dev);
master->dev.of_node = pdev->dev.of_node;
ret = devm_spi_register_master(&pdev->dev, master);
if (ret < 0) {
dev_err(dev, "Failed to register spi master: %d\n", ret);
goto exit_pm_disable;
}
#ifdef QSPI_BRINGUP_BUILD
ret = sysfs_create_group(&dev->kobj, tegra_qspi_groups[0]);
if (ret)
goto exit_pm_disable;
tqspi->qspi_force_bus_speed = false;
#endif
return ret;
exit_pm_disable:
pm_runtime_put_noidle(&pdev->dev);
pm_runtime_disable(&pdev->dev);
if (!pm_runtime_status_suspended(&pdev->dev))
tegra_qspi_runtime_suspend(&pdev->dev);
if (tqspi->clock_always_on)
tegra_qspi_clk_disable(tqspi);
exit_deinit_dma:
tegra_qspi_deinit_dma_param(tqspi, false);
exit_rx_dma_free:
tegra_qspi_deinit_dma_param(tqspi, true);
exit_free_master:
spi_master_put(master);
return ret;
}
static int tegra_qspi_remove(struct platform_device *pdev)
{
struct spi_master *master = dev_get_drvdata(&pdev->dev);
struct tegra_qspi_data *tqspi = spi_master_get_devdata(master);
#ifdef QSPI_BRINGUP_BUILD
sysfs_remove_group(&pdev->dev.kobj, tegra_qspi_groups[0]);
#endif
if (tqspi->tx_dma_chan)
tegra_qspi_deinit_dma_param(tqspi, false);
if (tqspi->rx_dma_chan)
tegra_qspi_deinit_dma_param(tqspi, true);
pm_runtime_put_noidle(&pdev->dev);
pm_runtime_disable(&pdev->dev);
if (!pm_runtime_status_suspended(&pdev->dev))
tegra_qspi_runtime_suspend(&pdev->dev);
if (tqspi->clock_always_on)
tegra_qspi_clk_disable(tqspi);
return 0;
}
#ifdef CONFIG_PM_SLEEP
static int tegra_qspi_suspend(struct device *dev)
{
struct spi_master *master = dev_get_drvdata(dev);
struct tegra_qspi_data *tqspi = spi_master_get_devdata(master);
int ret;
ret = spi_master_suspend(master);
if (tqspi->clock_always_on)
tegra_qspi_clk_disable(tqspi);
return ret;
}
static int tegra_qspi_resume(struct device *dev)
{
struct spi_master *master = dev_get_drvdata(dev);
struct tegra_qspi_data *tqspi = spi_master_get_devdata(master);
int ret;
if (tqspi->clock_always_on) {
ret = tegra_qspi_clk_enable(tqspi);
if (ret < 0)
return ret;
}
ret = pm_runtime_get_sync(dev);
if (ret < 0) {
dev_err(tqspi->dev, "Failed to get runtime PM: %d\n", ret);
return ret;
}
tegra_qspi_writel(tqspi, tqspi->command1_reg, QSPI_COMMAND1);
tegra_qspi_set_gr_registers(tqspi);
tegra_qspi_tap_delays(tqspi, tx_tap_delay, rx_tap_delay);
pm_runtime_mark_last_busy(dev);
pm_runtime_put_autosuspend(dev);
return spi_master_resume(master);
}
#endif
static int tegra_qspi_runtime_suspend(struct device *dev)
{
struct spi_master *master = dev_get_drvdata(dev);
struct tegra_qspi_data *tqspi = spi_master_get_devdata(master);
/* Flush all write which are in PPSB queue by reading back */
tegra_qspi_readl(tqspi, QSPI_COMMAND1);
tegra_qspi_clk_disable(tqspi);
return 0;
}
static int tegra_qspi_runtime_resume(struct device *dev)
{
struct spi_master *master = dev_get_drvdata(dev);
struct tegra_qspi_data *tqspi = spi_master_get_devdata(master);
return tegra_qspi_clk_enable(tqspi);
}
static const struct dev_pm_ops tegra_qspi_pm_ops = {
SET_RUNTIME_PM_OPS(tegra_qspi_runtime_suspend,
tegra_qspi_runtime_resume, NULL)
SET_SYSTEM_SLEEP_PM_OPS(tegra_qspi_suspend, tegra_qspi_resume)
};
static const struct of_device_id tegra_qspi_of_match[] = {
{ .compatible = "nvidia,tegra186-qspi", },
{ .compatible = "nvidia,tegra210-qspi", },
{}
};
MODULE_DEVICE_TABLE(of, tegra_qspi_of_match);
static struct platform_driver tegra_qspi_driver = {
.driver = {
.name = "tegra-qspi",
.pm = &tegra_qspi_pm_ops,
.of_match_table = tegra_qspi_of_match,
},
.probe = tegra_qspi_probe,
.remove = tegra_qspi_remove,
};
module_platform_driver(tegra_qspi_driver);
MODULE_DESCRIPTION("NVIDIA Tegra186 QSPI Controller Driver");
MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
MODULE_AUTHOR("Amlan Kundu <akundu@nvidia.com>");
MODULE_LICENSE("GPL v2");