summaryrefslogtreecommitdiffstats
path: root/drivers/spi
diff options
context:
space:
mode:
authorSowjanya Komatineni <skomatineni@nvidia.com>2019-04-04 20:14:12 -0400
committerMark Brown <broonie@kernel.org>2019-04-08 03:13:06 -0400
commitfa28fd3421373794e98eb3e511969fea5a8b2fc3 (patch)
tree0de45445102e0d2de55117b41540f39462e0df1a /drivers/spi
parent9d199231b000414e420a35912760f2d67e9c56d7 (diff)
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: Sowjanya Komatineni <skomatineni@nvidia.com> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'drivers/spi')
-rw-r--r--drivers/spi/spi-tegra114.c53
1 files changed, 48 insertions, 5 deletions
diff --git a/drivers/spi/spi-tegra114.c b/drivers/spi/spi-tegra114.c
index 751672b3bc16..b8c6393e2190 100644
--- a/drivers/spi/spi-tegra114.c
+++ b/drivers/spi/spi-tegra114.c
@@ -149,6 +149,8 @@
149 149
150#define SPI_TX_FIFO 0x108 150#define SPI_TX_FIFO 0x108
151#define SPI_RX_FIFO 0x188 151#define SPI_RX_FIFO 0x188
152#define SPI_INTR_MASK 0x18c
153#define SPI_INTR_ALL_MASK (0x1fUL << 25)
152#define MAX_CHIP_SELECT 4 154#define MAX_CHIP_SELECT 4
153#define SPI_FIFO_DEPTH 64 155#define SPI_FIFO_DEPTH 64
154#define DATA_DIR_TX (1 << 0) 156#define DATA_DIR_TX (1 << 0)
@@ -161,6 +163,10 @@
161#define MAX_HOLD_CYCLES 16 163#define MAX_HOLD_CYCLES 16
162#define SPI_DEFAULT_SPEED 25000000 164#define SPI_DEFAULT_SPEED 25000000
163 165
166struct tegra_spi_soc_data {
167 bool has_intr_mask_reg;
168};
169
164struct tegra_spi_data { 170struct tegra_spi_data {
165 struct device *dev; 171 struct device *dev;
166 struct spi_master *master; 172 struct spi_master *master;
@@ -211,6 +217,7 @@ struct tegra_spi_data {
211 u32 *tx_dma_buf; 217 u32 *tx_dma_buf;
212 dma_addr_t tx_dma_phys; 218 dma_addr_t tx_dma_phys;
213 struct dma_async_tx_descriptor *tx_dma_desc; 219 struct dma_async_tx_descriptor *tx_dma_desc;
220 const struct tegra_spi_soc_data *soc_data;
214}; 221};
215 222
216static int tegra_spi_runtime_suspend(struct device *dev); 223static int tegra_spi_runtime_suspend(struct device *dev);
@@ -554,11 +561,13 @@ static int tegra_spi_start_dma_based_transfer(
554 dma_burst = 8; 561 dma_burst = 8;
555 } 562 }
556 563
557 if (tspi->cur_direction & DATA_DIR_TX) 564 if (!tspi->soc_data->has_intr_mask_reg) {
558 val |= SPI_IE_TX; 565 if (tspi->cur_direction & DATA_DIR_TX)
566 val |= SPI_IE_TX;
559 567
560 if (tspi->cur_direction & DATA_DIR_RX) 568 if (tspi->cur_direction & DATA_DIR_RX)
561 val |= SPI_IE_RX; 569 val |= SPI_IE_RX;
570 }
562 571
563 tegra_spi_writel(tspi, val, SPI_DMA_CTL); 572 tegra_spi_writel(tspi, val, SPI_DMA_CTL);
564 tspi->dma_control_reg = val; 573 tspi->dma_control_reg = val;
@@ -847,6 +856,12 @@ static int tegra_spi_setup(struct spi_device *spi)
847 return ret; 856 return ret;
848 } 857 }
849 858
859 if (tspi->soc_data->has_intr_mask_reg) {
860 val = tegra_spi_readl(tspi, SPI_INTR_MASK);
861 val &= ~SPI_INTR_ALL_MASK;
862 tegra_spi_writel(tspi, val, SPI_INTR_MASK);
863 }
864
850 spin_lock_irqsave(&tspi->lock, flags); 865 spin_lock_irqsave(&tspi->lock, flags);
851 val = tspi->def_command1_reg; 866 val = tspi->def_command1_reg;
852 if (spi->mode & SPI_CS_HIGH) 867 if (spi->mode & SPI_CS_HIGH)
@@ -1135,8 +1150,29 @@ static irqreturn_t tegra_spi_isr(int irq, void *context_data)
1135 return IRQ_WAKE_THREAD; 1150 return IRQ_WAKE_THREAD;
1136} 1151}
1137 1152
1153static struct tegra_spi_soc_data tegra114_spi_soc_data = {
1154 .has_intr_mask_reg = false,
1155};
1156
1157static struct tegra_spi_soc_data tegra124_spi_soc_data = {
1158 .has_intr_mask_reg = false,
1159};
1160
1161static struct tegra_spi_soc_data tegra210_spi_soc_data = {
1162 .has_intr_mask_reg = true,
1163};
1164
1138static const struct of_device_id tegra_spi_of_match[] = { 1165static const struct of_device_id tegra_spi_of_match[] = {
1139 { .compatible = "nvidia,tegra114-spi", }, 1166 {
1167 .compatible = "nvidia,tegra114-spi",
1168 .data = &tegra114_spi_soc_data,
1169 }, {
1170 .compatible = "nvidia,tegra124-spi",
1171 .data = &tegra124_spi_soc_data,
1172 }, {
1173 .compatible = "nvidia,tegra210-spi",
1174 .data = &tegra210_spi_soc_data,
1175 },
1140 {} 1176 {}
1141}; 1177};
1142MODULE_DEVICE_TABLE(of, tegra_spi_of_match); 1178MODULE_DEVICE_TABLE(of, tegra_spi_of_match);
@@ -1177,6 +1213,13 @@ static int tegra_spi_probe(struct platform_device *pdev)
1177 tspi->dev = &pdev->dev; 1213 tspi->dev = &pdev->dev;
1178 spin_lock_init(&tspi->lock); 1214 spin_lock_init(&tspi->lock);
1179 1215
1216 tspi->soc_data = of_device_get_match_data(&pdev->dev);
1217 if (!tspi->soc_data) {
1218 dev_err(&pdev->dev, "unsupported tegra\n");
1219 ret = -ENODEV;
1220 goto exit_free_master;
1221 }
1222
1180 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1223 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1181 tspi->base = devm_ioremap_resource(&pdev->dev, r); 1224 tspi->base = devm_ioremap_resource(&pdev->dev, r);
1182 if (IS_ERR(tspi->base)) { 1225 if (IS_ERR(tspi->base)) {