1
2
3
4
5
6
7
8
9
10
11
12
13#include <linux/module.h>
14#include <linux/init.h>
15#include <linux/platform_device.h>
16#include <linux/dma-mapping.h>
17#include <linux/interrupt.h>
18#include <linux/delay.h>
19#include <linux/gfp.h>
20#include <linux/of_address.h>
21#include <linux/of_irq.h>
22#include <linux/of_platform.h>
23#include <linux/list.h>
24#include <linux/slab.h>
25
26#include <sound/core.h>
27#include <sound/pcm.h>
28#include <sound/pcm_params.h>
29#include <sound/soc.h>
30
31#include <asm/io.h>
32
33#include "fsl_dma.h"
34#include "fsl_ssi.h"
35
36#define DRV_NAME "fsl_dma"
37
38
39
40
41
42#define FSLDMA_PCM_FORMATS (SNDRV_PCM_FMTBIT_S8 | \
43 SNDRV_PCM_FMTBIT_U8 | \
44 SNDRV_PCM_FMTBIT_S16_LE | \
45 SNDRV_PCM_FMTBIT_S16_BE | \
46 SNDRV_PCM_FMTBIT_U16_LE | \
47 SNDRV_PCM_FMTBIT_U16_BE | \
48 SNDRV_PCM_FMTBIT_S24_LE | \
49 SNDRV_PCM_FMTBIT_S24_BE | \
50 SNDRV_PCM_FMTBIT_U24_LE | \
51 SNDRV_PCM_FMTBIT_U24_BE | \
52 SNDRV_PCM_FMTBIT_S32_LE | \
53 SNDRV_PCM_FMTBIT_S32_BE | \
54 SNDRV_PCM_FMTBIT_U32_LE | \
55 SNDRV_PCM_FMTBIT_U32_BE)
56struct dma_object {
57 struct snd_soc_component_driver dai;
58 dma_addr_t ssi_stx_phys;
59 dma_addr_t ssi_srx_phys;
60 unsigned int ssi_fifo_depth;
61 struct ccsr_dma_channel __iomem *channel;
62 unsigned int irq;
63 bool assigned;
64};
65
66
67
68
69
70#define NUM_DMA_LINKS 2
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93struct fsl_dma_private {
94 struct fsl_dma_link_descriptor link[NUM_DMA_LINKS];
95 struct ccsr_dma_channel __iomem *dma_channel;
96 unsigned int irq;
97 struct snd_pcm_substream *substream;
98 dma_addr_t ssi_sxx_phys;
99 unsigned int ssi_fifo_depth;
100 dma_addr_t ld_buf_phys;
101 unsigned int current_link;
102 dma_addr_t dma_buf_phys;
103 dma_addr_t dma_buf_next;
104 dma_addr_t dma_buf_end;
105 size_t period_size;
106 unsigned int num_periods;
107};
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128static const struct snd_pcm_hardware fsl_dma_hardware = {
129
130 .info = SNDRV_PCM_INFO_INTERLEAVED |
131 SNDRV_PCM_INFO_MMAP |
132 SNDRV_PCM_INFO_MMAP_VALID |
133 SNDRV_PCM_INFO_JOINT_DUPLEX |
134 SNDRV_PCM_INFO_PAUSE,
135 .formats = FSLDMA_PCM_FORMATS,
136 .period_bytes_min = 512,
137 .period_bytes_max = (u32) -1,
138 .periods_min = NUM_DMA_LINKS,
139 .periods_max = (unsigned int) -1,
140 .buffer_bytes_max = 128 * 1024,
141};
142
143
144
145
146
147
148
149static void fsl_dma_abort_stream(struct snd_pcm_substream *substream)
150{
151 snd_pcm_stop_xrun(substream);
152}
153
154
155
156
157
158
159
160static void fsl_dma_update_pointers(struct fsl_dma_private *dma_private)
161{
162 struct fsl_dma_link_descriptor *link =
163 &dma_private->link[dma_private->current_link];
164
165
166
167
168
169 if (dma_private->substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
170 link->source_addr = cpu_to_be32(dma_private->dma_buf_next);
171#ifdef CONFIG_PHYS_64BIT
172 link->source_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP |
173 upper_32_bits(dma_private->dma_buf_next));
174#endif
175 } else {
176 link->dest_addr = cpu_to_be32(dma_private->dma_buf_next);
177#ifdef CONFIG_PHYS_64BIT
178 link->dest_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP |
179 upper_32_bits(dma_private->dma_buf_next));
180#endif
181 }
182
183
184 dma_private->dma_buf_next += dma_private->period_size;
185
186 if (dma_private->dma_buf_next >= dma_private->dma_buf_end)
187 dma_private->dma_buf_next = dma_private->dma_buf_phys;
188
189 if (++dma_private->current_link >= NUM_DMA_LINKS)
190 dma_private->current_link = 0;
191}
192
193
194
195
196
197
198
199static irqreturn_t fsl_dma_isr(int irq, void *dev_id)
200{
201 struct fsl_dma_private *dma_private = dev_id;
202 struct snd_pcm_substream *substream = dma_private->substream;
203 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
204 struct device *dev = rtd->dev;
205 struct ccsr_dma_channel __iomem *dma_channel = dma_private->dma_channel;
206 irqreturn_t ret = IRQ_NONE;
207 u32 sr, sr2 = 0;
208
209
210
211
212 sr = in_be32(&dma_channel->sr);
213
214 if (sr & CCSR_DMA_SR_TE) {
215 dev_err(dev, "dma transmit error\n");
216 fsl_dma_abort_stream(substream);
217 sr2 |= CCSR_DMA_SR_TE;
218 ret = IRQ_HANDLED;
219 }
220
221 if (sr & CCSR_DMA_SR_CH)
222 ret = IRQ_HANDLED;
223
224 if (sr & CCSR_DMA_SR_PE) {
225 dev_err(dev, "dma programming error\n");
226 fsl_dma_abort_stream(substream);
227 sr2 |= CCSR_DMA_SR_PE;
228 ret = IRQ_HANDLED;
229 }
230
231 if (sr & CCSR_DMA_SR_EOLNI) {
232 sr2 |= CCSR_DMA_SR_EOLNI;
233 ret = IRQ_HANDLED;
234 }
235
236 if (sr & CCSR_DMA_SR_CB)
237 ret = IRQ_HANDLED;
238
239 if (sr & CCSR_DMA_SR_EOSI) {
240
241 snd_pcm_period_elapsed(substream);
242
243
244
245
246
247
248 if (dma_private->num_periods != NUM_DMA_LINKS)
249 fsl_dma_update_pointers(dma_private);
250
251 sr2 |= CCSR_DMA_SR_EOSI;
252 ret = IRQ_HANDLED;
253 }
254
255 if (sr & CCSR_DMA_SR_EOLSI) {
256 sr2 |= CCSR_DMA_SR_EOLSI;
257 ret = IRQ_HANDLED;
258 }
259
260
261 if (sr2)
262 out_be32(&dma_channel->sr, sr2);
263
264 return ret;
265}
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282static int fsl_dma_new(struct snd_soc_component *component,
283 struct snd_soc_pcm_runtime *rtd)
284{
285 struct snd_card *card = rtd->card->snd_card;
286 struct snd_pcm *pcm = rtd->pcm;
287 int ret;
288
289 ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(36));
290 if (ret)
291 return ret;
292
293 return snd_pcm_set_fixed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV,
294 card->dev,
295 fsl_dma_hardware.buffer_bytes_max);
296}
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360static int fsl_dma_open(struct snd_soc_component *component,
361 struct snd_pcm_substream *substream)
362{
363 struct snd_pcm_runtime *runtime = substream->runtime;
364 struct device *dev = component->dev;
365 struct dma_object *dma =
366 container_of(component->driver, struct dma_object, dai);
367 struct fsl_dma_private *dma_private;
368 struct ccsr_dma_channel __iomem *dma_channel;
369 dma_addr_t ld_buf_phys;
370 u64 temp_link;
371 u32 mr;
372 int ret = 0;
373 unsigned int i;
374
375
376
377
378
379
380 ret = snd_pcm_hw_constraint_integer(runtime,
381 SNDRV_PCM_HW_PARAM_PERIODS);
382 if (ret < 0) {
383 dev_err(dev, "invalid buffer size\n");
384 return ret;
385 }
386
387 if (dma->assigned) {
388 dev_err(dev, "dma channel already assigned\n");
389 return -EBUSY;
390 }
391
392 dma_private = dma_alloc_coherent(dev, sizeof(struct fsl_dma_private),
393 &ld_buf_phys, GFP_KERNEL);
394 if (!dma_private) {
395 dev_err(dev, "can't allocate dma private data\n");
396 return -ENOMEM;
397 }
398 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
399 dma_private->ssi_sxx_phys = dma->ssi_stx_phys;
400 else
401 dma_private->ssi_sxx_phys = dma->ssi_srx_phys;
402
403 dma_private->ssi_fifo_depth = dma->ssi_fifo_depth;
404 dma_private->dma_channel = dma->channel;
405 dma_private->irq = dma->irq;
406 dma_private->substream = substream;
407 dma_private->ld_buf_phys = ld_buf_phys;
408 dma_private->dma_buf_phys = substream->dma_buffer.addr;
409
410 ret = request_irq(dma_private->irq, fsl_dma_isr, 0, "fsldma-audio",
411 dma_private);
412 if (ret) {
413 dev_err(dev, "can't register ISR for IRQ %u (ret=%i)\n",
414 dma_private->irq, ret);
415 dma_free_coherent(dev, sizeof(struct fsl_dma_private),
416 dma_private, dma_private->ld_buf_phys);
417 return ret;
418 }
419
420 dma->assigned = true;
421
422 snd_soc_set_runtime_hwparams(substream, &fsl_dma_hardware);
423 runtime->private_data = dma_private;
424
425
426
427 dma_channel = dma_private->dma_channel;
428
429 temp_link = dma_private->ld_buf_phys +
430 sizeof(struct fsl_dma_link_descriptor);
431
432 for (i = 0; i < NUM_DMA_LINKS; i++) {
433 dma_private->link[i].next = cpu_to_be64(temp_link);
434
435 temp_link += sizeof(struct fsl_dma_link_descriptor);
436 }
437
438 dma_private->link[i - 1].next = cpu_to_be64(dma_private->ld_buf_phys);
439
440
441 out_be32(&dma_channel->clndar,
442 CCSR_DMA_CLNDAR_ADDR(dma_private->ld_buf_phys));
443 out_be32(&dma_channel->eclndar,
444 CCSR_DMA_ECLNDAR_ADDR(dma_private->ld_buf_phys));
445
446
447 out_be32(&dma_channel->bcr, 0);
448
449
450
451
452
453 mr = in_be32(&dma_channel->mr) &
454 ~(CCSR_DMA_MR_CA | CCSR_DMA_MR_DAHE | CCSR_DMA_MR_SAHE);
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471 mr |= CCSR_DMA_MR_EOSIE | CCSR_DMA_MR_EIE | CCSR_DMA_MR_EMP_EN |
472 CCSR_DMA_MR_EMS_EN;
473
474
475
476 mr |= (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
477 CCSR_DMA_MR_DAHE : CCSR_DMA_MR_SAHE;
478
479 out_be32(&dma_channel->mr, mr);
480
481 return 0;
482}
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508static int fsl_dma_hw_params(struct snd_soc_component *component,
509 struct snd_pcm_substream *substream,
510 struct snd_pcm_hw_params *hw_params)
511{
512 struct snd_pcm_runtime *runtime = substream->runtime;
513 struct fsl_dma_private *dma_private = runtime->private_data;
514 struct device *dev = component->dev;
515
516
517 unsigned int sample_bits =
518 snd_pcm_format_physical_width(params_format(hw_params));
519
520
521 unsigned int sample_bytes = sample_bits / 8;
522
523
524 dma_addr_t ssi_sxx_phys = dma_private->ssi_sxx_phys;
525
526
527 size_t buffer_size = params_buffer_bytes(hw_params);
528
529
530 size_t period_size = params_period_bytes(hw_params);
531
532
533 dma_addr_t temp_addr = substream->dma_buffer.addr;
534
535
536 struct ccsr_dma_channel __iomem *dma_channel = dma_private->dma_channel;
537
538 u32 mr;
539
540 unsigned int i;
541
542
543 dma_private->period_size = period_size;
544 dma_private->num_periods = params_periods(hw_params);
545 dma_private->dma_buf_end = dma_private->dma_buf_phys + buffer_size;
546 dma_private->dma_buf_next = dma_private->dma_buf_phys +
547 (NUM_DMA_LINKS * period_size);
548
549 if (dma_private->dma_buf_next >= dma_private->dma_buf_end)
550
551 dma_private->dma_buf_next = dma_private->dma_buf_phys;
552
553 mr = in_be32(&dma_channel->mr) & ~(CCSR_DMA_MR_BWC_MASK |
554 CCSR_DMA_MR_SAHTS_MASK | CCSR_DMA_MR_DAHTS_MASK);
555
556
557
558
559
560
561 switch (sample_bits) {
562 case 8:
563 mr |= CCSR_DMA_MR_DAHTS_1 | CCSR_DMA_MR_SAHTS_1;
564 ssi_sxx_phys += 3;
565 break;
566 case 16:
567 mr |= CCSR_DMA_MR_DAHTS_2 | CCSR_DMA_MR_SAHTS_2;
568 ssi_sxx_phys += 2;
569 break;
570 case 32:
571 mr |= CCSR_DMA_MR_DAHTS_4 | CCSR_DMA_MR_SAHTS_4;
572 break;
573 default:
574
575 dev_err(dev, "unsupported sample size %u\n", sample_bits);
576 return -EINVAL;
577 }
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610 mr |= CCSR_DMA_MR_BWC((dma_private->ssi_fifo_depth - 2) * sample_bytes);
611
612 out_be32(&dma_channel->mr, mr);
613
614 for (i = 0; i < NUM_DMA_LINKS; i++) {
615 struct fsl_dma_link_descriptor *link = &dma_private->link[i];
616
617 link->count = cpu_to_be32(period_size);
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
637 link->source_addr = cpu_to_be32(temp_addr);
638 link->source_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP |
639 upper_32_bits(temp_addr));
640
641 link->dest_addr = cpu_to_be32(ssi_sxx_phys);
642 link->dest_attr = cpu_to_be32(CCSR_DMA_ATR_NOSNOOP |
643 upper_32_bits(ssi_sxx_phys));
644 } else {
645 link->source_addr = cpu_to_be32(ssi_sxx_phys);
646 link->source_attr = cpu_to_be32(CCSR_DMA_ATR_NOSNOOP |
647 upper_32_bits(ssi_sxx_phys));
648
649 link->dest_addr = cpu_to_be32(temp_addr);
650 link->dest_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP |
651 upper_32_bits(temp_addr));
652 }
653
654 temp_addr += period_size;
655 }
656
657 return 0;
658}
659
660
661
662
663
664
665
666
667
668
669
670
671
672static snd_pcm_uframes_t fsl_dma_pointer(struct snd_soc_component *component,
673 struct snd_pcm_substream *substream)
674{
675 struct snd_pcm_runtime *runtime = substream->runtime;
676 struct fsl_dma_private *dma_private = runtime->private_data;
677 struct device *dev = component->dev;
678 struct ccsr_dma_channel __iomem *dma_channel = dma_private->dma_channel;
679 dma_addr_t position;
680 snd_pcm_uframes_t frames;
681
682
683
684
685
686 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
687 position = in_be32(&dma_channel->sar);
688#ifdef CONFIG_PHYS_64BIT
689 position |= (u64)(in_be32(&dma_channel->satr) &
690 CCSR_DMA_ATR_ESAD_MASK) << 32;
691#endif
692 } else {
693 position = in_be32(&dma_channel->dar);
694#ifdef CONFIG_PHYS_64BIT
695 position |= (u64)(in_be32(&dma_channel->datr) &
696 CCSR_DMA_ATR_ESAD_MASK) << 32;
697#endif
698 }
699
700
701
702
703
704
705
706
707 if (!position)
708 return 0;
709
710 if ((position < dma_private->dma_buf_phys) ||
711 (position > dma_private->dma_buf_end)) {
712 dev_err(dev, "dma pointer is out of range, halting stream\n");
713 return SNDRV_PCM_POS_XRUN;
714 }
715
716 frames = bytes_to_frames(runtime, position - dma_private->dma_buf_phys);
717
718
719
720
721
722 if (frames == runtime->buffer_size)
723 frames = 0;
724
725 return frames;
726}
727
728
729
730
731
732
733
734
735
736static int fsl_dma_hw_free(struct snd_soc_component *component,
737 struct snd_pcm_substream *substream)
738{
739 struct snd_pcm_runtime *runtime = substream->runtime;
740 struct fsl_dma_private *dma_private = runtime->private_data;
741
742 if (dma_private) {
743 struct ccsr_dma_channel __iomem *dma_channel;
744
745 dma_channel = dma_private->dma_channel;
746
747
748 out_be32(&dma_channel->mr, CCSR_DMA_MR_CA);
749 out_be32(&dma_channel->mr, 0);
750
751
752 out_be32(&dma_channel->sr, -1);
753 out_be32(&dma_channel->clndar, 0);
754 out_be32(&dma_channel->eclndar, 0);
755 out_be32(&dma_channel->satr, 0);
756 out_be32(&dma_channel->sar, 0);
757 out_be32(&dma_channel->datr, 0);
758 out_be32(&dma_channel->dar, 0);
759 out_be32(&dma_channel->bcr, 0);
760 out_be32(&dma_channel->nlndar, 0);
761 out_be32(&dma_channel->enlndar, 0);
762 }
763
764 return 0;
765}
766
767
768
769
770static int fsl_dma_close(struct snd_soc_component *component,
771 struct snd_pcm_substream *substream)
772{
773 struct snd_pcm_runtime *runtime = substream->runtime;
774 struct fsl_dma_private *dma_private = runtime->private_data;
775 struct device *dev = component->dev;
776 struct dma_object *dma =
777 container_of(component->driver, struct dma_object, dai);
778
779 if (dma_private) {
780 if (dma_private->irq)
781 free_irq(dma_private->irq, dma_private);
782
783
784 dma_free_coherent(dev, sizeof(struct fsl_dma_private),
785 dma_private, dma_private->ld_buf_phys);
786 substream->runtime->private_data = NULL;
787 }
788
789 dma->assigned = false;
790
791 return 0;
792}
793
794
795
796
797
798
799
800
801
802
803
804
805static struct device_node *find_ssi_node(struct device_node *dma_channel_np)
806{
807 struct device_node *ssi_np, *np;
808
809 for_each_compatible_node(ssi_np, NULL, "fsl,mpc8610-ssi") {
810
811
812
813 np = of_parse_phandle(ssi_np, "fsl,playback-dma", 0);
814 of_node_put(np);
815 if (np == dma_channel_np)
816 return ssi_np;
817
818 np = of_parse_phandle(ssi_np, "fsl,capture-dma", 0);
819 of_node_put(np);
820 if (np == dma_channel_np)
821 return ssi_np;
822 }
823
824 return NULL;
825}
826
827static int fsl_soc_dma_probe(struct platform_device *pdev)
828{
829 struct dma_object *dma;
830 struct device_node *np = pdev->dev.of_node;
831 struct device_node *ssi_np;
832 struct resource res;
833 const uint32_t *iprop;
834 int ret;
835
836
837 ssi_np = find_ssi_node(np);
838 if (!ssi_np) {
839 dev_err(&pdev->dev, "cannot find parent SSI node\n");
840 return -ENODEV;
841 }
842
843 ret = of_address_to_resource(ssi_np, 0, &res);
844 if (ret) {
845 dev_err(&pdev->dev, "could not determine resources for %pOF\n",
846 ssi_np);
847 of_node_put(ssi_np);
848 return ret;
849 }
850
851 dma = kzalloc(sizeof(*dma), GFP_KERNEL);
852 if (!dma) {
853 of_node_put(ssi_np);
854 return -ENOMEM;
855 }
856
857 dma->dai.name = DRV_NAME;
858 dma->dai.open = fsl_dma_open;
859 dma->dai.close = fsl_dma_close;
860 dma->dai.hw_params = fsl_dma_hw_params;
861 dma->dai.hw_free = fsl_dma_hw_free;
862 dma->dai.pointer = fsl_dma_pointer;
863 dma->dai.pcm_construct = fsl_dma_new;
864
865
866 dma->ssi_stx_phys = res.start + REG_SSI_STX0;
867 dma->ssi_srx_phys = res.start + REG_SSI_SRX0;
868
869 iprop = of_get_property(ssi_np, "fsl,fifo-depth", NULL);
870 if (iprop)
871 dma->ssi_fifo_depth = be32_to_cpup(iprop);
872 else
873
874 dma->ssi_fifo_depth = 8;
875
876 of_node_put(ssi_np);
877
878 ret = devm_snd_soc_register_component(&pdev->dev, &dma->dai, NULL, 0);
879 if (ret) {
880 dev_err(&pdev->dev, "could not register platform\n");
881 kfree(dma);
882 return ret;
883 }
884
885 dma->channel = of_iomap(np, 0);
886 dma->irq = irq_of_parse_and_map(np, 0);
887
888 dev_set_drvdata(&pdev->dev, dma);
889
890 return 0;
891}
892
893static int fsl_soc_dma_remove(struct platform_device *pdev)
894{
895 struct dma_object *dma = dev_get_drvdata(&pdev->dev);
896
897 iounmap(dma->channel);
898 irq_dispose_mapping(dma->irq);
899 kfree(dma);
900
901 return 0;
902}
903
904static const struct of_device_id fsl_soc_dma_ids[] = {
905 { .compatible = "fsl,ssi-dma-channel", },
906 {}
907};
908MODULE_DEVICE_TABLE(of, fsl_soc_dma_ids);
909
910static struct platform_driver fsl_soc_dma_driver = {
911 .driver = {
912 .name = "fsl-pcm-audio",
913 .of_match_table = fsl_soc_dma_ids,
914 },
915 .probe = fsl_soc_dma_probe,
916 .remove = fsl_soc_dma_remove,
917};
918
919module_platform_driver(fsl_soc_dma_driver);
920
921MODULE_AUTHOR("Timur Tabi <timur@freescale.com>");
922MODULE_DESCRIPTION("Freescale Elo DMA ASoC PCM Driver");
923MODULE_LICENSE("GPL v2");
924