diff options
author | Sowjanya Komatineni <skomatineni@nvidia.com> | 2019-04-04 20:14:12 -0400 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2019-04-08 03:13:06 -0400 |
commit | fa28fd3421373794e98eb3e511969fea5a8b2fc3 (patch) | |
tree | 0de45445102e0d2de55117b41540f39462e0df1a /drivers/spi | |
parent | 9d199231b000414e420a35912760f2d67e9c56d7 (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.c | 53 |
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 | ||
166 | struct tegra_spi_soc_data { | ||
167 | bool has_intr_mask_reg; | ||
168 | }; | ||
169 | |||
164 | struct tegra_spi_data { | 170 | struct 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 | ||
216 | static int tegra_spi_runtime_suspend(struct device *dev); | 223 | static 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 | ||
1153 | static struct tegra_spi_soc_data tegra114_spi_soc_data = { | ||
1154 | .has_intr_mask_reg = false, | ||
1155 | }; | ||
1156 | |||
1157 | static struct tegra_spi_soc_data tegra124_spi_soc_data = { | ||
1158 | .has_intr_mask_reg = false, | ||
1159 | }; | ||
1160 | |||
1161 | static struct tegra_spi_soc_data tegra210_spi_soc_data = { | ||
1162 | .has_intr_mask_reg = true, | ||
1163 | }; | ||
1164 | |||
1138 | static const struct of_device_id tegra_spi_of_match[] = { | 1165 | static 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 | }; |
1142 | MODULE_DEVICE_TABLE(of, tegra_spi_of_match); | 1178 | MODULE_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)) { |