Commit fa28fd34 authored by Sowjanya Komatineni's avatar Sowjanya Komatineni Committed by Mark Brown

spi: tegra114: add support for interrupt mask

This patch creates tegra_spi_soc_data structure to maintain and implement
SPI HW feature differences between different Tegra chips and also creates
a separate compatible string for T124/T210.

Tegra210 and later has a separate interrupt mask register SPI_INTR_MASK
for enabling or disabling interrupts while Tegra124 and prior uses
interrupt enable bits in SPI_DMA_CTL register.

This patch creates flag has_intr_mask_reg in tegra_spi_soc_data to
identify this and implements accordingly.
Signed-off-by: default avatarSowjanya Komatineni <skomatineni@nvidia.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 9d199231
...@@ -149,6 +149,8 @@ ...@@ -149,6 +149,8 @@
#define SPI_TX_FIFO 0x108 #define SPI_TX_FIFO 0x108
#define SPI_RX_FIFO 0x188 #define SPI_RX_FIFO 0x188
#define SPI_INTR_MASK 0x18c
#define SPI_INTR_ALL_MASK (0x1fUL << 25)
#define MAX_CHIP_SELECT 4 #define MAX_CHIP_SELECT 4
#define SPI_FIFO_DEPTH 64 #define SPI_FIFO_DEPTH 64
#define DATA_DIR_TX (1 << 0) #define DATA_DIR_TX (1 << 0)
...@@ -161,6 +163,10 @@ ...@@ -161,6 +163,10 @@
#define MAX_HOLD_CYCLES 16 #define MAX_HOLD_CYCLES 16
#define SPI_DEFAULT_SPEED 25000000 #define SPI_DEFAULT_SPEED 25000000
struct tegra_spi_soc_data {
bool has_intr_mask_reg;
};
struct tegra_spi_data { struct tegra_spi_data {
struct device *dev; struct device *dev;
struct spi_master *master; struct spi_master *master;
...@@ -211,6 +217,7 @@ struct tegra_spi_data { ...@@ -211,6 +217,7 @@ struct tegra_spi_data {
u32 *tx_dma_buf; u32 *tx_dma_buf;
dma_addr_t tx_dma_phys; dma_addr_t tx_dma_phys;
struct dma_async_tx_descriptor *tx_dma_desc; struct dma_async_tx_descriptor *tx_dma_desc;
const struct tegra_spi_soc_data *soc_data;
}; };
static int tegra_spi_runtime_suspend(struct device *dev); static int tegra_spi_runtime_suspend(struct device *dev);
...@@ -554,11 +561,13 @@ static int tegra_spi_start_dma_based_transfer( ...@@ -554,11 +561,13 @@ static int tegra_spi_start_dma_based_transfer(
dma_burst = 8; dma_burst = 8;
} }
if (tspi->cur_direction & DATA_DIR_TX) if (!tspi->soc_data->has_intr_mask_reg) {
val |= SPI_IE_TX; if (tspi->cur_direction & DATA_DIR_TX)
val |= SPI_IE_TX;
if (tspi->cur_direction & DATA_DIR_RX) if (tspi->cur_direction & DATA_DIR_RX)
val |= SPI_IE_RX; val |= SPI_IE_RX;
}
tegra_spi_writel(tspi, val, SPI_DMA_CTL); tegra_spi_writel(tspi, val, SPI_DMA_CTL);
tspi->dma_control_reg = val; tspi->dma_control_reg = val;
...@@ -847,6 +856,12 @@ static int tegra_spi_setup(struct spi_device *spi) ...@@ -847,6 +856,12 @@ static int tegra_spi_setup(struct spi_device *spi)
return ret; return ret;
} }
if (tspi->soc_data->has_intr_mask_reg) {
val = tegra_spi_readl(tspi, SPI_INTR_MASK);
val &= ~SPI_INTR_ALL_MASK;
tegra_spi_writel(tspi, val, SPI_INTR_MASK);
}
spin_lock_irqsave(&tspi->lock, flags); spin_lock_irqsave(&tspi->lock, flags);
val = tspi->def_command1_reg; val = tspi->def_command1_reg;
if (spi->mode & SPI_CS_HIGH) if (spi->mode & SPI_CS_HIGH)
...@@ -1135,8 +1150,29 @@ static irqreturn_t tegra_spi_isr(int irq, void *context_data) ...@@ -1135,8 +1150,29 @@ static irqreturn_t tegra_spi_isr(int irq, void *context_data)
return IRQ_WAKE_THREAD; return IRQ_WAKE_THREAD;
} }
static struct tegra_spi_soc_data tegra114_spi_soc_data = {
.has_intr_mask_reg = false,
};
static struct tegra_spi_soc_data tegra124_spi_soc_data = {
.has_intr_mask_reg = false,
};
static struct tegra_spi_soc_data tegra210_spi_soc_data = {
.has_intr_mask_reg = true,
};
static const struct of_device_id tegra_spi_of_match[] = { static const struct of_device_id tegra_spi_of_match[] = {
{ .compatible = "nvidia,tegra114-spi", }, {
.compatible = "nvidia,tegra114-spi",
.data = &tegra114_spi_soc_data,
}, {
.compatible = "nvidia,tegra124-spi",
.data = &tegra124_spi_soc_data,
}, {
.compatible = "nvidia,tegra210-spi",
.data = &tegra210_spi_soc_data,
},
{} {}
}; };
MODULE_DEVICE_TABLE(of, tegra_spi_of_match); MODULE_DEVICE_TABLE(of, tegra_spi_of_match);
...@@ -1177,6 +1213,13 @@ static int tegra_spi_probe(struct platform_device *pdev) ...@@ -1177,6 +1213,13 @@ static int tegra_spi_probe(struct platform_device *pdev)
tspi->dev = &pdev->dev; tspi->dev = &pdev->dev;
spin_lock_init(&tspi->lock); spin_lock_init(&tspi->lock);
tspi->soc_data = of_device_get_match_data(&pdev->dev);
if (!tspi->soc_data) {
dev_err(&pdev->dev, "unsupported tegra\n");
ret = -ENODEV;
goto exit_free_master;
}
r = platform_get_resource(pdev, IORESOURCE_MEM, 0); r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
tspi->base = devm_ioremap_resource(&pdev->dev, r); tspi->base = devm_ioremap_resource(&pdev->dev, r);
if (IS_ERR(tspi->base)) { if (IS_ERR(tspi->base)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment