blob: cf462b1abc0bb3eb57083438071e3bf4dfc2e129 [file] [log] [blame]
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301/*
2 * DMA driver for Nvidia's Tegra20 APB DMA controller.
3 *
Stephen Warren996556c2013-11-11 13:09:35 -07004 * Copyright (c) 2012-2013, NVIDIA CORPORATION. All rights reserved.
Laxman Dewanganec8a1582012-06-06 10:55:27 +05305 *
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/bitops.h>
20#include <linux/clk.h>
21#include <linux/delay.h>
22#include <linux/dmaengine.h>
23#include <linux/dma-mapping.h>
Thierry Reding73312052013-01-21 11:09:00 +010024#include <linux/err.h>
Laxman Dewanganec8a1582012-06-06 10:55:27 +053025#include <linux/init.h>
26#include <linux/interrupt.h>
27#include <linux/io.h>
28#include <linux/mm.h>
29#include <linux/module.h>
30#include <linux/of.h>
31#include <linux/of_device.h>
Stephen Warren996556c2013-11-11 13:09:35 -070032#include <linux/of_dma.h>
Laxman Dewanganec8a1582012-06-06 10:55:27 +053033#include <linux/platform_device.h>
Laxman Dewangan3065c192013-04-24 15:24:27 +053034#include <linux/pm.h>
Laxman Dewanganec8a1582012-06-06 10:55:27 +053035#include <linux/pm_runtime.h>
Stephen Warren9aa433d2013-11-06 16:35:34 -070036#include <linux/reset.h>
Laxman Dewanganec8a1582012-06-06 10:55:27 +053037#include <linux/slab.h>
38
Laxman Dewanganec8a1582012-06-06 10:55:27 +053039#include "dmaengine.h"
40
Ben Dooks95f295f2018-11-21 16:13:23 +000041#define CREATE_TRACE_POINTS
42#include <trace/events/tegra_apb_dma.h>
43
Laxman Dewanganec8a1582012-06-06 10:55:27 +053044#define TEGRA_APBDMA_GENERAL 0x0
45#define TEGRA_APBDMA_GENERAL_ENABLE BIT(31)
46
47#define TEGRA_APBDMA_CONTROL 0x010
48#define TEGRA_APBDMA_IRQ_MASK 0x01c
49#define TEGRA_APBDMA_IRQ_MASK_SET 0x020
50
51/* CSR register */
52#define TEGRA_APBDMA_CHAN_CSR 0x00
53#define TEGRA_APBDMA_CSR_ENB BIT(31)
54#define TEGRA_APBDMA_CSR_IE_EOC BIT(30)
55#define TEGRA_APBDMA_CSR_HOLD BIT(29)
56#define TEGRA_APBDMA_CSR_DIR BIT(28)
57#define TEGRA_APBDMA_CSR_ONCE BIT(27)
58#define TEGRA_APBDMA_CSR_FLOW BIT(21)
59#define TEGRA_APBDMA_CSR_REQ_SEL_SHIFT 16
Shardar Shariff Md00ef4492016-04-23 15:06:00 +053060#define TEGRA_APBDMA_CSR_REQ_SEL_MASK 0x1F
Laxman Dewanganec8a1582012-06-06 10:55:27 +053061#define TEGRA_APBDMA_CSR_WCOUNT_MASK 0xFFFC
62
63/* STATUS register */
64#define TEGRA_APBDMA_CHAN_STATUS 0x004
65#define TEGRA_APBDMA_STATUS_BUSY BIT(31)
66#define TEGRA_APBDMA_STATUS_ISE_EOC BIT(30)
67#define TEGRA_APBDMA_STATUS_HALT BIT(29)
68#define TEGRA_APBDMA_STATUS_PING_PONG BIT(28)
69#define TEGRA_APBDMA_STATUS_COUNT_SHIFT 2
70#define TEGRA_APBDMA_STATUS_COUNT_MASK 0xFFFC
71
Laxman Dewangan1b140902013-01-06 21:52:02 +053072#define TEGRA_APBDMA_CHAN_CSRE 0x00C
73#define TEGRA_APBDMA_CHAN_CSRE_PAUSE (1 << 31)
74
Laxman Dewanganec8a1582012-06-06 10:55:27 +053075/* AHB memory address */
76#define TEGRA_APBDMA_CHAN_AHBPTR 0x010
77
78/* AHB sequence register */
79#define TEGRA_APBDMA_CHAN_AHBSEQ 0x14
80#define TEGRA_APBDMA_AHBSEQ_INTR_ENB BIT(31)
81#define TEGRA_APBDMA_AHBSEQ_BUS_WIDTH_8 (0 << 28)
82#define TEGRA_APBDMA_AHBSEQ_BUS_WIDTH_16 (1 << 28)
83#define TEGRA_APBDMA_AHBSEQ_BUS_WIDTH_32 (2 << 28)
84#define TEGRA_APBDMA_AHBSEQ_BUS_WIDTH_64 (3 << 28)
85#define TEGRA_APBDMA_AHBSEQ_BUS_WIDTH_128 (4 << 28)
86#define TEGRA_APBDMA_AHBSEQ_DATA_SWAP BIT(27)
87#define TEGRA_APBDMA_AHBSEQ_BURST_1 (4 << 24)
88#define TEGRA_APBDMA_AHBSEQ_BURST_4 (5 << 24)
89#define TEGRA_APBDMA_AHBSEQ_BURST_8 (6 << 24)
90#define TEGRA_APBDMA_AHBSEQ_DBL_BUF BIT(19)
91#define TEGRA_APBDMA_AHBSEQ_WRAP_SHIFT 16
92#define TEGRA_APBDMA_AHBSEQ_WRAP_NONE 0
93
94/* APB address */
95#define TEGRA_APBDMA_CHAN_APBPTR 0x018
96
97/* APB sequence register */
98#define TEGRA_APBDMA_CHAN_APBSEQ 0x01c
99#define TEGRA_APBDMA_APBSEQ_BUS_WIDTH_8 (0 << 28)
100#define TEGRA_APBDMA_APBSEQ_BUS_WIDTH_16 (1 << 28)
101#define TEGRA_APBDMA_APBSEQ_BUS_WIDTH_32 (2 << 28)
102#define TEGRA_APBDMA_APBSEQ_BUS_WIDTH_64 (3 << 28)
103#define TEGRA_APBDMA_APBSEQ_BUS_WIDTH_128 (4 << 28)
104#define TEGRA_APBDMA_APBSEQ_DATA_SWAP BIT(27)
105#define TEGRA_APBDMA_APBSEQ_WRAP_WORD_1 (1 << 16)
106
Laxman Dewangan911dacc2014-01-06 11:16:45 -0700107/* Tegra148 specific registers */
108#define TEGRA_APBDMA_CHAN_WCOUNT 0x20
109
110#define TEGRA_APBDMA_CHAN_WORD_TRANSFER 0x24
111
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530112/*
113 * If any burst is in flight and DMA paused then this is the time to complete
114 * on-flight burst and update DMA status register.
115 */
116#define TEGRA_APBDMA_BURST_COMPLETE_TIME 20
117
118/* Channel base address offset from APBDMA base address */
119#define TEGRA_APBDMA_CHANNEL_BASE_ADD_OFFSET 0x1000
120
Shardar Shariff Md00ef4492016-04-23 15:06:00 +0530121#define TEGRA_APBDMA_SLAVE_ID_INVALID (TEGRA_APBDMA_CSR_REQ_SEL_MASK + 1)
122
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530123struct tegra_dma;
124
125/*
126 * tegra_dma_chip_data Tegra chip specific DMA data
127 * @nr_channels: Number of channels available in the controller.
Laxman Dewangan911dacc2014-01-06 11:16:45 -0700128 * @channel_reg_size: Channel register size/stride.
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530129 * @max_dma_count: Maximum DMA transfer count supported by DMA controller.
Laxman Dewangan1b140902013-01-06 21:52:02 +0530130 * @support_channel_pause: Support channel wise pause of dma.
Laxman Dewangan911dacc2014-01-06 11:16:45 -0700131 * @support_separate_wcount_reg: Support separate word count register.
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530132 */
133struct tegra_dma_chip_data {
134 int nr_channels;
Laxman Dewangan911dacc2014-01-06 11:16:45 -0700135 int channel_reg_size;
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530136 int max_dma_count;
Laxman Dewangan1b140902013-01-06 21:52:02 +0530137 bool support_channel_pause;
Laxman Dewangan911dacc2014-01-06 11:16:45 -0700138 bool support_separate_wcount_reg;
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530139};
140
141/* DMA channel registers */
142struct tegra_dma_channel_regs {
143 unsigned long csr;
144 unsigned long ahb_ptr;
145 unsigned long apb_ptr;
146 unsigned long ahb_seq;
147 unsigned long apb_seq;
Laxman Dewangan911dacc2014-01-06 11:16:45 -0700148 unsigned long wcount;
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530149};
150
151/*
Ben Dooks547b3112018-11-21 16:13:21 +0000152 * tegra_dma_sg_req: DMA request details to configure hardware. This
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530153 * contains the details for one transfer to configure DMA hw.
154 * The client's request for data transfer can be broken into multiple
155 * sub-transfer as per requester details and hw support.
156 * This sub transfer get added in the list of transfer and point to Tegra
157 * DMA descriptor which manages the transfer details.
158 */
159struct tegra_dma_sg_req {
160 struct tegra_dma_channel_regs ch_regs;
Ben Dooks216a1d72018-11-21 16:13:20 +0000161 unsigned int req_len;
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530162 bool configured;
163 bool last_sg;
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530164 struct list_head node;
165 struct tegra_dma_desc *dma_desc;
166};
167
168/*
169 * tegra_dma_desc: Tegra DMA descriptors which manages the client requests.
170 * This descriptor keep track of transfer status, callbacks and request
171 * counts etc.
172 */
173struct tegra_dma_desc {
174 struct dma_async_tx_descriptor txd;
Ben Dooks216a1d72018-11-21 16:13:20 +0000175 unsigned int bytes_requested;
176 unsigned int bytes_transferred;
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530177 enum dma_status dma_status;
178 struct list_head node;
179 struct list_head tx_list;
180 struct list_head cb_node;
181 int cb_count;
182};
183
184struct tegra_dma_channel;
185
186typedef void (*dma_isr_handler)(struct tegra_dma_channel *tdc,
187 bool to_terminate);
188
189/* tegra_dma_channel: Channel specific information */
190struct tegra_dma_channel {
191 struct dma_chan dma_chan;
Ben Dooks65c383c2018-11-21 16:13:22 +0000192 char name[12];
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530193 bool config_init;
194 int id;
195 int irq;
Jon Hunter13a33282015-08-06 14:32:31 +0100196 void __iomem *chan_addr;
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530197 spinlock_t lock;
198 bool busy;
199 struct tegra_dma *tdma;
200 bool cyclic;
201
202 /* Different lists for managing the requests */
203 struct list_head free_sg_req;
204 struct list_head pending_sg_req;
205 struct list_head free_dma_desc;
206 struct list_head cb_desc;
207
208 /* ISR handler and tasklet for bottom half of isr handling */
209 dma_isr_handler isr_handler;
210 struct tasklet_struct tasklet;
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530211
212 /* Channel-slave specific configuration */
Stephen Warren996556c2013-11-11 13:09:35 -0700213 unsigned int slave_id;
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530214 struct dma_slave_config dma_sconfig;
Laxman Dewangan3065c192013-04-24 15:24:27 +0530215 struct tegra_dma_channel_regs channel_reg;
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530216};
217
218/* tegra_dma: Tegra DMA specific information */
219struct tegra_dma {
220 struct dma_device dma_dev;
221 struct device *dev;
222 struct clk *dma_clk;
Stephen Warren9aa433d2013-11-06 16:35:34 -0700223 struct reset_control *rst;
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530224 spinlock_t global_lock;
225 void __iomem *base_addr;
Laxman Dewangan83a1ef22012-08-29 10:23:07 +0200226 const struct tegra_dma_chip_data *chip_data;
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530227
Jon Hunter23a1ec32015-08-06 14:32:33 +0100228 /*
229 * Counter for managing global pausing of the DMA controller.
230 * Only applicable for devices that don't support individual
231 * channel pausing.
232 */
233 u32 global_pause_count;
234
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530235 /* Some register need to be cache before suspend */
236 u32 reg_gen;
237
238 /* Last member of the structure */
239 struct tegra_dma_channel channels[0];
240};
241
242static inline void tdma_write(struct tegra_dma *tdma, u32 reg, u32 val)
243{
244 writel(val, tdma->base_addr + reg);
245}
246
247static inline u32 tdma_read(struct tegra_dma *tdma, u32 reg)
248{
249 return readl(tdma->base_addr + reg);
250}
251
252static inline void tdc_write(struct tegra_dma_channel *tdc,
253 u32 reg, u32 val)
254{
Jon Hunter13a33282015-08-06 14:32:31 +0100255 writel(val, tdc->chan_addr + reg);
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530256}
257
258static inline u32 tdc_read(struct tegra_dma_channel *tdc, u32 reg)
259{
Jon Hunter13a33282015-08-06 14:32:31 +0100260 return readl(tdc->chan_addr + reg);
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530261}
262
263static inline struct tegra_dma_channel *to_tegra_dma_chan(struct dma_chan *dc)
264{
265 return container_of(dc, struct tegra_dma_channel, dma_chan);
266}
267
268static inline struct tegra_dma_desc *txd_to_tegra_dma_desc(
269 struct dma_async_tx_descriptor *td)
270{
271 return container_of(td, struct tegra_dma_desc, txd);
272}
273
274static inline struct device *tdc2dev(struct tegra_dma_channel *tdc)
275{
276 return &tdc->dma_chan.dev->device;
277}
278
279static dma_cookie_t tegra_dma_tx_submit(struct dma_async_tx_descriptor *tx);
280static int tegra_dma_runtime_suspend(struct device *dev);
281static int tegra_dma_runtime_resume(struct device *dev);
282
283/* Get DMA desc from free list, if not there then allocate it. */
284static struct tegra_dma_desc *tegra_dma_desc_get(
285 struct tegra_dma_channel *tdc)
286{
287 struct tegra_dma_desc *dma_desc;
288 unsigned long flags;
289
290 spin_lock_irqsave(&tdc->lock, flags);
291
292 /* Do not allocate if desc are waiting for ack */
293 list_for_each_entry(dma_desc, &tdc->free_dma_desc, node) {
294 if (async_tx_test_ack(&dma_desc->txd)) {
295 list_del(&dma_desc->node);
296 spin_unlock_irqrestore(&tdc->lock, flags);
Laxman Dewanganb9bb37f2013-01-09 15:26:22 +0530297 dma_desc->txd.flags = 0;
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530298 return dma_desc;
299 }
300 }
301
302 spin_unlock_irqrestore(&tdc->lock, flags);
303
304 /* Allocate DMA desc */
Jon Hunter8fe97392015-11-13 16:39:42 +0000305 dma_desc = kzalloc(sizeof(*dma_desc), GFP_NOWAIT);
Peter Griffinaef94fe2016-06-07 18:38:41 +0100306 if (!dma_desc)
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530307 return NULL;
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530308
309 dma_async_tx_descriptor_init(&dma_desc->txd, &tdc->dma_chan);
310 dma_desc->txd.tx_submit = tegra_dma_tx_submit;
311 dma_desc->txd.flags = 0;
312 return dma_desc;
313}
314
315static void tegra_dma_desc_put(struct tegra_dma_channel *tdc,
316 struct tegra_dma_desc *dma_desc)
317{
318 unsigned long flags;
319
320 spin_lock_irqsave(&tdc->lock, flags);
321 if (!list_empty(&dma_desc->tx_list))
322 list_splice_init(&dma_desc->tx_list, &tdc->free_sg_req);
323 list_add_tail(&dma_desc->node, &tdc->free_dma_desc);
324 spin_unlock_irqrestore(&tdc->lock, flags);
325}
326
327static struct tegra_dma_sg_req *tegra_dma_sg_req_get(
328 struct tegra_dma_channel *tdc)
329{
330 struct tegra_dma_sg_req *sg_req = NULL;
331 unsigned long flags;
332
333 spin_lock_irqsave(&tdc->lock, flags);
334 if (!list_empty(&tdc->free_sg_req)) {
335 sg_req = list_first_entry(&tdc->free_sg_req,
336 typeof(*sg_req), node);
337 list_del(&sg_req->node);
338 spin_unlock_irqrestore(&tdc->lock, flags);
339 return sg_req;
340 }
341 spin_unlock_irqrestore(&tdc->lock, flags);
342
Jon Hunter8fe97392015-11-13 16:39:42 +0000343 sg_req = kzalloc(sizeof(struct tegra_dma_sg_req), GFP_NOWAIT);
Peter Griffinaef94fe2016-06-07 18:38:41 +0100344
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530345 return sg_req;
346}
347
348static int tegra_dma_slave_config(struct dma_chan *dc,
349 struct dma_slave_config *sconfig)
350{
351 struct tegra_dma_channel *tdc = to_tegra_dma_chan(dc);
352
353 if (!list_empty(&tdc->pending_sg_req)) {
354 dev_err(tdc2dev(tdc), "Configuration not allowed\n");
355 return -EBUSY;
356 }
357
358 memcpy(&tdc->dma_sconfig, sconfig, sizeof(*sconfig));
Dmitry Osipenkof6160f32017-11-16 20:11:06 +0300359 if (tdc->slave_id == TEGRA_APBDMA_SLAVE_ID_INVALID &&
360 sconfig->device_fc) {
Shardar Shariff Md00ef4492016-04-23 15:06:00 +0530361 if (sconfig->slave_id > TEGRA_APBDMA_CSR_REQ_SEL_MASK)
362 return -EINVAL;
Stephen Warren996556c2013-11-11 13:09:35 -0700363 tdc->slave_id = sconfig->slave_id;
Shardar Shariff Md00ef4492016-04-23 15:06:00 +0530364 }
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530365 tdc->config_init = true;
366 return 0;
367}
368
369static void tegra_dma_global_pause(struct tegra_dma_channel *tdc,
370 bool wait_for_burst_complete)
371{
372 struct tegra_dma *tdma = tdc->tdma;
373
374 spin_lock(&tdma->global_lock);
Jon Hunter23a1ec32015-08-06 14:32:33 +0100375
376 if (tdc->tdma->global_pause_count == 0) {
377 tdma_write(tdma, TEGRA_APBDMA_GENERAL, 0);
378 if (wait_for_burst_complete)
379 udelay(TEGRA_APBDMA_BURST_COMPLETE_TIME);
380 }
381
382 tdc->tdma->global_pause_count++;
383
384 spin_unlock(&tdma->global_lock);
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530385}
386
387static void tegra_dma_global_resume(struct tegra_dma_channel *tdc)
388{
389 struct tegra_dma *tdma = tdc->tdma;
390
Jon Hunter23a1ec32015-08-06 14:32:33 +0100391 spin_lock(&tdma->global_lock);
392
393 if (WARN_ON(tdc->tdma->global_pause_count == 0))
394 goto out;
395
396 if (--tdc->tdma->global_pause_count == 0)
397 tdma_write(tdma, TEGRA_APBDMA_GENERAL,
398 TEGRA_APBDMA_GENERAL_ENABLE);
399
400out:
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530401 spin_unlock(&tdma->global_lock);
402}
403
Laxman Dewangan1b140902013-01-06 21:52:02 +0530404static void tegra_dma_pause(struct tegra_dma_channel *tdc,
405 bool wait_for_burst_complete)
406{
407 struct tegra_dma *tdma = tdc->tdma;
408
409 if (tdma->chip_data->support_channel_pause) {
410 tdc_write(tdc, TEGRA_APBDMA_CHAN_CSRE,
411 TEGRA_APBDMA_CHAN_CSRE_PAUSE);
412 if (wait_for_burst_complete)
413 udelay(TEGRA_APBDMA_BURST_COMPLETE_TIME);
414 } else {
415 tegra_dma_global_pause(tdc, wait_for_burst_complete);
416 }
417}
418
419static void tegra_dma_resume(struct tegra_dma_channel *tdc)
420{
421 struct tegra_dma *tdma = tdc->tdma;
422
423 if (tdma->chip_data->support_channel_pause) {
424 tdc_write(tdc, TEGRA_APBDMA_CHAN_CSRE, 0);
425 } else {
426 tegra_dma_global_resume(tdc);
427 }
428}
429
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530430static void tegra_dma_stop(struct tegra_dma_channel *tdc)
431{
432 u32 csr;
433 u32 status;
434
435 /* Disable interrupts */
436 csr = tdc_read(tdc, TEGRA_APBDMA_CHAN_CSR);
437 csr &= ~TEGRA_APBDMA_CSR_IE_EOC;
438 tdc_write(tdc, TEGRA_APBDMA_CHAN_CSR, csr);
439
440 /* Disable DMA */
441 csr &= ~TEGRA_APBDMA_CSR_ENB;
442 tdc_write(tdc, TEGRA_APBDMA_CHAN_CSR, csr);
443
444 /* Clear interrupt status if it is there */
445 status = tdc_read(tdc, TEGRA_APBDMA_CHAN_STATUS);
446 if (status & TEGRA_APBDMA_STATUS_ISE_EOC) {
447 dev_dbg(tdc2dev(tdc), "%s():clearing interrupt\n", __func__);
448 tdc_write(tdc, TEGRA_APBDMA_CHAN_STATUS, status);
449 }
450 tdc->busy = false;
451}
452
453static void tegra_dma_start(struct tegra_dma_channel *tdc,
454 struct tegra_dma_sg_req *sg_req)
455{
456 struct tegra_dma_channel_regs *ch_regs = &sg_req->ch_regs;
457
458 tdc_write(tdc, TEGRA_APBDMA_CHAN_CSR, ch_regs->csr);
459 tdc_write(tdc, TEGRA_APBDMA_CHAN_APBSEQ, ch_regs->apb_seq);
460 tdc_write(tdc, TEGRA_APBDMA_CHAN_APBPTR, ch_regs->apb_ptr);
461 tdc_write(tdc, TEGRA_APBDMA_CHAN_AHBSEQ, ch_regs->ahb_seq);
462 tdc_write(tdc, TEGRA_APBDMA_CHAN_AHBPTR, ch_regs->ahb_ptr);
Laxman Dewangan911dacc2014-01-06 11:16:45 -0700463 if (tdc->tdma->chip_data->support_separate_wcount_reg)
464 tdc_write(tdc, TEGRA_APBDMA_CHAN_WCOUNT, ch_regs->wcount);
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530465
466 /* Start DMA */
467 tdc_write(tdc, TEGRA_APBDMA_CHAN_CSR,
468 ch_regs->csr | TEGRA_APBDMA_CSR_ENB);
469}
470
471static void tegra_dma_configure_for_next(struct tegra_dma_channel *tdc,
472 struct tegra_dma_sg_req *nsg_req)
473{
474 unsigned long status;
475
476 /*
477 * The DMA controller reloads the new configuration for next transfer
478 * after last burst of current transfer completes.
479 * If there is no IEC status then this makes sure that last burst
480 * has not be completed. There may be case that last burst is on
481 * flight and so it can complete but because DMA is paused, it
482 * will not generates interrupt as well as not reload the new
483 * configuration.
484 * If there is already IEC status then interrupt handler need to
485 * load new configuration.
486 */
Laxman Dewangan1b140902013-01-06 21:52:02 +0530487 tegra_dma_pause(tdc, false);
Thierry Reding7b0e00d2016-06-14 16:18:46 +0200488 status = tdc_read(tdc, TEGRA_APBDMA_CHAN_STATUS);
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530489
490 /*
491 * If interrupt is pending then do nothing as the ISR will handle
492 * the programing for new request.
493 */
494 if (status & TEGRA_APBDMA_STATUS_ISE_EOC) {
495 dev_err(tdc2dev(tdc),
496 "Skipping new configuration as interrupt is pending\n");
Laxman Dewangan1b140902013-01-06 21:52:02 +0530497 tegra_dma_resume(tdc);
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530498 return;
499 }
500
501 /* Safe to program new configuration */
502 tdc_write(tdc, TEGRA_APBDMA_CHAN_APBPTR, nsg_req->ch_regs.apb_ptr);
503 tdc_write(tdc, TEGRA_APBDMA_CHAN_AHBPTR, nsg_req->ch_regs.ahb_ptr);
Laxman Dewangan911dacc2014-01-06 11:16:45 -0700504 if (tdc->tdma->chip_data->support_separate_wcount_reg)
505 tdc_write(tdc, TEGRA_APBDMA_CHAN_WCOUNT,
506 nsg_req->ch_regs.wcount);
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530507 tdc_write(tdc, TEGRA_APBDMA_CHAN_CSR,
508 nsg_req->ch_regs.csr | TEGRA_APBDMA_CSR_ENB);
509 nsg_req->configured = true;
510
Laxman Dewangan1b140902013-01-06 21:52:02 +0530511 tegra_dma_resume(tdc);
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530512}
513
514static void tdc_start_head_req(struct tegra_dma_channel *tdc)
515{
516 struct tegra_dma_sg_req *sg_req;
517
518 if (list_empty(&tdc->pending_sg_req))
519 return;
520
521 sg_req = list_first_entry(&tdc->pending_sg_req,
522 typeof(*sg_req), node);
523 tegra_dma_start(tdc, sg_req);
524 sg_req->configured = true;
525 tdc->busy = true;
526}
527
528static void tdc_configure_next_head_desc(struct tegra_dma_channel *tdc)
529{
530 struct tegra_dma_sg_req *hsgreq;
531 struct tegra_dma_sg_req *hnsgreq;
532
533 if (list_empty(&tdc->pending_sg_req))
534 return;
535
536 hsgreq = list_first_entry(&tdc->pending_sg_req, typeof(*hsgreq), node);
537 if (!list_is_last(&hsgreq->node, &tdc->pending_sg_req)) {
538 hnsgreq = list_first_entry(&hsgreq->node,
539 typeof(*hnsgreq), node);
540 tegra_dma_configure_for_next(tdc, hnsgreq);
541 }
542}
543
544static inline int get_current_xferred_count(struct tegra_dma_channel *tdc,
545 struct tegra_dma_sg_req *sg_req, unsigned long status)
546{
547 return sg_req->req_len - (status & TEGRA_APBDMA_STATUS_COUNT_MASK) - 4;
548}
549
550static void tegra_dma_abort_all(struct tegra_dma_channel *tdc)
551{
552 struct tegra_dma_sg_req *sgreq;
553 struct tegra_dma_desc *dma_desc;
554
555 while (!list_empty(&tdc->pending_sg_req)) {
556 sgreq = list_first_entry(&tdc->pending_sg_req,
557 typeof(*sgreq), node);
Wei Yongjun2cc44e62012-09-05 15:08:56 +0800558 list_move_tail(&sgreq->node, &tdc->free_sg_req);
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530559 if (sgreq->last_sg) {
560 dma_desc = sgreq->dma_desc;
561 dma_desc->dma_status = DMA_ERROR;
562 list_add_tail(&dma_desc->node, &tdc->free_dma_desc);
563
564 /* Add in cb list if it is not there. */
565 if (!dma_desc->cb_count)
566 list_add_tail(&dma_desc->cb_node,
567 &tdc->cb_desc);
568 dma_desc->cb_count++;
569 }
570 }
571 tdc->isr_handler = NULL;
572}
573
574static bool handle_continuous_head_request(struct tegra_dma_channel *tdc,
575 struct tegra_dma_sg_req *last_sg_req, bool to_terminate)
576{
577 struct tegra_dma_sg_req *hsgreq = NULL;
578
579 if (list_empty(&tdc->pending_sg_req)) {
Ben Dooks547b3112018-11-21 16:13:21 +0000580 dev_err(tdc2dev(tdc), "DMA is running without req\n");
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530581 tegra_dma_stop(tdc);
582 return false;
583 }
584
585 /*
586 * Check that head req on list should be in flight.
587 * If it is not in flight then abort transfer as
588 * looping of transfer can not continue.
589 */
590 hsgreq = list_first_entry(&tdc->pending_sg_req, typeof(*hsgreq), node);
591 if (!hsgreq->configured) {
592 tegra_dma_stop(tdc);
Ben Dooks547b3112018-11-21 16:13:21 +0000593 dev_err(tdc2dev(tdc), "Error in DMA transfer, aborting DMA\n");
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530594 tegra_dma_abort_all(tdc);
595 return false;
596 }
597
598 /* Configure next request */
599 if (!to_terminate)
600 tdc_configure_next_head_desc(tdc);
601 return true;
602}
603
604static void handle_once_dma_done(struct tegra_dma_channel *tdc,
605 bool to_terminate)
606{
607 struct tegra_dma_sg_req *sgreq;
608 struct tegra_dma_desc *dma_desc;
609
610 tdc->busy = false;
611 sgreq = list_first_entry(&tdc->pending_sg_req, typeof(*sgreq), node);
612 dma_desc = sgreq->dma_desc;
613 dma_desc->bytes_transferred += sgreq->req_len;
614
615 list_del(&sgreq->node);
616 if (sgreq->last_sg) {
Vinod Koul00d696f2013-10-16 21:04:50 +0530617 dma_desc->dma_status = DMA_COMPLETE;
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530618 dma_cookie_complete(&dma_desc->txd);
619 if (!dma_desc->cb_count)
620 list_add_tail(&dma_desc->cb_node, &tdc->cb_desc);
621 dma_desc->cb_count++;
622 list_add_tail(&dma_desc->node, &tdc->free_dma_desc);
623 }
624 list_add_tail(&sgreq->node, &tdc->free_sg_req);
625
626 /* Do not start DMA if it is going to be terminate */
627 if (to_terminate || list_empty(&tdc->pending_sg_req))
628 return;
629
630 tdc_start_head_req(tdc);
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530631}
632
633static void handle_cont_sngl_cycle_dma_done(struct tegra_dma_channel *tdc,
634 bool to_terminate)
635{
636 struct tegra_dma_sg_req *sgreq;
637 struct tegra_dma_desc *dma_desc;
638 bool st;
639
640 sgreq = list_first_entry(&tdc->pending_sg_req, typeof(*sgreq), node);
641 dma_desc = sgreq->dma_desc;
Ben Dookse486df32018-11-21 16:13:19 +0000642 /* if we dma for long enough the transfer count will wrap */
643 dma_desc->bytes_transferred =
644 (dma_desc->bytes_transferred + sgreq->req_len) %
645 dma_desc->bytes_requested;
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530646
647 /* Callback need to be call */
648 if (!dma_desc->cb_count)
649 list_add_tail(&dma_desc->cb_node, &tdc->cb_desc);
650 dma_desc->cb_count++;
651
652 /* If not last req then put at end of pending list */
653 if (!list_is_last(&sgreq->node, &tdc->pending_sg_req)) {
Wei Yongjun2cc44e62012-09-05 15:08:56 +0800654 list_move_tail(&sgreq->node, &tdc->pending_sg_req);
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530655 sgreq->configured = false;
656 st = handle_continuous_head_request(tdc, sgreq, to_terminate);
657 if (!st)
658 dma_desc->dma_status = DMA_ERROR;
659 }
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530660}
661
662static void tegra_dma_tasklet(unsigned long data)
663{
664 struct tegra_dma_channel *tdc = (struct tegra_dma_channel *)data;
Dave Jiang370c0442016-07-20 13:13:16 -0700665 struct dmaengine_desc_callback cb;
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530666 struct tegra_dma_desc *dma_desc;
667 unsigned long flags;
668 int cb_count;
669
670 spin_lock_irqsave(&tdc->lock, flags);
671 while (!list_empty(&tdc->cb_desc)) {
672 dma_desc = list_first_entry(&tdc->cb_desc,
673 typeof(*dma_desc), cb_node);
674 list_del(&dma_desc->cb_node);
Dave Jiang370c0442016-07-20 13:13:16 -0700675 dmaengine_desc_get_callback(&dma_desc->txd, &cb);
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530676 cb_count = dma_desc->cb_count;
677 dma_desc->cb_count = 0;
Ben Dooks95f295f2018-11-21 16:13:23 +0000678 trace_tegra_dma_complete_cb(&tdc->dma_chan, cb_count,
679 cb.callback);
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530680 spin_unlock_irqrestore(&tdc->lock, flags);
Dave Jiang370c0442016-07-20 13:13:16 -0700681 while (cb_count--)
682 dmaengine_desc_callback_invoke(&cb, NULL);
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530683 spin_lock_irqsave(&tdc->lock, flags);
684 }
685 spin_unlock_irqrestore(&tdc->lock, flags);
686}
687
688static irqreturn_t tegra_dma_isr(int irq, void *dev_id)
689{
690 struct tegra_dma_channel *tdc = dev_id;
691 unsigned long status;
692 unsigned long flags;
693
694 spin_lock_irqsave(&tdc->lock, flags);
695
Ben Dooks95f295f2018-11-21 16:13:23 +0000696 trace_tegra_dma_isr(&tdc->dma_chan, irq);
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530697 status = tdc_read(tdc, TEGRA_APBDMA_CHAN_STATUS);
698 if (status & TEGRA_APBDMA_STATUS_ISE_EOC) {
699 tdc_write(tdc, TEGRA_APBDMA_CHAN_STATUS, status);
700 tdc->isr_handler(tdc, false);
701 tasklet_schedule(&tdc->tasklet);
702 spin_unlock_irqrestore(&tdc->lock, flags);
703 return IRQ_HANDLED;
704 }
705
706 spin_unlock_irqrestore(&tdc->lock, flags);
707 dev_info(tdc2dev(tdc),
708 "Interrupt already served status 0x%08lx\n", status);
709 return IRQ_NONE;
710}
711
712static dma_cookie_t tegra_dma_tx_submit(struct dma_async_tx_descriptor *txd)
713{
714 struct tegra_dma_desc *dma_desc = txd_to_tegra_dma_desc(txd);
715 struct tegra_dma_channel *tdc = to_tegra_dma_chan(txd->chan);
716 unsigned long flags;
717 dma_cookie_t cookie;
718
719 spin_lock_irqsave(&tdc->lock, flags);
720 dma_desc->dma_status = DMA_IN_PROGRESS;
721 cookie = dma_cookie_assign(&dma_desc->txd);
722 list_splice_tail_init(&dma_desc->tx_list, &tdc->pending_sg_req);
723 spin_unlock_irqrestore(&tdc->lock, flags);
724 return cookie;
725}
726
727static void tegra_dma_issue_pending(struct dma_chan *dc)
728{
729 struct tegra_dma_channel *tdc = to_tegra_dma_chan(dc);
730 unsigned long flags;
731
732 spin_lock_irqsave(&tdc->lock, flags);
733 if (list_empty(&tdc->pending_sg_req)) {
734 dev_err(tdc2dev(tdc), "No DMA request\n");
735 goto end;
736 }
737 if (!tdc->busy) {
738 tdc_start_head_req(tdc);
739
740 /* Continuous single mode: Configure next req */
741 if (tdc->cyclic) {
742 /*
743 * Wait for 1 burst time for configure DMA for
744 * next transfer.
745 */
746 udelay(TEGRA_APBDMA_BURST_COMPLETE_TIME);
747 tdc_configure_next_head_desc(tdc);
748 }
749 }
750end:
751 spin_unlock_irqrestore(&tdc->lock, flags);
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530752}
753
Vinod Koula7c439a2014-12-08 11:30:17 +0530754static int tegra_dma_terminate_all(struct dma_chan *dc)
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530755{
756 struct tegra_dma_channel *tdc = to_tegra_dma_chan(dc);
757 struct tegra_dma_sg_req *sgreq;
758 struct tegra_dma_desc *dma_desc;
759 unsigned long flags;
760 unsigned long status;
Laxman Dewangan911dacc2014-01-06 11:16:45 -0700761 unsigned long wcount;
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530762 bool was_busy;
763
764 spin_lock_irqsave(&tdc->lock, flags);
765 if (list_empty(&tdc->pending_sg_req)) {
766 spin_unlock_irqrestore(&tdc->lock, flags);
Vinod Koula7c439a2014-12-08 11:30:17 +0530767 return 0;
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530768 }
769
770 if (!tdc->busy)
771 goto skip_dma_stop;
772
773 /* Pause DMA before checking the queue status */
Laxman Dewangan1b140902013-01-06 21:52:02 +0530774 tegra_dma_pause(tdc, true);
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530775
776 status = tdc_read(tdc, TEGRA_APBDMA_CHAN_STATUS);
777 if (status & TEGRA_APBDMA_STATUS_ISE_EOC) {
778 dev_dbg(tdc2dev(tdc), "%s():handling isr\n", __func__);
779 tdc->isr_handler(tdc, true);
780 status = tdc_read(tdc, TEGRA_APBDMA_CHAN_STATUS);
781 }
Laxman Dewangan911dacc2014-01-06 11:16:45 -0700782 if (tdc->tdma->chip_data->support_separate_wcount_reg)
783 wcount = tdc_read(tdc, TEGRA_APBDMA_CHAN_WORD_TRANSFER);
784 else
785 wcount = status;
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530786
787 was_busy = tdc->busy;
788 tegra_dma_stop(tdc);
789
790 if (!list_empty(&tdc->pending_sg_req) && was_busy) {
791 sgreq = list_first_entry(&tdc->pending_sg_req,
792 typeof(*sgreq), node);
793 sgreq->dma_desc->bytes_transferred +=
Laxman Dewangan911dacc2014-01-06 11:16:45 -0700794 get_current_xferred_count(tdc, sgreq, wcount);
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530795 }
Laxman Dewangan1b140902013-01-06 21:52:02 +0530796 tegra_dma_resume(tdc);
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530797
798skip_dma_stop:
799 tegra_dma_abort_all(tdc);
800
801 while (!list_empty(&tdc->cb_desc)) {
802 dma_desc = list_first_entry(&tdc->cb_desc,
803 typeof(*dma_desc), cb_node);
804 list_del(&dma_desc->cb_node);
805 dma_desc->cb_count = 0;
806 }
807 spin_unlock_irqrestore(&tdc->lock, flags);
Vinod Koula7c439a2014-12-08 11:30:17 +0530808 return 0;
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530809}
810
811static enum dma_status tegra_dma_tx_status(struct dma_chan *dc,
812 dma_cookie_t cookie, struct dma_tx_state *txstate)
813{
814 struct tegra_dma_channel *tdc = to_tegra_dma_chan(dc);
815 struct tegra_dma_desc *dma_desc;
816 struct tegra_dma_sg_req *sg_req;
817 enum dma_status ret;
818 unsigned long flags;
Laxman Dewangan4a46ba32012-07-02 13:52:07 +0530819 unsigned int residual;
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530820
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530821 ret = dma_cookie_status(dc, cookie, txstate);
Jon Hunterd3183442016-06-29 17:08:39 +0100822 if (ret == DMA_COMPLETE)
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530823 return ret;
Andy Shevchenko0a0aee22013-05-27 15:14:39 +0300824
825 spin_lock_irqsave(&tdc->lock, flags);
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530826
827 /* Check on wait_ack desc status */
828 list_for_each_entry(dma_desc, &tdc->free_dma_desc, node) {
829 if (dma_desc->txd.cookie == cookie) {
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530830 ret = dma_desc->dma_status;
Jon Hunter004f6142016-06-29 17:08:38 +0100831 goto found;
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530832 }
833 }
834
835 /* Check in pending list */
836 list_for_each_entry(sg_req, &tdc->pending_sg_req, node) {
837 dma_desc = sg_req->dma_desc;
838 if (dma_desc->txd.cookie == cookie) {
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530839 ret = dma_desc->dma_status;
Jon Hunter004f6142016-06-29 17:08:38 +0100840 goto found;
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530841 }
842 }
843
Jon Hunter019bfcc2016-06-29 17:08:37 +0100844 dev_dbg(tdc2dev(tdc), "cookie %d not found\n", cookie);
Jon Hunter004f6142016-06-29 17:08:38 +0100845 dma_desc = NULL;
846
847found:
Jon Hunterd3183442016-06-29 17:08:39 +0100848 if (dma_desc && txstate) {
Jon Hunter004f6142016-06-29 17:08:38 +0100849 residual = dma_desc->bytes_requested -
850 (dma_desc->bytes_transferred %
851 dma_desc->bytes_requested);
852 dma_set_residue(txstate, residual);
853 }
854
Ben Dooks95f295f2018-11-21 16:13:23 +0000855 trace_tegra_dma_tx_status(&tdc->dma_chan, cookie, txstate);
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530856 spin_unlock_irqrestore(&tdc->lock, flags);
857 return ret;
858}
859
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530860static inline int get_bus_width(struct tegra_dma_channel *tdc,
861 enum dma_slave_buswidth slave_bw)
862{
863 switch (slave_bw) {
864 case DMA_SLAVE_BUSWIDTH_1_BYTE:
865 return TEGRA_APBDMA_APBSEQ_BUS_WIDTH_8;
866 case DMA_SLAVE_BUSWIDTH_2_BYTES:
867 return TEGRA_APBDMA_APBSEQ_BUS_WIDTH_16;
868 case DMA_SLAVE_BUSWIDTH_4_BYTES:
869 return TEGRA_APBDMA_APBSEQ_BUS_WIDTH_32;
870 case DMA_SLAVE_BUSWIDTH_8_BYTES:
871 return TEGRA_APBDMA_APBSEQ_BUS_WIDTH_64;
872 default:
873 dev_warn(tdc2dev(tdc),
874 "slave bw is not supported, using 32bits\n");
875 return TEGRA_APBDMA_APBSEQ_BUS_WIDTH_32;
876 }
877}
878
879static inline int get_burst_size(struct tegra_dma_channel *tdc,
880 u32 burst_size, enum dma_slave_buswidth slave_bw, int len)
881{
882 int burst_byte;
883 int burst_ahb_width;
884
885 /*
886 * burst_size from client is in terms of the bus_width.
887 * convert them into AHB memory width which is 4 byte.
888 */
889 burst_byte = burst_size * slave_bw;
890 burst_ahb_width = burst_byte / 4;
891
892 /* If burst size is 0 then calculate the burst size based on length */
893 if (!burst_ahb_width) {
894 if (len & 0xF)
895 return TEGRA_APBDMA_AHBSEQ_BURST_1;
896 else if ((len >> 4) & 0x1)
897 return TEGRA_APBDMA_AHBSEQ_BURST_4;
898 else
899 return TEGRA_APBDMA_AHBSEQ_BURST_8;
900 }
901 if (burst_ahb_width < 4)
902 return TEGRA_APBDMA_AHBSEQ_BURST_1;
903 else if (burst_ahb_width < 8)
904 return TEGRA_APBDMA_AHBSEQ_BURST_4;
905 else
906 return TEGRA_APBDMA_AHBSEQ_BURST_8;
907}
908
909static int get_transfer_param(struct tegra_dma_channel *tdc,
910 enum dma_transfer_direction direction, unsigned long *apb_addr,
911 unsigned long *apb_seq, unsigned long *csr, unsigned int *burst_size,
912 enum dma_slave_buswidth *slave_bw)
913{
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530914 switch (direction) {
915 case DMA_MEM_TO_DEV:
916 *apb_addr = tdc->dma_sconfig.dst_addr;
917 *apb_seq = get_bus_width(tdc, tdc->dma_sconfig.dst_addr_width);
918 *burst_size = tdc->dma_sconfig.dst_maxburst;
919 *slave_bw = tdc->dma_sconfig.dst_addr_width;
920 *csr = TEGRA_APBDMA_CSR_DIR;
921 return 0;
922
923 case DMA_DEV_TO_MEM:
924 *apb_addr = tdc->dma_sconfig.src_addr;
925 *apb_seq = get_bus_width(tdc, tdc->dma_sconfig.src_addr_width);
926 *burst_size = tdc->dma_sconfig.src_maxburst;
927 *slave_bw = tdc->dma_sconfig.src_addr_width;
928 *csr = 0;
929 return 0;
930
931 default:
Ben Dooks547b3112018-11-21 16:13:21 +0000932 dev_err(tdc2dev(tdc), "DMA direction is not supported\n");
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530933 return -EINVAL;
934 }
935 return -EINVAL;
936}
937
Laxman Dewangan911dacc2014-01-06 11:16:45 -0700938static void tegra_dma_prep_wcount(struct tegra_dma_channel *tdc,
939 struct tegra_dma_channel_regs *ch_regs, u32 len)
940{
941 u32 len_field = (len - 4) & 0xFFFC;
942
943 if (tdc->tdma->chip_data->support_separate_wcount_reg)
944 ch_regs->wcount = len_field;
945 else
946 ch_regs->csr |= len_field;
947}
948
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530949static struct dma_async_tx_descriptor *tegra_dma_prep_slave_sg(
950 struct dma_chan *dc, struct scatterlist *sgl, unsigned int sg_len,
951 enum dma_transfer_direction direction, unsigned long flags,
952 void *context)
953{
954 struct tegra_dma_channel *tdc = to_tegra_dma_chan(dc);
955 struct tegra_dma_desc *dma_desc;
Thierry Reding7b0e00d2016-06-14 16:18:46 +0200956 unsigned int i;
957 struct scatterlist *sg;
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530958 unsigned long csr, ahb_seq, apb_ptr, apb_seq;
959 struct list_head req_list;
960 struct tegra_dma_sg_req *sg_req = NULL;
961 u32 burst_size;
962 enum dma_slave_buswidth slave_bw;
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530963
964 if (!tdc->config_init) {
Ben Dooks547b3112018-11-21 16:13:21 +0000965 dev_err(tdc2dev(tdc), "DMA channel is not configured\n");
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530966 return NULL;
967 }
968 if (sg_len < 1) {
969 dev_err(tdc2dev(tdc), "Invalid segment length %d\n", sg_len);
970 return NULL;
971 }
972
Jon Hunterdc1ff4b2015-08-06 14:32:32 +0100973 if (get_transfer_param(tdc, direction, &apb_ptr, &apb_seq, &csr,
974 &burst_size, &slave_bw) < 0)
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530975 return NULL;
976
977 INIT_LIST_HEAD(&req_list);
978
979 ahb_seq = TEGRA_APBDMA_AHBSEQ_INTR_ENB;
980 ahb_seq |= TEGRA_APBDMA_AHBSEQ_WRAP_NONE <<
981 TEGRA_APBDMA_AHBSEQ_WRAP_SHIFT;
982 ahb_seq |= TEGRA_APBDMA_AHBSEQ_BUS_WIDTH_32;
983
Dmitry Osipenkof6160f32017-11-16 20:11:06 +0300984 csr |= TEGRA_APBDMA_CSR_ONCE;
985
986 if (tdc->slave_id != TEGRA_APBDMA_SLAVE_ID_INVALID) {
987 csr |= TEGRA_APBDMA_CSR_FLOW;
988 csr |= tdc->slave_id << TEGRA_APBDMA_CSR_REQ_SEL_SHIFT;
989 }
990
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530991 if (flags & DMA_PREP_INTERRUPT)
992 csr |= TEGRA_APBDMA_CSR_IE_EOC;
993
994 apb_seq |= TEGRA_APBDMA_APBSEQ_WRAP_WORD_1;
995
996 dma_desc = tegra_dma_desc_get(tdc);
997 if (!dma_desc) {
Ben Dooks547b3112018-11-21 16:13:21 +0000998 dev_err(tdc2dev(tdc), "DMA descriptors not available\n");
Laxman Dewanganec8a1582012-06-06 10:55:27 +0530999 return NULL;
1000 }
1001 INIT_LIST_HEAD(&dma_desc->tx_list);
1002 INIT_LIST_HEAD(&dma_desc->cb_node);
1003 dma_desc->cb_count = 0;
1004 dma_desc->bytes_requested = 0;
1005 dma_desc->bytes_transferred = 0;
1006 dma_desc->dma_status = DMA_IN_PROGRESS;
1007
1008 /* Make transfer requests */
1009 for_each_sg(sgl, sg, sg_len, i) {
1010 u32 len, mem;
1011
Laxman Dewangan597c8542012-06-22 20:41:10 +05301012 mem = sg_dma_address(sg);
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301013 len = sg_dma_len(sg);
1014
1015 if ((len & 3) || (mem & 3) ||
1016 (len > tdc->tdma->chip_data->max_dma_count)) {
1017 dev_err(tdc2dev(tdc),
Ben Dooks547b3112018-11-21 16:13:21 +00001018 "DMA length/memory address is not supported\n");
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301019 tegra_dma_desc_put(tdc, dma_desc);
1020 return NULL;
1021 }
1022
1023 sg_req = tegra_dma_sg_req_get(tdc);
1024 if (!sg_req) {
Ben Dooks547b3112018-11-21 16:13:21 +00001025 dev_err(tdc2dev(tdc), "DMA sg-req not available\n");
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301026 tegra_dma_desc_put(tdc, dma_desc);
1027 return NULL;
1028 }
1029
1030 ahb_seq |= get_burst_size(tdc, burst_size, slave_bw, len);
1031 dma_desc->bytes_requested += len;
1032
1033 sg_req->ch_regs.apb_ptr = apb_ptr;
1034 sg_req->ch_regs.ahb_ptr = mem;
Laxman Dewangan911dacc2014-01-06 11:16:45 -07001035 sg_req->ch_regs.csr = csr;
1036 tegra_dma_prep_wcount(tdc, &sg_req->ch_regs, len);
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301037 sg_req->ch_regs.apb_seq = apb_seq;
1038 sg_req->ch_regs.ahb_seq = ahb_seq;
1039 sg_req->configured = false;
1040 sg_req->last_sg = false;
1041 sg_req->dma_desc = dma_desc;
1042 sg_req->req_len = len;
1043
1044 list_add_tail(&sg_req->node, &dma_desc->tx_list);
1045 }
1046 sg_req->last_sg = true;
1047 if (flags & DMA_CTRL_ACK)
1048 dma_desc->txd.flags = DMA_CTRL_ACK;
1049
1050 /*
1051 * Make sure that mode should not be conflicting with currently
1052 * configured mode.
1053 */
1054 if (!tdc->isr_handler) {
1055 tdc->isr_handler = handle_once_dma_done;
1056 tdc->cyclic = false;
1057 } else {
1058 if (tdc->cyclic) {
1059 dev_err(tdc2dev(tdc), "DMA configured in cyclic mode\n");
1060 tegra_dma_desc_put(tdc, dma_desc);
1061 return NULL;
1062 }
1063 }
1064
1065 return &dma_desc->txd;
1066}
1067
Sachin Kamat404ff6692013-09-06 17:16:22 +05301068static struct dma_async_tx_descriptor *tegra_dma_prep_dma_cyclic(
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301069 struct dma_chan *dc, dma_addr_t buf_addr, size_t buf_len,
1070 size_t period_len, enum dma_transfer_direction direction,
Laurent Pinchart31c1e5a2014-08-01 12:20:10 +02001071 unsigned long flags)
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301072{
1073 struct tegra_dma_channel *tdc = to_tegra_dma_chan(dc);
1074 struct tegra_dma_desc *dma_desc = NULL;
Thierry Reding7b0e00d2016-06-14 16:18:46 +02001075 struct tegra_dma_sg_req *sg_req = NULL;
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301076 unsigned long csr, ahb_seq, apb_ptr, apb_seq;
1077 int len;
1078 size_t remain_len;
1079 dma_addr_t mem = buf_addr;
1080 u32 burst_size;
1081 enum dma_slave_buswidth slave_bw;
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301082
1083 if (!buf_len || !period_len) {
1084 dev_err(tdc2dev(tdc), "Invalid buffer/period len\n");
1085 return NULL;
1086 }
1087
1088 if (!tdc->config_init) {
1089 dev_err(tdc2dev(tdc), "DMA slave is not configured\n");
1090 return NULL;
1091 }
1092
1093 /*
1094 * We allow to take more number of requests till DMA is
1095 * not started. The driver will loop over all requests.
1096 * Once DMA is started then new requests can be queued only after
1097 * terminating the DMA.
1098 */
1099 if (tdc->busy) {
Ben Dooks547b3112018-11-21 16:13:21 +00001100 dev_err(tdc2dev(tdc), "Request not allowed when DMA running\n");
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301101 return NULL;
1102 }
1103
1104 /*
1105 * We only support cycle transfer when buf_len is multiple of
1106 * period_len.
1107 */
1108 if (buf_len % period_len) {
1109 dev_err(tdc2dev(tdc), "buf_len is not multiple of period_len\n");
1110 return NULL;
1111 }
1112
1113 len = period_len;
1114 if ((len & 3) || (buf_addr & 3) ||
1115 (len > tdc->tdma->chip_data->max_dma_count)) {
1116 dev_err(tdc2dev(tdc), "Req len/mem address is not correct\n");
1117 return NULL;
1118 }
1119
Jon Hunterdc1ff4b2015-08-06 14:32:32 +01001120 if (get_transfer_param(tdc, direction, &apb_ptr, &apb_seq, &csr,
1121 &burst_size, &slave_bw) < 0)
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301122 return NULL;
1123
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301124 ahb_seq = TEGRA_APBDMA_AHBSEQ_INTR_ENB;
1125 ahb_seq |= TEGRA_APBDMA_AHBSEQ_WRAP_NONE <<
1126 TEGRA_APBDMA_AHBSEQ_WRAP_SHIFT;
1127 ahb_seq |= TEGRA_APBDMA_AHBSEQ_BUS_WIDTH_32;
1128
Dmitry Osipenkof6160f32017-11-16 20:11:06 +03001129 if (tdc->slave_id != TEGRA_APBDMA_SLAVE_ID_INVALID) {
1130 csr |= TEGRA_APBDMA_CSR_FLOW;
1131 csr |= tdc->slave_id << TEGRA_APBDMA_CSR_REQ_SEL_SHIFT;
1132 }
1133
Laxman Dewanganb9bb37f2013-01-09 15:26:22 +05301134 if (flags & DMA_PREP_INTERRUPT)
1135 csr |= TEGRA_APBDMA_CSR_IE_EOC;
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301136
1137 apb_seq |= TEGRA_APBDMA_APBSEQ_WRAP_WORD_1;
1138
1139 dma_desc = tegra_dma_desc_get(tdc);
1140 if (!dma_desc) {
1141 dev_err(tdc2dev(tdc), "not enough descriptors available\n");
1142 return NULL;
1143 }
1144
1145 INIT_LIST_HEAD(&dma_desc->tx_list);
1146 INIT_LIST_HEAD(&dma_desc->cb_node);
1147 dma_desc->cb_count = 0;
1148
1149 dma_desc->bytes_transferred = 0;
1150 dma_desc->bytes_requested = buf_len;
1151 remain_len = buf_len;
1152
1153 /* Split transfer equal to period size */
1154 while (remain_len) {
1155 sg_req = tegra_dma_sg_req_get(tdc);
1156 if (!sg_req) {
Ben Dooks547b3112018-11-21 16:13:21 +00001157 dev_err(tdc2dev(tdc), "DMA sg-req not available\n");
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301158 tegra_dma_desc_put(tdc, dma_desc);
1159 return NULL;
1160 }
1161
1162 ahb_seq |= get_burst_size(tdc, burst_size, slave_bw, len);
1163 sg_req->ch_regs.apb_ptr = apb_ptr;
1164 sg_req->ch_regs.ahb_ptr = mem;
Laxman Dewangan911dacc2014-01-06 11:16:45 -07001165 sg_req->ch_regs.csr = csr;
1166 tegra_dma_prep_wcount(tdc, &sg_req->ch_regs, len);
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301167 sg_req->ch_regs.apb_seq = apb_seq;
1168 sg_req->ch_regs.ahb_seq = ahb_seq;
1169 sg_req->configured = false;
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301170 sg_req->last_sg = false;
1171 sg_req->dma_desc = dma_desc;
1172 sg_req->req_len = len;
1173
1174 list_add_tail(&sg_req->node, &dma_desc->tx_list);
1175 remain_len -= len;
1176 mem += len;
1177 }
1178 sg_req->last_sg = true;
Laxman Dewanganb9bb37f2013-01-09 15:26:22 +05301179 if (flags & DMA_CTRL_ACK)
1180 dma_desc->txd.flags = DMA_CTRL_ACK;
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301181
1182 /*
1183 * Make sure that mode should not be conflicting with currently
1184 * configured mode.
1185 */
1186 if (!tdc->isr_handler) {
1187 tdc->isr_handler = handle_cont_sngl_cycle_dma_done;
1188 tdc->cyclic = true;
1189 } else {
1190 if (!tdc->cyclic) {
1191 dev_err(tdc2dev(tdc), "DMA configuration conflict\n");
1192 tegra_dma_desc_put(tdc, dma_desc);
1193 return NULL;
1194 }
1195 }
1196
1197 return &dma_desc->txd;
1198}
1199
1200static int tegra_dma_alloc_chan_resources(struct dma_chan *dc)
1201{
1202 struct tegra_dma_channel *tdc = to_tegra_dma_chan(dc);
Laxman Dewanganffc49302012-07-20 13:31:08 +05301203 struct tegra_dma *tdma = tdc->tdma;
1204 int ret;
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301205
1206 dma_cookie_init(&tdc->dma_chan);
1207 tdc->config_init = false;
Jon Hunteredd3bdb2015-11-13 16:39:38 +00001208
1209 ret = pm_runtime_get_sync(tdma->dev);
Laxman Dewanganffc49302012-07-20 13:31:08 +05301210 if (ret < 0)
Jon Hunteredd3bdb2015-11-13 16:39:38 +00001211 return ret;
1212
1213 return 0;
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301214}
1215
1216static void tegra_dma_free_chan_resources(struct dma_chan *dc)
1217{
1218 struct tegra_dma_channel *tdc = to_tegra_dma_chan(dc);
Laxman Dewanganffc49302012-07-20 13:31:08 +05301219 struct tegra_dma *tdma = tdc->tdma;
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301220 struct tegra_dma_desc *dma_desc;
1221 struct tegra_dma_sg_req *sg_req;
1222 struct list_head dma_desc_list;
1223 struct list_head sg_req_list;
1224 unsigned long flags;
1225
1226 INIT_LIST_HEAD(&dma_desc_list);
1227 INIT_LIST_HEAD(&sg_req_list);
1228
1229 dev_dbg(tdc2dev(tdc), "Freeing channel %d\n", tdc->id);
1230
1231 if (tdc->busy)
1232 tegra_dma_terminate_all(dc);
1233
1234 spin_lock_irqsave(&tdc->lock, flags);
1235 list_splice_init(&tdc->pending_sg_req, &sg_req_list);
1236 list_splice_init(&tdc->free_sg_req, &sg_req_list);
1237 list_splice_init(&tdc->free_dma_desc, &dma_desc_list);
1238 INIT_LIST_HEAD(&tdc->cb_desc);
1239 tdc->config_init = false;
Dmitry Osipenko7bdc1e22013-05-11 20:30:53 +04001240 tdc->isr_handler = NULL;
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301241 spin_unlock_irqrestore(&tdc->lock, flags);
1242
1243 while (!list_empty(&dma_desc_list)) {
1244 dma_desc = list_first_entry(&dma_desc_list,
1245 typeof(*dma_desc), node);
1246 list_del(&dma_desc->node);
1247 kfree(dma_desc);
1248 }
1249
1250 while (!list_empty(&sg_req_list)) {
1251 sg_req = list_first_entry(&sg_req_list, typeof(*sg_req), node);
1252 list_del(&sg_req->node);
1253 kfree(sg_req);
1254 }
Jon Hunteredd3bdb2015-11-13 16:39:38 +00001255 pm_runtime_put(tdma->dev);
Stephen Warren996556c2013-11-11 13:09:35 -07001256
Shardar Shariff Md00ef4492016-04-23 15:06:00 +05301257 tdc->slave_id = TEGRA_APBDMA_SLAVE_ID_INVALID;
Stephen Warren996556c2013-11-11 13:09:35 -07001258}
1259
1260static struct dma_chan *tegra_dma_of_xlate(struct of_phandle_args *dma_spec,
1261 struct of_dma *ofdma)
1262{
1263 struct tegra_dma *tdma = ofdma->of_dma_data;
1264 struct dma_chan *chan;
1265 struct tegra_dma_channel *tdc;
1266
Shardar Shariff Md00ef4492016-04-23 15:06:00 +05301267 if (dma_spec->args[0] > TEGRA_APBDMA_CSR_REQ_SEL_MASK) {
1268 dev_err(tdma->dev, "Invalid slave id: %d\n", dma_spec->args[0]);
1269 return NULL;
1270 }
1271
Stephen Warren996556c2013-11-11 13:09:35 -07001272 chan = dma_get_any_slave_channel(&tdma->dma_dev);
1273 if (!chan)
1274 return NULL;
1275
1276 tdc = to_tegra_dma_chan(chan);
1277 tdc->slave_id = dma_spec->args[0];
1278
1279 return chan;
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301280}
1281
1282/* Tegra20 specific DMA controller information */
Laxman Dewangan75f21632012-08-29 10:31:18 +02001283static const struct tegra_dma_chip_data tegra20_dma_chip_data = {
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301284 .nr_channels = 16,
Laxman Dewangan911dacc2014-01-06 11:16:45 -07001285 .channel_reg_size = 0x20,
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301286 .max_dma_count = 1024UL * 64,
Laxman Dewangan1b140902013-01-06 21:52:02 +05301287 .support_channel_pause = false,
Laxman Dewangan911dacc2014-01-06 11:16:45 -07001288 .support_separate_wcount_reg = false,
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301289};
1290
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301291/* Tegra30 specific DMA controller information */
Laxman Dewangan75f21632012-08-29 10:31:18 +02001292static const struct tegra_dma_chip_data tegra30_dma_chip_data = {
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301293 .nr_channels = 32,
Laxman Dewangan911dacc2014-01-06 11:16:45 -07001294 .channel_reg_size = 0x20,
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301295 .max_dma_count = 1024UL * 64,
Laxman Dewangan1b140902013-01-06 21:52:02 +05301296 .support_channel_pause = false,
Laxman Dewangan911dacc2014-01-06 11:16:45 -07001297 .support_separate_wcount_reg = false,
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301298};
1299
Laxman Dewangan5ea7caf2013-01-06 21:52:03 +05301300/* Tegra114 specific DMA controller information */
1301static const struct tegra_dma_chip_data tegra114_dma_chip_data = {
1302 .nr_channels = 32,
Laxman Dewangan911dacc2014-01-06 11:16:45 -07001303 .channel_reg_size = 0x20,
Laxman Dewangan5ea7caf2013-01-06 21:52:03 +05301304 .max_dma_count = 1024UL * 64,
1305 .support_channel_pause = true,
Laxman Dewangan911dacc2014-01-06 11:16:45 -07001306 .support_separate_wcount_reg = false,
1307};
1308
1309/* Tegra148 specific DMA controller information */
1310static const struct tegra_dma_chip_data tegra148_dma_chip_data = {
1311 .nr_channels = 32,
1312 .channel_reg_size = 0x40,
1313 .max_dma_count = 1024UL * 64,
1314 .support_channel_pause = true,
1315 .support_separate_wcount_reg = true,
Laxman Dewangan5ea7caf2013-01-06 21:52:03 +05301316};
1317
Bill Pemberton463a1f82012-11-19 13:22:55 -05001318static int tegra_dma_probe(struct platform_device *pdev)
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301319{
Thierry Reding7b0e00d2016-06-14 16:18:46 +02001320 struct resource *res;
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301321 struct tegra_dma *tdma;
1322 int ret;
1323 int i;
Laxman Dewangan333f16e2016-03-01 18:54:40 +05301324 const struct tegra_dma_chip_data *cdata;
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301325
Laxman Dewangan333f16e2016-03-01 18:54:40 +05301326 cdata = of_device_get_match_data(&pdev->dev);
1327 if (!cdata) {
1328 dev_err(&pdev->dev, "Error: No device match data found\n");
Stephen Warrendc7badb2013-03-11 16:30:26 -06001329 return -ENODEV;
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301330 }
1331
Gustavo A. R. Silvad3d70372019-01-04 15:16:12 -06001332 tdma = devm_kzalloc(&pdev->dev,
1333 struct_size(tdma, channels, cdata->nr_channels),
1334 GFP_KERNEL);
Peter Griffinaef94fe2016-06-07 18:38:41 +01001335 if (!tdma)
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301336 return -ENOMEM;
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301337
1338 tdma->dev = &pdev->dev;
1339 tdma->chip_data = cdata;
1340 platform_set_drvdata(pdev, tdma);
1341
1342 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
Thierry Reding73312052013-01-21 11:09:00 +01001343 tdma->base_addr = devm_ioremap_resource(&pdev->dev, res);
1344 if (IS_ERR(tdma->base_addr))
1345 return PTR_ERR(tdma->base_addr);
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301346
1347 tdma->dma_clk = devm_clk_get(&pdev->dev, NULL);
1348 if (IS_ERR(tdma->dma_clk)) {
1349 dev_err(&pdev->dev, "Error: Missing controller clock\n");
1350 return PTR_ERR(tdma->dma_clk);
1351 }
1352
Stephen Warren9aa433d2013-11-06 16:35:34 -07001353 tdma->rst = devm_reset_control_get(&pdev->dev, "dma");
1354 if (IS_ERR(tdma->rst)) {
1355 dev_err(&pdev->dev, "Error: Missing reset\n");
1356 return PTR_ERR(tdma->rst);
1357 }
1358
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301359 spin_lock_init(&tdma->global_lock);
1360
1361 pm_runtime_enable(&pdev->dev);
Jon Hunteredd3bdb2015-11-13 16:39:38 +00001362 if (!pm_runtime_enabled(&pdev->dev))
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301363 ret = tegra_dma_runtime_resume(&pdev->dev);
Jon Hunteredd3bdb2015-11-13 16:39:38 +00001364 else
1365 ret = pm_runtime_get_sync(&pdev->dev);
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301366
Laxman Dewanganffc49302012-07-20 13:31:08 +05301367 if (ret < 0) {
Jon Hunteredd3bdb2015-11-13 16:39:38 +00001368 pm_runtime_disable(&pdev->dev);
1369 return ret;
Laxman Dewanganffc49302012-07-20 13:31:08 +05301370 }
1371
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301372 /* Reset DMA controller */
Stephen Warren9aa433d2013-11-06 16:35:34 -07001373 reset_control_assert(tdma->rst);
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301374 udelay(2);
Stephen Warren9aa433d2013-11-06 16:35:34 -07001375 reset_control_deassert(tdma->rst);
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301376
1377 /* Enable global DMA registers */
1378 tdma_write(tdma, TEGRA_APBDMA_GENERAL, TEGRA_APBDMA_GENERAL_ENABLE);
1379 tdma_write(tdma, TEGRA_APBDMA_CONTROL, 0);
1380 tdma_write(tdma, TEGRA_APBDMA_IRQ_MASK_SET, 0xFFFFFFFFul);
1381
Jon Hunteredd3bdb2015-11-13 16:39:38 +00001382 pm_runtime_put(&pdev->dev);
Laxman Dewanganffc49302012-07-20 13:31:08 +05301383
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301384 INIT_LIST_HEAD(&tdma->dma_dev.channels);
1385 for (i = 0; i < cdata->nr_channels; i++) {
1386 struct tegra_dma_channel *tdc = &tdma->channels[i];
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301387
Jon Hunter13a33282015-08-06 14:32:31 +01001388 tdc->chan_addr = tdma->base_addr +
1389 TEGRA_APBDMA_CHANNEL_BASE_ADD_OFFSET +
1390 (i * cdata->channel_reg_size);
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301391
1392 res = platform_get_resource(pdev, IORESOURCE_IRQ, i);
1393 if (!res) {
1394 ret = -EINVAL;
1395 dev_err(&pdev->dev, "No irq resource for chan %d\n", i);
1396 goto err_irq;
1397 }
1398 tdc->irq = res->start;
Laxman Dewangand0fc9052012-10-03 22:48:07 +05301399 snprintf(tdc->name, sizeof(tdc->name), "apbdma.%d", i);
Jon Hunter05e866b2015-11-13 16:39:43 +00001400 ret = request_irq(tdc->irq, tegra_dma_isr, 0, tdc->name, tdc);
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301401 if (ret) {
1402 dev_err(&pdev->dev,
1403 "request_irq failed with err %d channel %d\n",
Dmitry Osipenkoac7ae752013-05-11 20:30:52 +04001404 ret, i);
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301405 goto err_irq;
1406 }
1407
1408 tdc->dma_chan.device = &tdma->dma_dev;
1409 dma_cookie_init(&tdc->dma_chan);
1410 list_add_tail(&tdc->dma_chan.device_node,
1411 &tdma->dma_dev.channels);
1412 tdc->tdma = tdma;
1413 tdc->id = i;
Shardar Shariff Md00ef4492016-04-23 15:06:00 +05301414 tdc->slave_id = TEGRA_APBDMA_SLAVE_ID_INVALID;
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301415
1416 tasklet_init(&tdc->tasklet, tegra_dma_tasklet,
1417 (unsigned long)tdc);
1418 spin_lock_init(&tdc->lock);
1419
1420 INIT_LIST_HEAD(&tdc->pending_sg_req);
1421 INIT_LIST_HEAD(&tdc->free_sg_req);
1422 INIT_LIST_HEAD(&tdc->free_dma_desc);
1423 INIT_LIST_HEAD(&tdc->cb_desc);
1424 }
1425
1426 dma_cap_set(DMA_SLAVE, tdma->dma_dev.cap_mask);
1427 dma_cap_set(DMA_PRIVATE, tdma->dma_dev.cap_mask);
Laxman Dewangan46fb3f82012-06-22 17:12:43 +05301428 dma_cap_set(DMA_CYCLIC, tdma->dma_dev.cap_mask);
1429
Jon Hunter23a1ec32015-08-06 14:32:33 +01001430 tdma->global_pause_count = 0;
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301431 tdma->dma_dev.dev = &pdev->dev;
1432 tdma->dma_dev.device_alloc_chan_resources =
1433 tegra_dma_alloc_chan_resources;
1434 tdma->dma_dev.device_free_chan_resources =
1435 tegra_dma_free_chan_resources;
1436 tdma->dma_dev.device_prep_slave_sg = tegra_dma_prep_slave_sg;
1437 tdma->dma_dev.device_prep_dma_cyclic = tegra_dma_prep_dma_cyclic;
Paul Walmsley891653a2015-01-06 06:44:56 +00001438 tdma->dma_dev.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
1439 BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
1440 BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) |
1441 BIT(DMA_SLAVE_BUSWIDTH_8_BYTES);
1442 tdma->dma_dev.dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
1443 BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
1444 BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) |
1445 BIT(DMA_SLAVE_BUSWIDTH_8_BYTES);
1446 tdma->dma_dev.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
1447 /*
1448 * XXX The hardware appears to support
1449 * DMA_RESIDUE_GRANULARITY_BURST-level reporting, but it's
1450 * only used by this driver during tegra_dma_terminate_all()
1451 */
1452 tdma->dma_dev.residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT;
Maxime Ripard662f1ac2014-11-17 14:42:37 +01001453 tdma->dma_dev.device_config = tegra_dma_slave_config;
1454 tdma->dma_dev.device_terminate_all = tegra_dma_terminate_all;
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301455 tdma->dma_dev.device_tx_status = tegra_dma_tx_status;
1456 tdma->dma_dev.device_issue_pending = tegra_dma_issue_pending;
1457
1458 ret = dma_async_device_register(&tdma->dma_dev);
1459 if (ret < 0) {
1460 dev_err(&pdev->dev,
1461 "Tegra20 APB DMA driver registration failed %d\n", ret);
1462 goto err_irq;
1463 }
1464
Stephen Warren996556c2013-11-11 13:09:35 -07001465 ret = of_dma_controller_register(pdev->dev.of_node,
1466 tegra_dma_of_xlate, tdma);
1467 if (ret < 0) {
1468 dev_err(&pdev->dev,
1469 "Tegra20 APB DMA OF registration failed %d\n", ret);
1470 goto err_unregister_dma_dev;
1471 }
1472
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301473 dev_info(&pdev->dev, "Tegra20 APB DMA driver register %d channels\n",
1474 cdata->nr_channels);
1475 return 0;
1476
Stephen Warren996556c2013-11-11 13:09:35 -07001477err_unregister_dma_dev:
1478 dma_async_device_unregister(&tdma->dma_dev);
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301479err_irq:
1480 while (--i >= 0) {
1481 struct tegra_dma_channel *tdc = &tdma->channels[i];
Jon Hunter05e866b2015-11-13 16:39:43 +00001482
1483 free_irq(tdc->irq, tdc);
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301484 tasklet_kill(&tdc->tasklet);
1485 }
1486
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301487 pm_runtime_disable(&pdev->dev);
1488 if (!pm_runtime_status_suspended(&pdev->dev))
1489 tegra_dma_runtime_suspend(&pdev->dev);
1490 return ret;
1491}
1492
Greg Kroah-Hartman4bf27b82012-12-21 15:09:59 -08001493static int tegra_dma_remove(struct platform_device *pdev)
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301494{
1495 struct tegra_dma *tdma = platform_get_drvdata(pdev);
1496 int i;
1497 struct tegra_dma_channel *tdc;
1498
1499 dma_async_device_unregister(&tdma->dma_dev);
1500
1501 for (i = 0; i < tdma->chip_data->nr_channels; ++i) {
1502 tdc = &tdma->channels[i];
Jon Hunter05e866b2015-11-13 16:39:43 +00001503 free_irq(tdc->irq, tdc);
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301504 tasklet_kill(&tdc->tasklet);
1505 }
1506
1507 pm_runtime_disable(&pdev->dev);
1508 if (!pm_runtime_status_suspended(&pdev->dev))
1509 tegra_dma_runtime_suspend(&pdev->dev);
1510
1511 return 0;
1512}
1513
1514static int tegra_dma_runtime_suspend(struct device *dev)
1515{
Jon Hunter286a6442015-11-13 16:39:39 +00001516 struct tegra_dma *tdma = dev_get_drvdata(dev);
Laxman Dewangan3065c192013-04-24 15:24:27 +05301517 int i;
Laxman Dewangan3065c192013-04-24 15:24:27 +05301518
1519 tdma->reg_gen = tdma_read(tdma, TEGRA_APBDMA_GENERAL);
1520 for (i = 0; i < tdma->chip_data->nr_channels; i++) {
1521 struct tegra_dma_channel *tdc = &tdma->channels[i];
1522 struct tegra_dma_channel_regs *ch_reg = &tdc->channel_reg;
1523
Jon Hunter4aad5be2015-11-13 16:39:41 +00001524 /* Only save the state of DMA channels that are in use */
1525 if (!tdc->config_init)
1526 continue;
1527
Laxman Dewangan3065c192013-04-24 15:24:27 +05301528 ch_reg->csr = tdc_read(tdc, TEGRA_APBDMA_CHAN_CSR);
1529 ch_reg->ahb_ptr = tdc_read(tdc, TEGRA_APBDMA_CHAN_AHBPTR);
1530 ch_reg->apb_ptr = tdc_read(tdc, TEGRA_APBDMA_CHAN_APBPTR);
1531 ch_reg->ahb_seq = tdc_read(tdc, TEGRA_APBDMA_CHAN_AHBSEQ);
1532 ch_reg->apb_seq = tdc_read(tdc, TEGRA_APBDMA_CHAN_APBSEQ);
Jon Hunter68ae7a92015-11-13 16:39:40 +00001533 if (tdma->chip_data->support_separate_wcount_reg)
1534 ch_reg->wcount = tdc_read(tdc,
1535 TEGRA_APBDMA_CHAN_WCOUNT);
Laxman Dewangan3065c192013-04-24 15:24:27 +05301536 }
1537
Jon Hunter65a5c3d2017-06-06 13:49:29 +01001538 clk_disable_unprepare(tdma->dma_clk);
1539
Laxman Dewangan3065c192013-04-24 15:24:27 +05301540 return 0;
1541}
1542
Jon Hunter65a5c3d2017-06-06 13:49:29 +01001543static int tegra_dma_runtime_resume(struct device *dev)
Laxman Dewangan3065c192013-04-24 15:24:27 +05301544{
1545 struct tegra_dma *tdma = dev_get_drvdata(dev);
Jon Hunter65a5c3d2017-06-06 13:49:29 +01001546 int i, ret;
Laxman Dewangan3065c192013-04-24 15:24:27 +05301547
Jon Hunter65a5c3d2017-06-06 13:49:29 +01001548 ret = clk_prepare_enable(tdma->dma_clk);
1549 if (ret < 0) {
1550 dev_err(dev, "clk_enable failed: %d\n", ret);
Laxman Dewangan3065c192013-04-24 15:24:27 +05301551 return ret;
Jon Hunter65a5c3d2017-06-06 13:49:29 +01001552 }
Laxman Dewangan3065c192013-04-24 15:24:27 +05301553
1554 tdma_write(tdma, TEGRA_APBDMA_GENERAL, tdma->reg_gen);
1555 tdma_write(tdma, TEGRA_APBDMA_CONTROL, 0);
1556 tdma_write(tdma, TEGRA_APBDMA_IRQ_MASK_SET, 0xFFFFFFFFul);
1557
1558 for (i = 0; i < tdma->chip_data->nr_channels; i++) {
1559 struct tegra_dma_channel *tdc = &tdma->channels[i];
1560 struct tegra_dma_channel_regs *ch_reg = &tdc->channel_reg;
1561
Jon Hunter4aad5be2015-11-13 16:39:41 +00001562 /* Only restore the state of DMA channels that are in use */
1563 if (!tdc->config_init)
1564 continue;
1565
Jon Hunter68ae7a92015-11-13 16:39:40 +00001566 if (tdma->chip_data->support_separate_wcount_reg)
1567 tdc_write(tdc, TEGRA_APBDMA_CHAN_WCOUNT,
1568 ch_reg->wcount);
Laxman Dewangan3065c192013-04-24 15:24:27 +05301569 tdc_write(tdc, TEGRA_APBDMA_CHAN_APBSEQ, ch_reg->apb_seq);
1570 tdc_write(tdc, TEGRA_APBDMA_CHAN_APBPTR, ch_reg->apb_ptr);
1571 tdc_write(tdc, TEGRA_APBDMA_CHAN_AHBSEQ, ch_reg->ahb_seq);
1572 tdc_write(tdc, TEGRA_APBDMA_CHAN_AHBPTR, ch_reg->ahb_ptr);
1573 tdc_write(tdc, TEGRA_APBDMA_CHAN_CSR,
1574 (ch_reg->csr & ~TEGRA_APBDMA_CSR_ENB));
1575 }
1576
Laxman Dewangan3065c192013-04-24 15:24:27 +05301577 return 0;
1578}
Laxman Dewangan3065c192013-04-24 15:24:27 +05301579
Greg Kroah-Hartman4bf27b82012-12-21 15:09:59 -08001580static const struct dev_pm_ops tegra_dma_dev_pm_ops = {
Jon Hunteredd3bdb2015-11-13 16:39:38 +00001581 SET_RUNTIME_PM_OPS(tegra_dma_runtime_suspend, tegra_dma_runtime_resume,
1582 NULL)
Jon Hunter65a5c3d2017-06-06 13:49:29 +01001583 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
1584 pm_runtime_force_resume)
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301585};
1586
Laxman Dewangan242637b2016-03-04 15:55:11 +05301587static const struct of_device_id tegra_dma_of_match[] = {
1588 {
1589 .compatible = "nvidia,tegra148-apbdma",
1590 .data = &tegra148_dma_chip_data,
1591 }, {
1592 .compatible = "nvidia,tegra114-apbdma",
1593 .data = &tegra114_dma_chip_data,
1594 }, {
1595 .compatible = "nvidia,tegra30-apbdma",
1596 .data = &tegra30_dma_chip_data,
1597 }, {
1598 .compatible = "nvidia,tegra20-apbdma",
1599 .data = &tegra20_dma_chip_data,
1600 }, {
1601 },
1602};
1603MODULE_DEVICE_TABLE(of, tegra_dma_of_match);
1604
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301605static struct platform_driver tegra_dmac_driver = {
1606 .driver = {
Laxman Dewangancd9092c2012-07-02 13:52:08 +05301607 .name = "tegra-apbdma",
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301608 .pm = &tegra_dma_dev_pm_ops,
Stephen Warrendc7badb2013-03-11 16:30:26 -06001609 .of_match_table = tegra_dma_of_match,
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301610 },
1611 .probe = tegra_dma_probe,
Bill Pembertona7d6e3e2012-11-19 13:20:04 -05001612 .remove = tegra_dma_remove,
Laxman Dewanganec8a1582012-06-06 10:55:27 +05301613};
1614
1615module_platform_driver(tegra_dmac_driver);
1616
1617MODULE_ALIAS("platform:tegra20-apbdma");
1618MODULE_DESCRIPTION("NVIDIA Tegra APB DMA Controller driver");
1619MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
1620MODULE_LICENSE("GPL v2");