blob: abdcabc8cdddcef41a2a52601b0e57771b5f548d [file] [log] [blame]
Yan Heaabe3fc2016-11-14 17:04:53 -08001/* Copyright (c) 2011-2013, 2015, 2017, The Linux Foundation. All rights
2 * reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14/* BAM-DMA Manager. */
15
16#ifdef CONFIG_SPS_SUPPORT_BAMDMA
17
18#include <linux/export.h>
19#include <linux/memory.h> /* memset */
20
21#include "spsi.h"
22#include "bam.h"
23#include "sps_bam.h" /* bam_dma_thresh_dma */
24#include "sps_core.h" /* sps_h2bam() */
25
26/**
27 * registers
28 */
29
30#define DMA_ENBL (0x00000000)
31#ifdef CONFIG_SPS_SUPPORT_NDP_BAM
32#define DMA_REVISION (0x00000004)
33#define DMA_CONFIG (0x00000008)
34#define DMA_CHNL_CONFIG(n) (0x00001000 + 4096 * (n))
35#else
36#define DMA_CHNL_CONFIG(n) (0x00000004 + 4 * (n))
37#define DMA_CONFIG (0x00000040)
38#endif
39
40/**
41 * masks
42 */
43
44/* DMA_CHNL_confign */
45#ifdef CONFIG_SPS_SUPPORT_NDP_BAM
46#define DMA_CHNL_PRODUCER_PIPE_ENABLED 0x40000
47#define DMA_CHNL_CONSUMER_PIPE_ENABLED 0x20000
48#endif
49#define DMA_CHNL_HALT_DONE 0x10000
50#define DMA_CHNL_HALT 0x1000
51#define DMA_CHNL_ENABLE 0x100
52#define DMA_CHNL_ACT_THRESH 0x30
53#define DMA_CHNL_WEIGHT 0x7
54
55/* DMA_CONFIG */
56#define TESTBUS_SELECT 0x3
57
58/**
59 *
60 * Write register with debug info.
61 *
62 * @base - bam base virtual address.
63 * @offset - register offset.
64 * @val - value to write.
65 *
66 */
67static inline void dma_write_reg(void *base, u32 offset, u32 val)
68{
69 iowrite32(val, base + offset);
70 SPS_DBG(sps, "sps:bamdma: write reg 0x%x w_val 0x%x.", offset, val);
71}
72
73/**
74 * Write register masked field with debug info.
75 *
76 * @base - bam base virtual address.
77 * @offset - register offset.
78 * @mask - register bitmask.
79 * @val - value to write.
80 *
81 */
82static inline void dma_write_reg_field(void *base, u32 offset,
83 const u32 mask, u32 val)
84{
85 u32 shift = find_first_bit((void *)&mask, 32);
86 u32 tmp = ioread32(base + offset);
87
88 tmp &= ~mask; /* clear written bits */
89 val = tmp | (val << shift);
90 iowrite32(val, base + offset);
91 SPS_DBG(sps, "sps:bamdma: write reg 0x%x w_val 0x%x.", offset, val);
92}
93
94/* Round max number of pipes to nearest multiple of 2 */
95#define DMA_MAX_PIPES ((BAM_MAX_PIPES / 2) * 2)
96
97/* Maximum number of BAM-DMAs supported */
98#define MAX_BAM_DMA_DEVICES 1
99
100/* Maximum number of BAMs that will be registered */
101#define MAX_BAM_DMA_BAMS 1
102
103/* Pipe enable check values */
104#define DMA_PIPES_STATE_DIFF 0
105#define DMA_PIPES_BOTH_DISABLED 1
106#define DMA_PIPES_BOTH_ENABLED 2
107
108/* Even pipe is tx/dest/input/write, odd pipe is rx/src/output/read */
109#define DMA_PIPE_IS_DEST(p) (((p) & 1) == 0)
110#define DMA_PIPE_IS_SRC(p) (((p) & 1) != 0)
111
112/* BAM DMA pipe state */
113enum bamdma_pipe_state {
114 PIPE_INACTIVE = 0,
115 PIPE_ACTIVE
116};
117
118/* BAM DMA channel state */
119enum bamdma_chan_state {
120 DMA_CHAN_STATE_FREE = 0,
121 DMA_CHAN_STATE_ALLOC_EXT, /* Client allocation */
122 DMA_CHAN_STATE_ALLOC_INT /* Internal (resource mgr) allocation */
123};
124
125struct bamdma_chan {
126 /* Allocation state */
127 enum bamdma_chan_state state;
128
129 /* BAM DMA channel configuration parameters */
130 u32 threshold;
131 enum sps_dma_priority priority;
132
133 /* HWIO channel configuration parameters */
134 enum bam_dma_thresh_dma thresh;
135 enum bam_dma_weight_dma weight;
136
137};
138
139/* BAM DMA device state */
140struct bamdma_device {
141 /* BAM-DMA device state */
142 int enabled;
143 int local;
144
145 /* BAM device state */
146 struct sps_bam *bam;
147
148 /* BAM handle, for deregistration */
149 unsigned long h;
150
151 /* BAM DMA device virtual mapping */
152 void *virt_addr;
153 int virtual_mapped;
154 phys_addr_t phys_addr;
155 void *hwio;
156
157 /* BAM DMA pipe/channel state */
158 u32 num_pipes;
159 enum bamdma_pipe_state pipes[DMA_MAX_PIPES];
160 struct bamdma_chan chans[DMA_MAX_PIPES / 2];
161
162};
163
164/* BAM-DMA devices */
165static struct bamdma_device bam_dma_dev[MAX_BAM_DMA_DEVICES];
166static struct mutex bam_dma_lock;
167
168/*
169 * The BAM DMA module registers all BAMs in the BSP properties, but only
170 * uses the first BAM-DMA device for allocations. References to the others
171 * are stored in the following data array.
172 */
173static int num_bams;
174static unsigned long bam_handles[MAX_BAM_DMA_BAMS];
175
176/**
177 * Find BAM-DMA device
178 *
179 * This function finds the BAM-DMA device associated with the BAM handle.
180 *
181 * @h - BAM handle
182 *
183 * @return - pointer to BAM-DMA device, or NULL on error
184 *
185 */
186static struct bamdma_device *sps_dma_find_device(unsigned long h)
187{
188 return &bam_dma_dev[0];
189}
190
191/**
192 * BAM DMA device enable
193 *
194 * This function enables a BAM DMA device and the associated BAM.
195 *
196 * @dev - pointer to BAM DMA device context
197 *
198 * @return 0 on success, negative value on error
199 *
200 */
201static int sps_dma_device_enable(struct bamdma_device *dev)
202{
203 if (dev->enabled)
204 return 0;
205
206 /*
207 * If the BAM-DMA device is locally controlled then enable BAM-DMA
208 * device
209 */
210 if (dev->local)
211 dma_write_reg(dev->virt_addr, DMA_ENBL, 1);
212
213 /* Enable BAM device */
214 if (sps_bam_enable(dev->bam)) {
215 SPS_ERR(sps, "sps:Failed to enable BAM DMA's BAM: %pa",
216 &dev->phys_addr);
217 return SPS_ERROR;
218 }
219
220 dev->enabled = true;
221
222 return 0;
223}
224
225/**
226 * BAM DMA device enable
227 *
228 * This function initializes a BAM DMA device.
229 *
230 * @dev - pointer to BAM DMA device context
231 *
232 * @return 0 on success, negative value on error
233 *
234 */
235static int sps_dma_device_disable(struct bamdma_device *dev)
236{
237 u32 pipe_index;
238
239 if (!dev->enabled)
240 return 0;
241
242 /* Do not disable if channels active */
243 for (pipe_index = 0; pipe_index < dev->num_pipes; pipe_index++) {
244 if (dev->pipes[pipe_index] != PIPE_INACTIVE)
245 break;
246 }
247
248 if (pipe_index < dev->num_pipes) {
249 SPS_ERR(sps,
250 "sps:Fail to disable BAM-DMA %pa:channels are active",
251 &dev->phys_addr);
252 return SPS_ERROR;
253 }
254
255 dev->enabled = false;
256
257 /* Disable BAM device */
258 if (sps_bam_disable(dev->bam)) {
259 SPS_ERR(sps,
260 "sps:Fail to disable BAM-DMA BAM:%pa", &dev->phys_addr);
261 return SPS_ERROR;
262 }
263
264 /* Is the BAM-DMA device locally controlled? */
265 if (dev->local)
266 /* Disable BAM-DMA device */
267 dma_write_reg(dev->virt_addr, DMA_ENBL, 0);
268
269 return 0;
270}
271
272/**
273 * Initialize BAM DMA device
274 *
275 */
276int sps_dma_device_init(unsigned long h)
277{
278 struct bamdma_device *dev;
279 struct sps_bam_props *props;
280 int result = SPS_ERROR;
281
282 mutex_lock(&bam_dma_lock);
283
284 /* Find a free BAM-DMA device slot */
285 dev = NULL;
286 if (bam_dma_dev[0].bam != NULL) {
287 SPS_ERR(sps,
288 "sps:%s:BAM-DMA BAM device is already initialized.",
289 __func__);
290 goto exit_err;
291 } else {
292 dev = &bam_dma_dev[0];
293 }
294
295 /* Record BAM */
296 memset(dev, 0, sizeof(*dev));
297 dev->h = h;
298 dev->bam = sps_h2bam(h);
299
300 if (dev->bam == NULL) {
301 SPS_ERR(sps,
302 "sps:%s:BAM-DMA BAM device is not found from the handle.",
303 __func__);
304 goto exit_err;
305 }
306
307 /* Map the BAM DMA device into virtual space, if necessary */
308 props = &dev->bam->props;
309 dev->phys_addr = props->periph_phys_addr;
310 if (props->periph_virt_addr != NULL) {
311 dev->virt_addr = props->periph_virt_addr;
312 dev->virtual_mapped = false;
313 } else {
314 if (props->periph_virt_size == 0) {
315 SPS_ERR(sps,
316 "sps:Unable to map BAM DMA IO memory: %pa %x",
317 &dev->phys_addr, props->periph_virt_size);
318 goto exit_err;
319 }
320
321 dev->virt_addr = ioremap(dev->phys_addr,
322 props->periph_virt_size);
323 if (dev->virt_addr == NULL) {
324 SPS_ERR(sps,
325 "sps:Unable to map BAM DMA IO memory: %pa %x",
326 &dev->phys_addr, props->periph_virt_size);
327 goto exit_err;
328 }
329 dev->virtual_mapped = true;
330 }
331 dev->hwio = (void *) dev->virt_addr;
332
333 /* Is the BAM-DMA device locally controlled? */
334 if ((props->manage & SPS_BAM_MGR_DEVICE_REMOTE) == 0) {
335 SPS_DBG3(sps, "sps:BAM-DMA is controlled locally: %pa",
336 &dev->phys_addr);
337 dev->local = true;
338 } else {
339 SPS_DBG3(sps, "sps:BAM-DMA is controlled remotely: %pa",
340 &dev->phys_addr);
341 dev->local = false;
342 }
343
344 /*
345 * Enable the BAM DMA and determine the number of pipes/channels.
346 * Leave the BAM-DMA enabled, since it is always a shared device.
347 */
348 if (sps_dma_device_enable(dev))
349 goto exit_err;
350
351 dev->num_pipes = dev->bam->props.num_pipes;
352
353 result = 0;
354exit_err:
355 if (result) {
356 if (dev != NULL) {
357 if (dev->virtual_mapped)
358 iounmap(dev->virt_addr);
359
360 dev->bam = NULL;
361 }
362 }
363
364 mutex_unlock(&bam_dma_lock);
365
366 return result;
367}
368
369/**
370 * De-initialize BAM DMA device
371 *
372 */
373int sps_dma_device_de_init(unsigned long h)
374{
375 struct bamdma_device *dev;
376 u32 pipe_index;
377 u32 chan;
378 int result = 0;
379
380 mutex_lock(&bam_dma_lock);
381
382 dev = sps_dma_find_device(h);
383 if (dev == NULL) {
384 SPS_ERR(sps, "sps:BAM-DMA: not registered: %lx", h);
385 result = SPS_ERROR;
386 goto exit_err;
387 }
388
389 /* Check for channel leaks */
390 for (chan = 0; chan < dev->num_pipes / 2; chan++) {
391 if (dev->chans[chan].state != DMA_CHAN_STATE_FREE) {
392 SPS_ERR(sps, "sps:BAM-DMA: channel not free: %d", chan);
393 result = SPS_ERROR;
394 dev->chans[chan].state = DMA_CHAN_STATE_FREE;
395 }
396 }
397 for (pipe_index = 0; pipe_index < dev->num_pipes; pipe_index++) {
398 if (dev->pipes[pipe_index] != PIPE_INACTIVE) {
399 SPS_ERR(sps, "sps:BAM-DMA: pipe not inactive: %d",
400 pipe_index);
401 result = SPS_ERROR;
402 dev->pipes[pipe_index] = PIPE_INACTIVE;
403 }
404 }
405
406 /* Disable BAM and BAM-DMA */
407 if (sps_dma_device_disable(dev))
408 result = SPS_ERROR;
409
410 dev->h = BAM_HANDLE_INVALID;
411 dev->bam = NULL;
412 if (dev->virtual_mapped)
413 iounmap(dev->virt_addr);
414
415exit_err:
416 mutex_unlock(&bam_dma_lock);
417
418 return result;
419}
420
421/**
422 * Initialize BAM DMA module
423 *
424 */
425int sps_dma_init(const struct sps_bam_props *bam_props)
426{
427 struct sps_bam_props props;
428 const struct sps_bam_props *bam_reg;
429 unsigned long h;
430
431 /* Init local data */
432 memset(&bam_dma_dev, 0, sizeof(bam_dma_dev));
433 num_bams = 0;
434 memset(bam_handles, 0, sizeof(bam_handles));
435
436 /* Create a mutex to control access to the BAM-DMA devices */
437 mutex_init(&bam_dma_lock);
438
439 /* Are there any BAM DMA devices? */
440 if (bam_props == NULL)
441 return 0;
442
443 /*
444 * Registers all BAMs in the BSP properties, but only uses the first
445 * BAM-DMA device for allocations.
446 */
447 if (bam_props->phys_addr) {
448 /* Force multi-EE option for all BAM-DMAs */
449 bam_reg = bam_props;
450 if ((bam_props->options & SPS_BAM_OPT_BAMDMA) &&
451 (bam_props->manage & SPS_BAM_MGR_MULTI_EE) == 0) {
452 SPS_DBG(sps,
453 "sps:Setting multi-EE options for BAM-DMA: %pa",
454 &bam_props->phys_addr);
455 props = *bam_props;
456 props.manage |= SPS_BAM_MGR_MULTI_EE;
457 bam_reg = &props;
458 }
459
460 /* Register the BAM */
461 if (sps_register_bam_device(bam_reg, &h)) {
462 SPS_ERR(sps,
463 "sps:Fail to register BAM-DMA BAM device: phys %pa",
464 &bam_props->phys_addr);
465 return SPS_ERROR;
466 }
467
468 /* Record the BAM so that it may be deregistered later */
469 if (num_bams < MAX_BAM_DMA_BAMS) {
470 bam_handles[num_bams] = h;
471 num_bams++;
472 } else {
473 SPS_ERR(sps, "sps:BAM-DMA: BAM limit exceeded: %d",
474 num_bams);
475 return SPS_ERROR;
476 }
477 } else {
478 SPS_ERR(sps,
479 "sps:%s:BAM-DMA phys_addr is zero.",
480 __func__);
481 return SPS_ERROR;
482 }
483
484
485 return 0;
486}
487
488/**
489 * De-initialize BAM DMA module
490 *
491 */
492void sps_dma_de_init(void)
493{
494 int n;
495
496 /* De-initialize the BAM devices */
497 for (n = 0; n < num_bams; n++)
498 sps_deregister_bam_device(bam_handles[n]);
499
500 /* Clear local data */
501 memset(&bam_dma_dev, 0, sizeof(bam_dma_dev));
502 num_bams = 0;
503 memset(bam_handles, 0, sizeof(bam_handles));
504}
505
506/**
507 * Allocate a BAM DMA channel
508 *
509 */
510int sps_alloc_dma_chan(const struct sps_alloc_dma_chan *alloc,
511 struct sps_dma_chan *chan_info)
512{
513 struct bamdma_device *dev;
514 struct bamdma_chan *chan;
515 u32 pipe_index;
516 enum bam_dma_thresh_dma thresh = (enum bam_dma_thresh_dma) 0;
517 enum bam_dma_weight_dma weight = (enum bam_dma_weight_dma) 0;
518 int result = SPS_ERROR;
519
520 if (alloc == NULL || chan_info == NULL) {
521 SPS_ERR(sps,
522 "sps:%s:invalid parameters", __func__);
523 return SPS_ERROR;
524 }
525
526 /* Translate threshold and priority to hwio values */
527 if (alloc->threshold != SPS_DMA_THRESHOLD_DEFAULT) {
528 if (alloc->threshold >= 512)
529 thresh = BAM_DMA_THRESH_512;
530 else if (alloc->threshold >= 256)
531 thresh = BAM_DMA_THRESH_256;
532 else if (alloc->threshold >= 128)
533 thresh = BAM_DMA_THRESH_128;
534 else
535 thresh = BAM_DMA_THRESH_64;
536 }
537
538 weight = alloc->priority;
539
540 if ((u32)alloc->priority > (u32)BAM_DMA_WEIGHT_HIGH) {
541 SPS_ERR(sps, "sps:BAM-DMA: invalid priority: %x",
542 alloc->priority);
543 return SPS_ERROR;
544 }
545
546 mutex_lock(&bam_dma_lock);
547
548 dev = sps_dma_find_device(alloc->dev);
549 if (dev == NULL) {
550 SPS_ERR(sps, "sps:BAM-DMA: invalid BAM handle: %lx",
551 alloc->dev);
552 goto exit_err;
553 }
554
555 /* Search for a free set of pipes */
556 for (pipe_index = 0, chan = dev->chans;
557 pipe_index < dev->num_pipes; pipe_index += 2, chan++) {
558 if (chan->state == DMA_CHAN_STATE_FREE) {
559 /* Just check pipes for safety */
560 if (dev->pipes[pipe_index] != PIPE_INACTIVE ||
561 dev->pipes[pipe_index + 1] != PIPE_INACTIVE) {
562 SPS_ERR(sps,
563 "sps:BAM-DMA: channel %d state error:%d %d",
564 pipe_index / 2, dev->pipes[pipe_index],
565 dev->pipes[pipe_index + 1]);
566 goto exit_err;
567 }
568 break; /* Found free pipe */
569 }
570 }
571
572 if (pipe_index >= dev->num_pipes) {
573 SPS_ERR(sps, "sps:BAM-DMA: no free channel. num_pipes = %d",
574 dev->num_pipes);
575 goto exit_err;
576 }
577
578 chan->state = DMA_CHAN_STATE_ALLOC_EXT;
579
580 /* Store config values for use when pipes are activated */
581 chan = &dev->chans[pipe_index / 2];
582 chan->threshold = alloc->threshold;
583 chan->thresh = thresh;
584 chan->priority = alloc->priority;
585 chan->weight = weight;
586
587 SPS_DBG3(sps, "sps:sps_alloc_dma_chan. pipe %d.\n", pipe_index);
588
589 /* Report allocated pipes to client */
590 chan_info->dev = dev->h;
591 /* Dest/input/write pipex */
592 chan_info->dest_pipe_index = pipe_index;
593 /* Source/output/read pipe */
594 chan_info->src_pipe_index = pipe_index + 1;
595
596 result = 0;
597exit_err:
598 mutex_unlock(&bam_dma_lock);
599
600 return result;
601}
602EXPORT_SYMBOL(sps_alloc_dma_chan);
603
604/**
605 * Free a BAM DMA channel
606 *
607 */
608int sps_free_dma_chan(struct sps_dma_chan *chan)
609{
610 struct bamdma_device *dev;
611 u32 pipe_index;
612 int result = 0;
613
614 if (chan == NULL) {
615 SPS_ERR(sps,
616 "sps:%s:chan is NULL", __func__);
617 return SPS_ERROR;
618 }
619
620 mutex_lock(&bam_dma_lock);
621
622 dev = sps_dma_find_device(chan->dev);
623 if (dev == NULL) {
624 SPS_ERR(sps, "sps:BAM-DMA: invalid BAM handle: %lx", chan->dev);
625 result = SPS_ERROR;
626 goto exit_err;
627 }
628
629 /* Verify the pipe indices */
630 pipe_index = chan->dest_pipe_index;
631 if (pipe_index >= dev->num_pipes || ((pipe_index & 1)) ||
632 (pipe_index + 1) != chan->src_pipe_index) {
633 SPS_ERR(sps,
634 "sps:sps_free_dma_chan. Invalid pipe indices. num_pipes=%d.dest=%d.src=%d.",
635 dev->num_pipes,
636 chan->dest_pipe_index,
637 chan->src_pipe_index);
638 result = SPS_ERROR;
639 goto exit_err;
640 }
641
642 /* Are both pipes inactive? */
643 if (dev->chans[pipe_index / 2].state != DMA_CHAN_STATE_ALLOC_EXT ||
644 dev->pipes[pipe_index] != PIPE_INACTIVE ||
645 dev->pipes[pipe_index + 1] != PIPE_INACTIVE) {
646 SPS_ERR(sps,
647 "sps:BAM-DMA: attempt to free active chan %d: %d %d",
648 pipe_index / 2, dev->pipes[pipe_index],
649 dev->pipes[pipe_index + 1]);
650 result = SPS_ERROR;
651 goto exit_err;
652 }
653
654 /* Free the channel */
655 dev->chans[pipe_index / 2].state = DMA_CHAN_STATE_FREE;
656
657exit_err:
658 mutex_unlock(&bam_dma_lock);
659
660 return result;
661}
662EXPORT_SYMBOL(sps_free_dma_chan);
663
664/**
665 * Activate a BAM DMA pipe
666 *
667 * This function activates a BAM DMA pipe.
668 *
669 * @dev - pointer to BAM-DMA device descriptor
670 *
671 * @pipe_index - pipe index
672 *
673 * @return 0 on success, negative value on error
674 *
675 */
676static u32 sps_dma_check_pipes(struct bamdma_device *dev, u32 pipe_index)
677{
678 u32 pipe_in;
679 u32 pipe_out;
680 int enabled_in;
681 int enabled_out;
682 u32 check;
683
684 pipe_in = pipe_index & ~1;
685 pipe_out = pipe_in + 1;
686 enabled_in = bam_pipe_is_enabled(&dev->bam->base, pipe_in);
687 enabled_out = bam_pipe_is_enabled(&dev->bam->base, pipe_out);
688
689 if (!enabled_in && !enabled_out)
690 check = DMA_PIPES_BOTH_DISABLED;
691 else if (enabled_in && enabled_out)
692 check = DMA_PIPES_BOTH_ENABLED;
693 else
694 check = DMA_PIPES_STATE_DIFF;
695
696 return check;
697}
698
699/**
700 * Allocate a BAM DMA pipe
701 *
702 */
703int sps_dma_pipe_alloc(void *bam_arg, u32 pipe_index, enum sps_mode dir)
704{
705 struct sps_bam *bam = bam_arg;
706 struct bamdma_device *dev;
707 struct bamdma_chan *chan;
708 u32 channel;
709 int result = SPS_ERROR;
710
711 if (bam == NULL) {
712 SPS_ERR(sps, "%s", "sps:BAM context is NULL");
713 return SPS_ERROR;
714 }
715
716 /* Check pipe direction */
717 if ((DMA_PIPE_IS_DEST(pipe_index) && dir != SPS_MODE_DEST) ||
718 (DMA_PIPE_IS_SRC(pipe_index) && dir != SPS_MODE_SRC)) {
719 SPS_ERR(sps, "sps:BAM-DMA: wrong direction for BAM %pa pipe %d",
720 &bam->props.phys_addr, pipe_index);
721 return SPS_ERROR;
722 }
723
724 mutex_lock(&bam_dma_lock);
725
726 dev = sps_dma_find_device((unsigned long) bam);
727 if (dev == NULL) {
728 SPS_ERR(sps, "sps:BAM-DMA: invalid BAM: %pa",
729 &bam->props.phys_addr);
730 goto exit_err;
731 }
732 if (pipe_index >= dev->num_pipes) {
733 SPS_ERR(sps, "sps:BAM-DMA: BAM %pa invalid pipe: %d",
734 &bam->props.phys_addr, pipe_index);
735 goto exit_err;
736 }
737 if (dev->pipes[pipe_index] != PIPE_INACTIVE) {
738 SPS_ERR(sps, "sps:BAM-DMA: BAM %pa pipe %d already active",
739 &bam->props.phys_addr, pipe_index);
740 goto exit_err;
741 }
742
743 /* Mark pipe active */
744 dev->pipes[pipe_index] = PIPE_ACTIVE;
745
746 /* If channel is not allocated, make an internal allocation */
747 channel = pipe_index / 2;
748 chan = &dev->chans[channel];
749 if (chan->state != DMA_CHAN_STATE_ALLOC_EXT &&
750 chan->state != DMA_CHAN_STATE_ALLOC_INT) {
751 chan->state = DMA_CHAN_STATE_ALLOC_INT;
752 }
753
754 result = 0;
755exit_err:
756 mutex_unlock(&bam_dma_lock);
757
758 return result;
759}
760
761/**
762 * Enable a BAM DMA pipe
763 *
764 */
765int sps_dma_pipe_enable(void *bam_arg, u32 pipe_index)
766{
767 struct sps_bam *bam = bam_arg;
768 struct bamdma_device *dev;
769 struct bamdma_chan *chan;
770 u32 channel;
771 int result = SPS_ERROR;
772
773 SPS_DBG3(sps, "sps:sps_dma_pipe_enable.pipe %d", pipe_index);
774
775 mutex_lock(&bam_dma_lock);
776
777 dev = sps_dma_find_device((unsigned long) bam);
778 if (dev == NULL) {
779 SPS_ERR(sps, "sps:%s:BAM-DMA: invalid BAM", __func__);
780 goto exit_err;
781 }
782 if (pipe_index >= dev->num_pipes) {
783 SPS_ERR(sps, "sps:BAM-DMA: BAM %pa invalid pipe: %d",
784 &bam->props.phys_addr, pipe_index);
785 goto exit_err;
786 }
787 if (dev->pipes[pipe_index] != PIPE_ACTIVE) {
788 SPS_ERR(sps, "sps:BAM-DMA: BAM %pa pipe %d not active",
789 &bam->props.phys_addr, pipe_index);
790 goto exit_err;
791 }
792
793 /*
794 * The channel must be enabled when the dest/input/write pipe
795 * is enabled
796 */
797 if (DMA_PIPE_IS_DEST(pipe_index)) {
798 /* Configure and enable the channel */
799 channel = pipe_index / 2;
800 chan = &dev->chans[channel];
801
802 if (chan->threshold != SPS_DMA_THRESHOLD_DEFAULT)
803 dma_write_reg_field(dev->virt_addr,
804 DMA_CHNL_CONFIG(channel),
805 DMA_CHNL_ACT_THRESH,
806 chan->thresh);
807
808 if (chan->priority != SPS_DMA_PRI_DEFAULT)
809 dma_write_reg_field(dev->virt_addr,
810 DMA_CHNL_CONFIG(channel),
811 DMA_CHNL_WEIGHT,
812 chan->weight);
813
814 dma_write_reg_field(dev->virt_addr,
815 DMA_CHNL_CONFIG(channel),
816 DMA_CHNL_ENABLE, 1);
817 }
818
819 result = 0;
820exit_err:
821 mutex_unlock(&bam_dma_lock);
822
823 return result;
824}
825
826/**
827 * Deactivate a BAM DMA pipe
828 *
829 * This function deactivates a BAM DMA pipe.
830 *
831 * @dev - pointer to BAM-DMA device descriptor
832 *
833 * @bam - pointer to BAM device descriptor
834 *
835 * @pipe_index - pipe index
836 *
837 * @return 0 on success, negative value on error
838 *
839 */
840static int sps_dma_deactivate_pipe_atomic(struct bamdma_device *dev,
841 struct sps_bam *bam,
842 u32 pipe_index)
843{
844 u32 channel;
845
846 if (dev->bam != bam)
847 return SPS_ERROR;
848 if (pipe_index >= dev->num_pipes)
849 return SPS_ERROR;
850 if (dev->pipes[pipe_index] != PIPE_ACTIVE)
851 return SPS_ERROR; /* Pipe is not active */
852
853 SPS_DBG3(sps, "sps:BAM-DMA: deactivate pipe %d", pipe_index);
854
855 /* Mark pipe inactive */
856 dev->pipes[pipe_index] = PIPE_INACTIVE;
857
858 /*
859 * Channel must be reset when either pipe is disabled, so just always
860 * reset regardless of other pipe's state
861 */
862 channel = pipe_index / 2;
863 dma_write_reg_field(dev->virt_addr, DMA_CHNL_CONFIG(channel),
864 DMA_CHNL_ENABLE, 0);
865
866 /* If the peer pipe is also inactive, reset the channel */
867 if (sps_dma_check_pipes(dev, pipe_index) == DMA_PIPES_BOTH_DISABLED) {
868 /* Free channel if allocated internally */
869 if (dev->chans[channel].state == DMA_CHAN_STATE_ALLOC_INT)
870 dev->chans[channel].state = DMA_CHAN_STATE_FREE;
871 }
872
873 return 0;
874}
875
876/**
877 * Free a BAM DMA pipe
878 *
879 */
880int sps_dma_pipe_free(void *bam_arg, u32 pipe_index)
881{
882 struct bamdma_device *dev;
883 struct sps_bam *bam = bam_arg;
884 int result;
885
886 mutex_lock(&bam_dma_lock);
887
888 dev = sps_dma_find_device((unsigned long) bam);
889 if (dev == NULL) {
890 SPS_ERR(sps, "sps:%s:BAM-DMA: invalid BAM", __func__);
891 result = SPS_ERROR;
892 goto exit_err;
893 }
894
895 result = sps_dma_deactivate_pipe_atomic(dev, bam, pipe_index);
896
897exit_err:
898 mutex_unlock(&bam_dma_lock);
899
900 return result;
901}
902
903/**
904 * Get the BAM handle for BAM-DMA.
905 *
906 * The BAM handle should be use as source/destination in the sps_connect().
907 *
908 * @return bam handle on success, zero on error
909 */
910unsigned long sps_dma_get_bam_handle(void)
911{
912 return (unsigned long)bam_dma_dev[0].bam;
913}
914EXPORT_SYMBOL(sps_dma_get_bam_handle);
915
916/**
917 * Free the BAM handle for BAM-DMA.
918 *
919 */
920void sps_dma_free_bam_handle(unsigned long h)
921{
922}
923EXPORT_SYMBOL(sps_dma_free_bam_handle);
924
925#endif /* CONFIG_SPS_SUPPORT_BAMDMA */