aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVinod Koul <vinod.koul@intel.com>2016-05-17 00:45:27 -0400
committerVinod Koul <vinod.koul@intel.com>2016-05-17 00:45:27 -0400
commit0f5c85f48a3d5cb4f551a7d68592085e75591df3 (patch)
tree522667aa670e1e0f97e7d8173d9b39933a23346c
parent53b84bad9e49e28faff74c51b137d036944291f4 (diff)
parent86e486a098b6251e3931ca04b7078aa037bfe5ad (diff)
Merge branch 'topic/tegra' into for-linus
-rw-r--r--Documentation/devicetree/bindings/dma/nvidia,tegra210-adma.txt55
-rw-r--r--MAINTAINERS5
-rw-r--r--drivers/dma/Kconfig14
-rw-r--r--drivers/dma/Makefile1
-rw-r--r--drivers/dma/tegra20-apb-dma.c16
-rw-r--r--drivers/dma/tegra210-adma.c840
6 files changed, 927 insertions, 4 deletions
diff --git a/Documentation/devicetree/bindings/dma/nvidia,tegra210-adma.txt b/Documentation/devicetree/bindings/dma/nvidia,tegra210-adma.txt
new file mode 100644
index 000000000000..1e1dc8f972e4
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/nvidia,tegra210-adma.txt
@@ -0,0 +1,55 @@
1* NVIDIA Tegra Audio DMA (ADMA) controller
2
3The Tegra Audio DMA controller that is used for transferring data
4between system memory and the Audio Processing Engine (APE).
5
6Required properties:
7- compatible: Must be "nvidia,tegra210-adma".
8- reg: Should contain DMA registers location and length. This should be
9 a single entry that includes all of the per-channel registers in one
10 contiguous bank.
11- interrupt-parent: Phandle to the interrupt parent controller.
12- interrupts: Should contain all of the per-channel DMA interrupts in
13 ascending order with respect to the DMA channel index.
14- clocks: Must contain one entry for the ADMA module clock
15 (TEGRA210_CLK_D_AUDIO).
16- clock-names: Must contain the name "d_audio" for the corresponding
17 'clocks' entry.
18- #dma-cells : Must be 1. The first cell denotes the receive/transmit
19 request number and should be between 1 and the maximum number of
20 requests supported. This value corresponds to the RX/TX_REQUEST_SELECT
21 fields in the ADMA_CHn_CTRL register.
22
23
24Example:
25
26adma: dma@702e2000 {
27 compatible = "nvidia,tegra210-adma";
28 reg = <0x0 0x702e2000 0x0 0x2000>;
29 interrupt-parent = <&tegra_agic>;
30 interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>,
31 <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>,
32 <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>,
33 <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>,
34 <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>,
35 <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>,
36 <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>,
37 <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>,
38 <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
39 <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>,
40 <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>,
41 <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>,
42 <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>,
43 <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>,
44 <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>,
45 <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>,
46 <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
47 <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
48 <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
49 <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>,
50 <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>,
51 <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
52 clocks = <&tegra_car TEGRA210_CLK_D_AUDIO>;
53 clock-names = "d_audio";
54 #dma-cells = <1>;
55};
diff --git a/MAINTAINERS b/MAINTAINERS
index 03e00c7c88eb..c34052e9a942 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10921,10 +10921,11 @@ M: Prashant Gaikwad <pgaikwad@nvidia.com>
10921S: Supported 10921S: Supported
10922F: drivers/clk/tegra/ 10922F: drivers/clk/tegra/
10923 10923
10924TEGRA DMA DRIVER 10924TEGRA DMA DRIVERS
10925M: Laxman Dewangan <ldewangan@nvidia.com> 10925M: Laxman Dewangan <ldewangan@nvidia.com>
10926M: Jon Hunter <jonathanh@nvidia.com>
10926S: Supported 10927S: Supported
10927F: drivers/dma/tegra20-apb-dma.c 10928F: drivers/dma/tegra*
10928 10929
10929TEGRA I2C DRIVER 10930TEGRA I2C DRIVER
10930M: Laxman Dewangan <ldewangan@nvidia.com> 10931M: Laxman Dewangan <ldewangan@nvidia.com>
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 67b37ce94143..8d0e5ebe1dac 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -467,6 +467,20 @@ config TEGRA20_APB_DMA
467 This DMA controller transfers data from memory to peripheral fifo 467 This DMA controller transfers data from memory to peripheral fifo
468 or vice versa. It does not support memory to memory data transfer. 468 or vice versa. It does not support memory to memory data transfer.
469 469
470config TEGRA210_ADMA
471 bool "NVIDIA Tegra210 ADMA support"
472 depends on ARCH_TEGRA_210_SOC
473 select DMA_ENGINE
474 select DMA_VIRTUAL_CHANNELS
475 select PM_CLK
476 help
477 Support for the NVIDIA Tegra210 ADMA controller driver. The
478 DMA controller has multiple DMA channels and is used to service
479 various audio clients in the Tegra210 audio processing engine
480 (APE). This DMA controller transfers data from memory to
481 peripheral and vice versa. It does not support memory to
482 memory data transfer.
483
470config TIMB_DMA 484config TIMB_DMA
471 tristate "Timberdale FPGA DMA support" 485 tristate "Timberdale FPGA DMA support"
472 depends on MFD_TIMBERDALE 486 depends on MFD_TIMBERDALE
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index 6084127c1486..614f28b0b739 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -59,6 +59,7 @@ obj-$(CONFIG_STM32_DMA) += stm32-dma.o
59obj-$(CONFIG_S3C24XX_DMAC) += s3c24xx-dma.o 59obj-$(CONFIG_S3C24XX_DMAC) += s3c24xx-dma.o
60obj-$(CONFIG_TXX9_DMAC) += txx9dmac.o 60obj-$(CONFIG_TXX9_DMAC) += txx9dmac.o
61obj-$(CONFIG_TEGRA20_APB_DMA) += tegra20-apb-dma.o 61obj-$(CONFIG_TEGRA20_APB_DMA) += tegra20-apb-dma.o
62obj-$(CONFIG_TEGRA210_ADMA) += tegra210-adma.o
62obj-$(CONFIG_TIMB_DMA) += timb_dma.o 63obj-$(CONFIG_TIMB_DMA) += timb_dma.o
63obj-$(CONFIG_TI_CPPI41) += cppi41.o 64obj-$(CONFIG_TI_CPPI41) += cppi41.o
64obj-$(CONFIG_TI_DMA_CROSSBAR) += ti-dma-crossbar.o 65obj-$(CONFIG_TI_DMA_CROSSBAR) += ti-dma-crossbar.o
diff --git a/drivers/dma/tegra20-apb-dma.c b/drivers/dma/tegra20-apb-dma.c
index 3871f29e523d..01e316f73559 100644
--- a/drivers/dma/tegra20-apb-dma.c
+++ b/drivers/dma/tegra20-apb-dma.c
@@ -54,6 +54,7 @@
54#define TEGRA_APBDMA_CSR_ONCE BIT(27) 54#define TEGRA_APBDMA_CSR_ONCE BIT(27)
55#define TEGRA_APBDMA_CSR_FLOW BIT(21) 55#define TEGRA_APBDMA_CSR_FLOW BIT(21)
56#define TEGRA_APBDMA_CSR_REQ_SEL_SHIFT 16 56#define TEGRA_APBDMA_CSR_REQ_SEL_SHIFT 16
57#define TEGRA_APBDMA_CSR_REQ_SEL_MASK 0x1F
57#define TEGRA_APBDMA_CSR_WCOUNT_MASK 0xFFFC 58#define TEGRA_APBDMA_CSR_WCOUNT_MASK 0xFFFC
58 59
59/* STATUS register */ 60/* STATUS register */
@@ -114,6 +115,8 @@
114/* Channel base address offset from APBDMA base address */ 115/* Channel base address offset from APBDMA base address */
115#define TEGRA_APBDMA_CHANNEL_BASE_ADD_OFFSET 0x1000 116#define TEGRA_APBDMA_CHANNEL_BASE_ADD_OFFSET 0x1000
116 117
118#define TEGRA_APBDMA_SLAVE_ID_INVALID (TEGRA_APBDMA_CSR_REQ_SEL_MASK + 1)
119
117struct tegra_dma; 120struct tegra_dma;
118 121
119/* 122/*
@@ -353,8 +356,11 @@ static int tegra_dma_slave_config(struct dma_chan *dc,
353 } 356 }
354 357
355 memcpy(&tdc->dma_sconfig, sconfig, sizeof(*sconfig)); 358 memcpy(&tdc->dma_sconfig, sconfig, sizeof(*sconfig));
356 if (!tdc->slave_id) 359 if (tdc->slave_id == TEGRA_APBDMA_SLAVE_ID_INVALID) {
360 if (sconfig->slave_id > TEGRA_APBDMA_CSR_REQ_SEL_MASK)
361 return -EINVAL;
357 tdc->slave_id = sconfig->slave_id; 362 tdc->slave_id = sconfig->slave_id;
363 }
358 tdc->config_init = true; 364 tdc->config_init = true;
359 return 0; 365 return 0;
360} 366}
@@ -1236,7 +1242,7 @@ static void tegra_dma_free_chan_resources(struct dma_chan *dc)
1236 } 1242 }
1237 pm_runtime_put(tdma->dev); 1243 pm_runtime_put(tdma->dev);
1238 1244
1239 tdc->slave_id = 0; 1245 tdc->slave_id = TEGRA_APBDMA_SLAVE_ID_INVALID;
1240} 1246}
1241 1247
1242static struct dma_chan *tegra_dma_of_xlate(struct of_phandle_args *dma_spec, 1248static struct dma_chan *tegra_dma_of_xlate(struct of_phandle_args *dma_spec,
@@ -1246,6 +1252,11 @@ static struct dma_chan *tegra_dma_of_xlate(struct of_phandle_args *dma_spec,
1246 struct dma_chan *chan; 1252 struct dma_chan *chan;
1247 struct tegra_dma_channel *tdc; 1253 struct tegra_dma_channel *tdc;
1248 1254
1255 if (dma_spec->args[0] > TEGRA_APBDMA_CSR_REQ_SEL_MASK) {
1256 dev_err(tdma->dev, "Invalid slave id: %d\n", dma_spec->args[0]);
1257 return NULL;
1258 }
1259
1249 chan = dma_get_any_slave_channel(&tdma->dma_dev); 1260 chan = dma_get_any_slave_channel(&tdma->dma_dev);
1250 if (!chan) 1261 if (!chan)
1251 return NULL; 1262 return NULL;
@@ -1389,6 +1400,7 @@ static int tegra_dma_probe(struct platform_device *pdev)
1389 &tdma->dma_dev.channels); 1400 &tdma->dma_dev.channels);
1390 tdc->tdma = tdma; 1401 tdc->tdma = tdma;
1391 tdc->id = i; 1402 tdc->id = i;
1403 tdc->slave_id = TEGRA_APBDMA_SLAVE_ID_INVALID;
1392 1404
1393 tasklet_init(&tdc->tasklet, tegra_dma_tasklet, 1405 tasklet_init(&tdc->tasklet, tegra_dma_tasklet,
1394 (unsigned long)tdc); 1406 (unsigned long)tdc);
diff --git a/drivers/dma/tegra210-adma.c b/drivers/dma/tegra210-adma.c
new file mode 100644
index 000000000000..c4b121c4559d
--- /dev/null
+++ b/drivers/dma/tegra210-adma.c
@@ -0,0 +1,840 @@
1/*
2 * ADMA driver for Nvidia's Tegra210 ADMA controller.
3 *
4 * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <linux/clk.h>
20#include <linux/iopoll.h>
21#include <linux/module.h>
22#include <linux/of_device.h>
23#include <linux/of_dma.h>
24#include <linux/of_irq.h>
25#include <linux/pm_clock.h>
26#include <linux/pm_runtime.h>
27#include <linux/slab.h>
28
29#include "virt-dma.h"
30
31#define ADMA_CH_CMD 0x00
32#define ADMA_CH_STATUS 0x0c
33#define ADMA_CH_STATUS_XFER_EN BIT(0)
34
35#define ADMA_CH_INT_STATUS 0x10
36#define ADMA_CH_INT_STATUS_XFER_DONE BIT(0)
37
38#define ADMA_CH_INT_CLEAR 0x1c
39#define ADMA_CH_CTRL 0x24
40#define ADMA_CH_CTRL_TX_REQ(val) (((val) & 0xf) << 28)
41#define ADMA_CH_CTRL_TX_REQ_MAX 10
42#define ADMA_CH_CTRL_RX_REQ(val) (((val) & 0xf) << 24)
43#define ADMA_CH_CTRL_RX_REQ_MAX 10
44#define ADMA_CH_CTRL_DIR(val) (((val) & 0xf) << 12)
45#define ADMA_CH_CTRL_DIR_AHUB2MEM 2
46#define ADMA_CH_CTRL_DIR_MEM2AHUB 4
47#define ADMA_CH_CTRL_MODE_CONTINUOUS (2 << 8)
48#define ADMA_CH_CTRL_FLOWCTRL_EN BIT(1)
49
50#define ADMA_CH_CONFIG 0x28
51#define ADMA_CH_CONFIG_SRC_BUF(val) (((val) & 0x7) << 28)
52#define ADMA_CH_CONFIG_TRG_BUF(val) (((val) & 0x7) << 24)
53#define ADMA_CH_CONFIG_BURST_SIZE(val) (((val) & 0x7) << 20)
54#define ADMA_CH_CONFIG_BURST_16 5
55#define ADMA_CH_CONFIG_WEIGHT_FOR_WRR(val) ((val) & 0xf)
56#define ADMA_CH_CONFIG_MAX_BUFS 8
57
58#define ADMA_CH_FIFO_CTRL 0x2c
59#define ADMA_CH_FIFO_CTRL_OVRFW_THRES(val) (((val) & 0xf) << 24)
60#define ADMA_CH_FIFO_CTRL_STARV_THRES(val) (((val) & 0xf) << 16)
61#define ADMA_CH_FIFO_CTRL_TX_SIZE(val) (((val) & 0xf) << 8)
62#define ADMA_CH_FIFO_CTRL_RX_SIZE(val) ((val) & 0xf)
63
64#define ADMA_CH_LOWER_SRC_ADDR 0x34
65#define ADMA_CH_LOWER_TRG_ADDR 0x3c
66#define ADMA_CH_TC 0x44
67#define ADMA_CH_TC_COUNT_MASK 0x3ffffffc
68
69#define ADMA_CH_XFER_STATUS 0x54
70#define ADMA_CH_XFER_STATUS_COUNT_MASK 0xffff
71
72#define ADMA_GLOBAL_CMD 0xc00
73#define ADMA_GLOBAL_SOFT_RESET 0xc04
74#define ADMA_GLOBAL_INT_CLEAR 0xc20
75#define ADMA_GLOBAL_CTRL 0xc24
76
77#define ADMA_CH_REG_OFFSET(a) (a * 0x80)
78
79#define ADMA_CH_FIFO_CTRL_DEFAULT (ADMA_CH_FIFO_CTRL_OVRFW_THRES(1) | \
80 ADMA_CH_FIFO_CTRL_STARV_THRES(1) | \
81 ADMA_CH_FIFO_CTRL_TX_SIZE(3) | \
82 ADMA_CH_FIFO_CTRL_RX_SIZE(3))
83struct tegra_adma;
84
85/*
86 * struct tegra_adma_chip_data - Tegra chip specific data
87 * @nr_channels: Number of DMA channels available.
88 */
89struct tegra_adma_chip_data {
90 int nr_channels;
91};
92
93/*
94 * struct tegra_adma_chan_regs - Tegra ADMA channel registers
95 */
96struct tegra_adma_chan_regs {
97 unsigned int ctrl;
98 unsigned int config;
99 unsigned int src_addr;
100 unsigned int trg_addr;
101 unsigned int fifo_ctrl;
102 unsigned int tc;
103};
104
105/*
106 * struct tegra_adma_desc - Tegra ADMA descriptor to manage transfer requests.
107 */
108struct tegra_adma_desc {
109 struct virt_dma_desc vd;
110 struct tegra_adma_chan_regs ch_regs;
111 size_t buf_len;
112 size_t period_len;
113 size_t num_periods;
114};
115
116/*
117 * struct tegra_adma_chan - Tegra ADMA channel information
118 */
119struct tegra_adma_chan {
120 struct virt_dma_chan vc;
121 struct tegra_adma_desc *desc;
122 struct tegra_adma *tdma;
123 int irq;
124 void __iomem *chan_addr;
125
126 /* Slave channel configuration info */
127 struct dma_slave_config sconfig;
128 enum dma_transfer_direction sreq_dir;
129 unsigned int sreq_index;
130 bool sreq_reserved;
131
132 /* Transfer count and position info */
133 unsigned int tx_buf_count;
134 unsigned int tx_buf_pos;
135};
136
137/*
138 * struct tegra_adma - Tegra ADMA controller information
139 */
140struct tegra_adma {
141 struct dma_device dma_dev;
142 struct device *dev;
143 void __iomem *base_addr;
144 unsigned int nr_channels;
145 unsigned long rx_requests_reserved;
146 unsigned long tx_requests_reserved;
147
148 /* Used to store global command register state when suspending */
149 unsigned int global_cmd;
150
151 /* Last member of the structure */
152 struct tegra_adma_chan channels[0];
153};
154
155static inline void tdma_write(struct tegra_adma *tdma, u32 reg, u32 val)
156{
157 writel(val, tdma->base_addr + reg);
158}
159
160static inline u32 tdma_read(struct tegra_adma *tdma, u32 reg)
161{
162 return readl(tdma->base_addr + reg);
163}
164
165static inline void tdma_ch_write(struct tegra_adma_chan *tdc, u32 reg, u32 val)
166{
167 writel(val, tdc->chan_addr + reg);
168}
169
170static inline u32 tdma_ch_read(struct tegra_adma_chan *tdc, u32 reg)
171{
172 return readl(tdc->chan_addr + reg);
173}
174
175static inline struct tegra_adma_chan *to_tegra_adma_chan(struct dma_chan *dc)
176{
177 return container_of(dc, struct tegra_adma_chan, vc.chan);
178}
179
180static inline struct tegra_adma_desc *to_tegra_adma_desc(
181 struct dma_async_tx_descriptor *td)
182{
183 return container_of(td, struct tegra_adma_desc, vd.tx);
184}
185
186static inline struct device *tdc2dev(struct tegra_adma_chan *tdc)
187{
188 return tdc->tdma->dev;
189}
190
191static void tegra_adma_desc_free(struct virt_dma_desc *vd)
192{
193 kfree(container_of(vd, struct tegra_adma_desc, vd));
194}
195
196static int tegra_adma_slave_config(struct dma_chan *dc,
197 struct dma_slave_config *sconfig)
198{
199 struct tegra_adma_chan *tdc = to_tegra_adma_chan(dc);
200
201 memcpy(&tdc->sconfig, sconfig, sizeof(*sconfig));
202
203 return 0;
204}
205
206static int tegra_adma_init(struct tegra_adma *tdma)
207{
208 u32 status;
209 int ret;
210
211 /* Clear any interrupts */
212 tdma_write(tdma, ADMA_GLOBAL_INT_CLEAR, 0x1);
213
214 /* Assert soft reset */
215 tdma_write(tdma, ADMA_GLOBAL_SOFT_RESET, 0x1);
216
217 /* Wait for reset to clear */
218 ret = readx_poll_timeout(readl,
219 tdma->base_addr + ADMA_GLOBAL_SOFT_RESET,
220 status, status == 0, 20, 10000);
221 if (ret)
222 return ret;
223
224 /* Enable global ADMA registers */
225 tdma_write(tdma, ADMA_GLOBAL_CMD, 1);
226
227 return 0;
228}
229
230static int tegra_adma_request_alloc(struct tegra_adma_chan *tdc,
231 enum dma_transfer_direction direction)
232{
233 struct tegra_adma *tdma = tdc->tdma;
234 unsigned int sreq_index = tdc->sreq_index;
235
236 if (tdc->sreq_reserved)
237 return tdc->sreq_dir == direction ? 0 : -EINVAL;
238
239 switch (direction) {
240 case DMA_MEM_TO_DEV:
241 if (sreq_index > ADMA_CH_CTRL_TX_REQ_MAX) {
242 dev_err(tdma->dev, "invalid DMA request\n");
243 return -EINVAL;
244 }
245
246 if (test_and_set_bit(sreq_index, &tdma->tx_requests_reserved)) {
247 dev_err(tdma->dev, "DMA request reserved\n");
248 return -EINVAL;
249 }
250 break;
251
252 case DMA_DEV_TO_MEM:
253 if (sreq_index > ADMA_CH_CTRL_RX_REQ_MAX) {
254 dev_err(tdma->dev, "invalid DMA request\n");
255 return -EINVAL;
256 }
257
258 if (test_and_set_bit(sreq_index, &tdma->rx_requests_reserved)) {
259 dev_err(tdma->dev, "DMA request reserved\n");
260 return -EINVAL;
261 }
262 break;
263
264 default:
265 dev_WARN(tdma->dev, "channel %s has invalid transfer type\n",
266 dma_chan_name(&tdc->vc.chan));
267 return -EINVAL;
268 }
269
270 tdc->sreq_dir = direction;
271 tdc->sreq_reserved = true;
272
273 return 0;
274}
275
276static void tegra_adma_request_free(struct tegra_adma_chan *tdc)
277{
278 struct tegra_adma *tdma = tdc->tdma;
279
280 if (!tdc->sreq_reserved)
281 return;
282
283 switch (tdc->sreq_dir) {
284 case DMA_MEM_TO_DEV:
285 clear_bit(tdc->sreq_index, &tdma->tx_requests_reserved);
286 break;
287
288 case DMA_DEV_TO_MEM:
289 clear_bit(tdc->sreq_index, &tdma->rx_requests_reserved);
290 break;
291
292 default:
293 dev_WARN(tdma->dev, "channel %s has invalid transfer type\n",
294 dma_chan_name(&tdc->vc.chan));
295 return;
296 }
297
298 tdc->sreq_reserved = false;
299}
300
301static u32 tegra_adma_irq_status(struct tegra_adma_chan *tdc)
302{
303 u32 status = tdma_ch_read(tdc, ADMA_CH_INT_STATUS);
304
305 return status & ADMA_CH_INT_STATUS_XFER_DONE;
306}
307
308static u32 tegra_adma_irq_clear(struct tegra_adma_chan *tdc)
309{
310 u32 status = tegra_adma_irq_status(tdc);
311
312 if (status)
313 tdma_ch_write(tdc, ADMA_CH_INT_CLEAR, status);
314
315 return status;
316}
317
318static void tegra_adma_stop(struct tegra_adma_chan *tdc)
319{
320 unsigned int status;
321
322 /* Disable ADMA */
323 tdma_ch_write(tdc, ADMA_CH_CMD, 0);
324
325 /* Clear interrupt status */
326 tegra_adma_irq_clear(tdc);
327
328 if (readx_poll_timeout_atomic(readl, tdc->chan_addr + ADMA_CH_STATUS,
329 status, !(status & ADMA_CH_STATUS_XFER_EN),
330 20, 10000)) {
331 dev_err(tdc2dev(tdc), "unable to stop DMA channel\n");
332 return;
333 }
334
335 kfree(tdc->desc);
336 tdc->desc = NULL;
337}
338
339static void tegra_adma_start(struct tegra_adma_chan *tdc)
340{
341 struct virt_dma_desc *vd = vchan_next_desc(&tdc->vc);
342 struct tegra_adma_chan_regs *ch_regs;
343 struct tegra_adma_desc *desc;
344
345 if (!vd)
346 return;
347
348 list_del(&vd->node);
349
350 desc = to_tegra_adma_desc(&vd->tx);
351
352 if (!desc) {
353 dev_warn(tdc2dev(tdc), "unable to start DMA, no descriptor\n");
354 return;
355 }
356
357 ch_regs = &desc->ch_regs;
358
359 tdc->tx_buf_pos = 0;
360 tdc->tx_buf_count = 0;
361 tdma_ch_write(tdc, ADMA_CH_TC, ch_regs->tc);
362 tdma_ch_write(tdc, ADMA_CH_CTRL, ch_regs->ctrl);
363 tdma_ch_write(tdc, ADMA_CH_LOWER_SRC_ADDR, ch_regs->src_addr);
364 tdma_ch_write(tdc, ADMA_CH_LOWER_TRG_ADDR, ch_regs->trg_addr);
365 tdma_ch_write(tdc, ADMA_CH_FIFO_CTRL, ch_regs->fifo_ctrl);
366 tdma_ch_write(tdc, ADMA_CH_CONFIG, ch_regs->config);
367
368 /* Start ADMA */
369 tdma_ch_write(tdc, ADMA_CH_CMD, 1);
370
371 tdc->desc = desc;
372}
373
374static unsigned int tegra_adma_get_residue(struct tegra_adma_chan *tdc)
375{
376 struct tegra_adma_desc *desc = tdc->desc;
377 unsigned int max = ADMA_CH_XFER_STATUS_COUNT_MASK + 1;
378 unsigned int pos = tdma_ch_read(tdc, ADMA_CH_XFER_STATUS);
379 unsigned int periods_remaining;
380
381 /*
382 * Handle wrap around of buffer count register
383 */
384 if (pos < tdc->tx_buf_pos)
385 tdc->tx_buf_count += pos + (max - tdc->tx_buf_pos);
386 else
387 tdc->tx_buf_count += pos - tdc->tx_buf_pos;
388
389 periods_remaining = tdc->tx_buf_count % desc->num_periods;
390 tdc->tx_buf_pos = pos;
391
392 return desc->buf_len - (periods_remaining * desc->period_len);
393}
394
395static irqreturn_t tegra_adma_isr(int irq, void *dev_id)
396{
397 struct tegra_adma_chan *tdc = dev_id;
398 unsigned long status;
399 unsigned long flags;
400
401 spin_lock_irqsave(&tdc->vc.lock, flags);
402
403 status = tegra_adma_irq_clear(tdc);
404 if (status == 0 || !tdc->desc) {
405 spin_unlock_irqrestore(&tdc->vc.lock, flags);
406 return IRQ_NONE;
407 }
408
409 vchan_cyclic_callback(&tdc->desc->vd);
410
411 spin_unlock_irqrestore(&tdc->vc.lock, flags);
412
413 return IRQ_HANDLED;
414}
415
416static void tegra_adma_issue_pending(struct dma_chan *dc)
417{
418 struct tegra_adma_chan *tdc = to_tegra_adma_chan(dc);
419 unsigned long flags;
420
421 spin_lock_irqsave(&tdc->vc.lock, flags);
422
423 if (vchan_issue_pending(&tdc->vc)) {
424 if (!tdc->desc)
425 tegra_adma_start(tdc);
426 }
427
428 spin_unlock_irqrestore(&tdc->vc.lock, flags);
429}
430
431static int tegra_adma_terminate_all(struct dma_chan *dc)
432{
433 struct tegra_adma_chan *tdc = to_tegra_adma_chan(dc);
434 unsigned long flags;
435 LIST_HEAD(head);
436
437 spin_lock_irqsave(&tdc->vc.lock, flags);
438
439 if (tdc->desc)
440 tegra_adma_stop(tdc);
441
442 tegra_adma_request_free(tdc);
443 vchan_get_all_descriptors(&tdc->vc, &head);
444 spin_unlock_irqrestore(&tdc->vc.lock, flags);
445 vchan_dma_desc_free_list(&tdc->vc, &head);
446
447 return 0;
448}
449
450static enum dma_status tegra_adma_tx_status(struct dma_chan *dc,
451 dma_cookie_t cookie,
452 struct dma_tx_state *txstate)
453{
454 struct tegra_adma_chan *tdc = to_tegra_adma_chan(dc);
455 struct tegra_adma_desc *desc;
456 struct virt_dma_desc *vd;
457 enum dma_status ret;
458 unsigned long flags;
459 unsigned int residual;
460
461 ret = dma_cookie_status(dc, cookie, txstate);
462 if (ret == DMA_COMPLETE || !txstate)
463 return ret;
464
465 spin_lock_irqsave(&tdc->vc.lock, flags);
466
467 vd = vchan_find_desc(&tdc->vc, cookie);
468 if (vd) {
469 desc = to_tegra_adma_desc(&vd->tx);
470 residual = desc->ch_regs.tc;
471 } else if (tdc->desc && tdc->desc->vd.tx.cookie == cookie) {
472 residual = tegra_adma_get_residue(tdc);
473 } else {
474 residual = 0;
475 }
476
477 spin_unlock_irqrestore(&tdc->vc.lock, flags);
478
479 dma_set_residue(txstate, residual);
480
481 return ret;
482}
483
484static int tegra_adma_set_xfer_params(struct tegra_adma_chan *tdc,
485 struct tegra_adma_desc *desc,
486 dma_addr_t buf_addr,
487 enum dma_transfer_direction direction)
488{
489 struct tegra_adma_chan_regs *ch_regs = &desc->ch_regs;
490 unsigned int burst_size, adma_dir;
491
492 if (desc->num_periods > ADMA_CH_CONFIG_MAX_BUFS)
493 return -EINVAL;
494
495 switch (direction) {
496 case DMA_MEM_TO_DEV:
497 adma_dir = ADMA_CH_CTRL_DIR_MEM2AHUB;
498 burst_size = fls(tdc->sconfig.dst_maxburst);
499 ch_regs->config = ADMA_CH_CONFIG_SRC_BUF(desc->num_periods - 1);
500 ch_regs->ctrl = ADMA_CH_CTRL_TX_REQ(tdc->sreq_index);
501 ch_regs->src_addr = buf_addr;
502 break;
503
504 case DMA_DEV_TO_MEM:
505 adma_dir = ADMA_CH_CTRL_DIR_AHUB2MEM;
506 burst_size = fls(tdc->sconfig.src_maxburst);
507 ch_regs->config = ADMA_CH_CONFIG_TRG_BUF(desc->num_periods - 1);
508 ch_regs->ctrl = ADMA_CH_CTRL_RX_REQ(tdc->sreq_index);
509 ch_regs->trg_addr = buf_addr;
510 break;
511
512 default:
513 dev_err(tdc2dev(tdc), "DMA direction is not supported\n");
514 return -EINVAL;
515 }
516
517 if (!burst_size || burst_size > ADMA_CH_CONFIG_BURST_16)
518 burst_size = ADMA_CH_CONFIG_BURST_16;
519
520 ch_regs->ctrl |= ADMA_CH_CTRL_DIR(adma_dir) |
521 ADMA_CH_CTRL_MODE_CONTINUOUS |
522 ADMA_CH_CTRL_FLOWCTRL_EN;
523 ch_regs->config |= ADMA_CH_CONFIG_BURST_SIZE(burst_size);
524 ch_regs->config |= ADMA_CH_CONFIG_WEIGHT_FOR_WRR(1);
525 ch_regs->fifo_ctrl = ADMA_CH_FIFO_CTRL_DEFAULT;
526 ch_regs->tc = desc->period_len & ADMA_CH_TC_COUNT_MASK;
527
528 return tegra_adma_request_alloc(tdc, direction);
529}
530
531static struct dma_async_tx_descriptor *tegra_adma_prep_dma_cyclic(
532 struct dma_chan *dc, dma_addr_t buf_addr, size_t buf_len,
533 size_t period_len, enum dma_transfer_direction direction,
534 unsigned long flags)
535{
536 struct tegra_adma_chan *tdc = to_tegra_adma_chan(dc);
537 struct tegra_adma_desc *desc = NULL;
538
539 if (!buf_len || !period_len || period_len > ADMA_CH_TC_COUNT_MASK) {
540 dev_err(tdc2dev(tdc), "invalid buffer/period len\n");
541 return NULL;
542 }
543
544 if (buf_len % period_len) {
545 dev_err(tdc2dev(tdc), "buf_len not a multiple of period_len\n");
546 return NULL;
547 }
548
549 if (!IS_ALIGNED(buf_addr, 4)) {
550 dev_err(tdc2dev(tdc), "invalid buffer alignment\n");
551 return NULL;
552 }
553
554 desc = kzalloc(sizeof(*desc), GFP_NOWAIT);
555 if (!desc)
556 return NULL;
557
558 desc->buf_len = buf_len;
559 desc->period_len = period_len;
560 desc->num_periods = buf_len / period_len;
561
562 if (tegra_adma_set_xfer_params(tdc, desc, buf_addr, direction)) {
563 kfree(desc);
564 return NULL;
565 }
566
567 return vchan_tx_prep(&tdc->vc, &desc->vd, flags);
568}
569
570static int tegra_adma_alloc_chan_resources(struct dma_chan *dc)
571{
572 struct tegra_adma_chan *tdc = to_tegra_adma_chan(dc);
573 int ret;
574
575 ret = request_irq(tdc->irq, tegra_adma_isr, 0, dma_chan_name(dc), tdc);
576 if (ret) {
577 dev_err(tdc2dev(tdc), "failed to get interrupt for %s\n",
578 dma_chan_name(dc));
579 return ret;
580 }
581
582 ret = pm_runtime_get_sync(tdc2dev(tdc));
583 if (ret < 0) {
584 free_irq(tdc->irq, tdc);
585 return ret;
586 }
587
588 dma_cookie_init(&tdc->vc.chan);
589
590 return 0;
591}
592
593static void tegra_adma_free_chan_resources(struct dma_chan *dc)
594{
595 struct tegra_adma_chan *tdc = to_tegra_adma_chan(dc);
596
597 tegra_adma_terminate_all(dc);
598 vchan_free_chan_resources(&tdc->vc);
599 tasklet_kill(&tdc->vc.task);
600 free_irq(tdc->irq, tdc);
601 pm_runtime_put(tdc2dev(tdc));
602
603 tdc->sreq_index = 0;
604 tdc->sreq_dir = DMA_TRANS_NONE;
605}
606
607static struct dma_chan *tegra_dma_of_xlate(struct of_phandle_args *dma_spec,
608 struct of_dma *ofdma)
609{
610 struct tegra_adma *tdma = ofdma->of_dma_data;
611 struct tegra_adma_chan *tdc;
612 struct dma_chan *chan;
613 unsigned int sreq_index;
614
615 if (dma_spec->args_count != 1)
616 return NULL;
617
618 sreq_index = dma_spec->args[0];
619
620 if (sreq_index == 0) {
621 dev_err(tdma->dev, "DMA request must not be 0\n");
622 return NULL;
623 }
624
625 chan = dma_get_any_slave_channel(&tdma->dma_dev);
626 if (!chan)
627 return NULL;
628
629 tdc = to_tegra_adma_chan(chan);
630 tdc->sreq_index = sreq_index;
631
632 return chan;
633}
634
635static int tegra_adma_runtime_suspend(struct device *dev)
636{
637 struct tegra_adma *tdma = dev_get_drvdata(dev);
638
639 tdma->global_cmd = tdma_read(tdma, ADMA_GLOBAL_CMD);
640
641 return pm_clk_suspend(dev);
642}
643
644static int tegra_adma_runtime_resume(struct device *dev)
645{
646 struct tegra_adma *tdma = dev_get_drvdata(dev);
647 int ret;
648
649 ret = pm_clk_resume(dev);
650 if (ret)
651 return ret;
652
653 tdma_write(tdma, ADMA_GLOBAL_CMD, tdma->global_cmd);
654
655 return 0;
656}
657
658static const struct tegra_adma_chip_data tegra210_chip_data = {
659 .nr_channels = 22,
660};
661
662static const struct of_device_id tegra_adma_of_match[] = {
663 { .compatible = "nvidia,tegra210-adma", .data = &tegra210_chip_data },
664 { },
665};
666MODULE_DEVICE_TABLE(of, tegra_adma_of_match);
667
668static int tegra_adma_probe(struct platform_device *pdev)
669{
670 const struct tegra_adma_chip_data *cdata;
671 struct tegra_adma *tdma;
672 struct resource *res;
673 struct clk *clk;
674 int ret, i;
675
676 cdata = of_device_get_match_data(&pdev->dev);
677 if (!cdata) {
678 dev_err(&pdev->dev, "device match data not found\n");
679 return -ENODEV;
680 }
681
682 tdma = devm_kzalloc(&pdev->dev, sizeof(*tdma) + cdata->nr_channels *
683 sizeof(struct tegra_adma_chan), GFP_KERNEL);
684 if (!tdma)
685 return -ENOMEM;
686
687 tdma->dev = &pdev->dev;
688 tdma->nr_channels = cdata->nr_channels;
689 platform_set_drvdata(pdev, tdma);
690
691 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
692 tdma->base_addr = devm_ioremap_resource(&pdev->dev, res);
693 if (IS_ERR(tdma->base_addr))
694 return PTR_ERR(tdma->base_addr);
695
696 ret = pm_clk_create(&pdev->dev);
697 if (ret)
698 return ret;
699
700 clk = clk_get(&pdev->dev, "d_audio");
701 if (IS_ERR(clk)) {
702 dev_err(&pdev->dev, "ADMA clock not found\n");
703 ret = PTR_ERR(clk);
704 goto clk_destroy;
705 }
706
707 ret = pm_clk_add_clk(&pdev->dev, clk);
708 if (ret) {
709 clk_put(clk);
710 goto clk_destroy;
711 }
712
713 pm_runtime_enable(&pdev->dev);
714
715 ret = pm_runtime_get_sync(&pdev->dev);
716 if (ret < 0)
717 goto rpm_disable;
718
719 ret = tegra_adma_init(tdma);
720 if (ret)
721 goto rpm_put;
722
723 INIT_LIST_HEAD(&tdma->dma_dev.channels);
724 for (i = 0; i < tdma->nr_channels; i++) {
725 struct tegra_adma_chan *tdc = &tdma->channels[i];
726
727 tdc->chan_addr = tdma->base_addr + ADMA_CH_REG_OFFSET(i);
728
729 tdc->irq = of_irq_get(pdev->dev.of_node, i);
730 if (tdc->irq < 0) {
731 ret = tdc->irq;
732 goto irq_dispose;
733 }
734
735 vchan_init(&tdc->vc, &tdma->dma_dev);
736 tdc->vc.desc_free = tegra_adma_desc_free;
737 tdc->tdma = tdma;
738 }
739
740 dma_cap_set(DMA_SLAVE, tdma->dma_dev.cap_mask);
741 dma_cap_set(DMA_PRIVATE, tdma->dma_dev.cap_mask);
742 dma_cap_set(DMA_CYCLIC, tdma->dma_dev.cap_mask);
743
744 tdma->dma_dev.dev = &pdev->dev;
745 tdma->dma_dev.device_alloc_chan_resources =
746 tegra_adma_alloc_chan_resources;
747 tdma->dma_dev.device_free_chan_resources =
748 tegra_adma_free_chan_resources;
749 tdma->dma_dev.device_issue_pending = tegra_adma_issue_pending;
750 tdma->dma_dev.device_prep_dma_cyclic = tegra_adma_prep_dma_cyclic;
751 tdma->dma_dev.device_config = tegra_adma_slave_config;
752 tdma->dma_dev.device_tx_status = tegra_adma_tx_status;
753 tdma->dma_dev.device_terminate_all = tegra_adma_terminate_all;
754 tdma->dma_dev.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
755 tdma->dma_dev.dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
756 tdma->dma_dev.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
757 tdma->dma_dev.residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT;
758
759 ret = dma_async_device_register(&tdma->dma_dev);
760 if (ret < 0) {
761 dev_err(&pdev->dev, "ADMA registration failed: %d\n", ret);
762 goto irq_dispose;
763 }
764
765 ret = of_dma_controller_register(pdev->dev.of_node,
766 tegra_dma_of_xlate, tdma);
767 if (ret < 0) {
768 dev_err(&pdev->dev, "ADMA OF registration failed %d\n", ret);
769 goto dma_remove;
770 }
771
772 pm_runtime_put(&pdev->dev);
773
774 dev_info(&pdev->dev, "Tegra210 ADMA driver registered %d channels\n",
775 tdma->nr_channels);
776
777 return 0;
778
779dma_remove:
780 dma_async_device_unregister(&tdma->dma_dev);
781irq_dispose:
782 while (--i >= 0)
783 irq_dispose_mapping(tdma->channels[i].irq);
784rpm_put:
785 pm_runtime_put_sync(&pdev->dev);
786rpm_disable:
787 pm_runtime_disable(&pdev->dev);
788clk_destroy:
789 pm_clk_destroy(&pdev->dev);
790
791 return ret;
792}
793
794static int tegra_adma_remove(struct platform_device *pdev)
795{
796 struct tegra_adma *tdma = platform_get_drvdata(pdev);
797 int i;
798
799 dma_async_device_unregister(&tdma->dma_dev);
800
801 for (i = 0; i < tdma->nr_channels; ++i)
802 irq_dispose_mapping(tdma->channels[i].irq);
803
804 pm_runtime_put_sync(&pdev->dev);
805 pm_runtime_disable(&pdev->dev);
806 pm_clk_destroy(&pdev->dev);
807
808 return 0;
809}
810
811#ifdef CONFIG_PM_SLEEP
812static int tegra_adma_pm_suspend(struct device *dev)
813{
814 return pm_runtime_suspended(dev) == false;
815}
816#endif
817
818static const struct dev_pm_ops tegra_adma_dev_pm_ops = {
819 SET_RUNTIME_PM_OPS(tegra_adma_runtime_suspend,
820 tegra_adma_runtime_resume, NULL)
821 SET_SYSTEM_SLEEP_PM_OPS(tegra_adma_pm_suspend, NULL)
822};
823
824static struct platform_driver tegra_admac_driver = {
825 .driver = {
826 .name = "tegra-adma",
827 .pm = &tegra_adma_dev_pm_ops,
828 .of_match_table = tegra_adma_of_match,
829 },
830 .probe = tegra_adma_probe,
831 .remove = tegra_adma_remove,
832};
833
834module_platform_driver(tegra_admac_driver);
835
836MODULE_ALIAS("platform:tegra210-adma");
837MODULE_DESCRIPTION("NVIDIA Tegra ADMA driver");
838MODULE_AUTHOR("Dara Ramesh <dramesh@nvidia.com>");
839MODULE_AUTHOR("Jon Hunter <jonathanh@nvidia.com>");
840MODULE_LICENSE("GPL v2");