diff options
Diffstat (limited to 'sound/soc/fsl/fsl_dma.c')
-rw-r--r-- | sound/soc/fsl/fsl_dma.c | 458 |
1 files changed, 293 insertions, 165 deletions
diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c index 410c7496a18d..4cf98c03af22 100644 --- a/sound/soc/fsl/fsl_dma.c +++ b/sound/soc/fsl/fsl_dma.c | |||
@@ -3,10 +3,11 @@ | |||
3 | * | 3 | * |
4 | * Author: Timur Tabi <timur@freescale.com> | 4 | * Author: Timur Tabi <timur@freescale.com> |
5 | * | 5 | * |
6 | * Copyright 2007-2008 Freescale Semiconductor, Inc. This file is licensed | 6 | * Copyright 2007-2010 Freescale Semiconductor, Inc. |
7 | * under the terms of the GNU General Public License version 2. This | 7 | * |
8 | * program is licensed "as is" without any warranty of any kind, whether | 8 | * This file is licensed under the terms of the GNU General Public License |
9 | * express or implied. | 9 | * version 2. This program is licensed "as is" without any warranty of any |
10 | * kind, whether express or implied. | ||
10 | * | 11 | * |
11 | * This driver implements ASoC support for the Elo DMA controller, which is | 12 | * This driver implements ASoC support for the Elo DMA controller, which is |
12 | * the DMA controller on Freescale 83xx, 85xx, and 86xx SOCs. In ALSA terms, | 13 | * the DMA controller on Freescale 83xx, 85xx, and 86xx SOCs. In ALSA terms, |
@@ -20,6 +21,9 @@ | |||
20 | #include <linux/interrupt.h> | 21 | #include <linux/interrupt.h> |
21 | #include <linux/delay.h> | 22 | #include <linux/delay.h> |
22 | #include <linux/gfp.h> | 23 | #include <linux/gfp.h> |
24 | #include <linux/of_platform.h> | ||
25 | #include <linux/list.h> | ||
26 | #include <linux/slab.h> | ||
23 | 27 | ||
24 | #include <sound/core.h> | 28 | #include <sound/core.h> |
25 | #include <sound/pcm.h> | 29 | #include <sound/pcm.h> |
@@ -29,6 +33,7 @@ | |||
29 | #include <asm/io.h> | 33 | #include <asm/io.h> |
30 | 34 | ||
31 | #include "fsl_dma.h" | 35 | #include "fsl_dma.h" |
36 | #include "fsl_ssi.h" /* For the offset of stx0 and srx0 */ | ||
32 | 37 | ||
33 | /* | 38 | /* |
34 | * The formats that the DMA controller supports, which is anything | 39 | * The formats that the DMA controller supports, which is anything |
@@ -52,26 +57,16 @@ | |||
52 | #define FSLDMA_PCM_RATES (SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_192000 | \ | 57 | #define FSLDMA_PCM_RATES (SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_192000 | \ |
53 | SNDRV_PCM_RATE_CONTINUOUS) | 58 | SNDRV_PCM_RATE_CONTINUOUS) |
54 | 59 | ||
55 | /* DMA global data. This structure is used by fsl_dma_open() to determine | 60 | struct dma_object { |
56 | * which DMA channels to assign to a substream. Unfortunately, ASoC V1 does | 61 | struct snd_soc_platform_driver dai; |
57 | * not allow the machine driver to provide this information to the PCM | ||
58 | * driver in advance, and there's no way to differentiate between the two | ||
59 | * DMA controllers. So for now, this driver only supports one SSI device | ||
60 | * using two DMA channels. We cannot support multiple DMA devices. | ||
61 | * | ||
62 | * ssi_stx_phys: bus address of SSI STX register | ||
63 | * ssi_srx_phys: bus address of SSI SRX register | ||
64 | * dma_channel: pointer to the DMA channel's registers | ||
65 | * irq: IRQ for this DMA channel | ||
66 | * assigned: set to 1 if that DMA channel is assigned to a substream | ||
67 | */ | ||
68 | static struct { | ||
69 | dma_addr_t ssi_stx_phys; | 62 | dma_addr_t ssi_stx_phys; |
70 | dma_addr_t ssi_srx_phys; | 63 | dma_addr_t ssi_srx_phys; |
71 | struct ccsr_dma_channel __iomem *dma_channel[2]; | 64 | unsigned int ssi_fifo_depth; |
72 | unsigned int irq[2]; | 65 | struct ccsr_dma_channel __iomem *channel; |
73 | unsigned int assigned[2]; | 66 | unsigned int irq; |
74 | } dma_global_data; | 67 | bool assigned; |
68 | char path[1]; | ||
69 | }; | ||
75 | 70 | ||
76 | /* | 71 | /* |
77 | * The number of DMA links to use. Two is the bare minimum, but if you | 72 | * The number of DMA links to use. Two is the bare minimum, but if you |
@@ -88,8 +83,6 @@ static struct { | |||
88 | * structure. | 83 | * structure. |
89 | * | 84 | * |
90 | * @link[]: array of link descriptors | 85 | * @link[]: array of link descriptors |
91 | * @controller_id: which DMA controller (0, 1, ...) | ||
92 | * @channel_id: which DMA channel on the controller (0, 1, 2, ...) | ||
93 | * @dma_channel: pointer to the DMA channel's registers | 86 | * @dma_channel: pointer to the DMA channel's registers |
94 | * @irq: IRQ for this DMA channel | 87 | * @irq: IRQ for this DMA channel |
95 | * @substream: pointer to the substream object, needed by the ISR | 88 | * @substream: pointer to the substream object, needed by the ISR |
@@ -104,12 +97,11 @@ static struct { | |||
104 | */ | 97 | */ |
105 | struct fsl_dma_private { | 98 | struct fsl_dma_private { |
106 | struct fsl_dma_link_descriptor link[NUM_DMA_LINKS]; | 99 | struct fsl_dma_link_descriptor link[NUM_DMA_LINKS]; |
107 | unsigned int controller_id; | ||
108 | unsigned int channel_id; | ||
109 | struct ccsr_dma_channel __iomem *dma_channel; | 100 | struct ccsr_dma_channel __iomem *dma_channel; |
110 | unsigned int irq; | 101 | unsigned int irq; |
111 | struct snd_pcm_substream *substream; | 102 | struct snd_pcm_substream *substream; |
112 | dma_addr_t ssi_sxx_phys; | 103 | dma_addr_t ssi_sxx_phys; |
104 | unsigned int ssi_fifo_depth; | ||
113 | dma_addr_t ld_buf_phys; | 105 | dma_addr_t ld_buf_phys; |
114 | unsigned int current_link; | 106 | unsigned int current_link; |
115 | dma_addr_t dma_buf_phys; | 107 | dma_addr_t dma_buf_phys; |
@@ -185,13 +177,23 @@ static void fsl_dma_update_pointers(struct fsl_dma_private *dma_private) | |||
185 | struct fsl_dma_link_descriptor *link = | 177 | struct fsl_dma_link_descriptor *link = |
186 | &dma_private->link[dma_private->current_link]; | 178 | &dma_private->link[dma_private->current_link]; |
187 | 179 | ||
188 | /* Update our link descriptors to point to the next period */ | 180 | /* Update our link descriptors to point to the next period. On a 36-bit |
189 | if (dma_private->substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 181 | * system, we also need to update the ESAD bits. We also set (keep) the |
190 | link->source_addr = | 182 | * snoop bits. See the comments in fsl_dma_hw_params() about snooping. |
191 | cpu_to_be32(dma_private->dma_buf_next); | 183 | */ |
192 | else | 184 | if (dma_private->substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
193 | link->dest_addr = | 185 | link->source_addr = cpu_to_be32(dma_private->dma_buf_next); |
194 | cpu_to_be32(dma_private->dma_buf_next); | 186 | #ifdef CONFIG_PHYS_64BIT |
187 | link->source_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP | | ||
188 | upper_32_bits(dma_private->dma_buf_next)); | ||
189 | #endif | ||
190 | } else { | ||
191 | link->dest_addr = cpu_to_be32(dma_private->dma_buf_next); | ||
192 | #ifdef CONFIG_PHYS_64BIT | ||
193 | link->dest_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP | | ||
194 | upper_32_bits(dma_private->dma_buf_next)); | ||
195 | #endif | ||
196 | } | ||
195 | 197 | ||
196 | /* Update our variables for next time */ | 198 | /* Update our variables for next time */ |
197 | dma_private->dma_buf_next += dma_private->period_size; | 199 | dma_private->dma_buf_next += dma_private->period_size; |
@@ -212,6 +214,9 @@ static void fsl_dma_update_pointers(struct fsl_dma_private *dma_private) | |||
212 | static irqreturn_t fsl_dma_isr(int irq, void *dev_id) | 214 | static irqreturn_t fsl_dma_isr(int irq, void *dev_id) |
213 | { | 215 | { |
214 | struct fsl_dma_private *dma_private = dev_id; | 216 | struct fsl_dma_private *dma_private = dev_id; |
217 | struct snd_pcm_substream *substream = dma_private->substream; | ||
218 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
219 | struct device *dev = rtd->platform->dev; | ||
215 | struct ccsr_dma_channel __iomem *dma_channel = dma_private->dma_channel; | 220 | struct ccsr_dma_channel __iomem *dma_channel = dma_private->dma_channel; |
216 | irqreturn_t ret = IRQ_NONE; | 221 | irqreturn_t ret = IRQ_NONE; |
217 | u32 sr, sr2 = 0; | 222 | u32 sr, sr2 = 0; |
@@ -222,11 +227,8 @@ static irqreturn_t fsl_dma_isr(int irq, void *dev_id) | |||
222 | sr = in_be32(&dma_channel->sr); | 227 | sr = in_be32(&dma_channel->sr); |
223 | 228 | ||
224 | if (sr & CCSR_DMA_SR_TE) { | 229 | if (sr & CCSR_DMA_SR_TE) { |
225 | dev_err(dma_private->substream->pcm->card->dev, | 230 | dev_err(dev, "dma transmit error\n"); |
226 | "DMA transmit error (controller=%u channel=%u irq=%u\n", | 231 | fsl_dma_abort_stream(substream); |
227 | dma_private->controller_id, | ||
228 | dma_private->channel_id, irq); | ||
229 | fsl_dma_abort_stream(dma_private->substream); | ||
230 | sr2 |= CCSR_DMA_SR_TE; | 232 | sr2 |= CCSR_DMA_SR_TE; |
231 | ret = IRQ_HANDLED; | 233 | ret = IRQ_HANDLED; |
232 | } | 234 | } |
@@ -235,11 +237,8 @@ static irqreturn_t fsl_dma_isr(int irq, void *dev_id) | |||
235 | ret = IRQ_HANDLED; | 237 | ret = IRQ_HANDLED; |
236 | 238 | ||
237 | if (sr & CCSR_DMA_SR_PE) { | 239 | if (sr & CCSR_DMA_SR_PE) { |
238 | dev_err(dma_private->substream->pcm->card->dev, | 240 | dev_err(dev, "dma programming error\n"); |
239 | "DMA%u programming error (channel=%u irq=%u)\n", | 241 | fsl_dma_abort_stream(substream); |
240 | dma_private->controller_id, | ||
241 | dma_private->channel_id, irq); | ||
242 | fsl_dma_abort_stream(dma_private->substream); | ||
243 | sr2 |= CCSR_DMA_SR_PE; | 242 | sr2 |= CCSR_DMA_SR_PE; |
244 | ret = IRQ_HANDLED; | 243 | ret = IRQ_HANDLED; |
245 | } | 244 | } |
@@ -253,8 +252,6 @@ static irqreturn_t fsl_dma_isr(int irq, void *dev_id) | |||
253 | ret = IRQ_HANDLED; | 252 | ret = IRQ_HANDLED; |
254 | 253 | ||
255 | if (sr & CCSR_DMA_SR_EOSI) { | 254 | if (sr & CCSR_DMA_SR_EOSI) { |
256 | struct snd_pcm_substream *substream = dma_private->substream; | ||
257 | |||
258 | /* Tell ALSA we completed a period. */ | 255 | /* Tell ALSA we completed a period. */ |
259 | snd_pcm_period_elapsed(substream); | 256 | snd_pcm_period_elapsed(substream); |
260 | 257 | ||
@@ -288,11 +285,19 @@ static irqreturn_t fsl_dma_isr(int irq, void *dev_id) | |||
288 | * This function is called when the codec driver calls snd_soc_new_pcms(), | 285 | * This function is called when the codec driver calls snd_soc_new_pcms(), |
289 | * once for each .dai_link in the machine driver's snd_soc_card | 286 | * once for each .dai_link in the machine driver's snd_soc_card |
290 | * structure. | 287 | * structure. |
288 | * | ||
289 | * snd_dma_alloc_pages() is just a front-end to dma_alloc_coherent(), which | ||
290 | * (currently) always allocates the DMA buffer in lowmem, even if GFP_HIGHMEM | ||
291 | * is specified. Therefore, any DMA buffers we allocate will always be in low | ||
292 | * memory, but we support for 36-bit physical addresses anyway. | ||
293 | * | ||
294 | * Regardless of where the memory is actually allocated, since the device can | ||
295 | * technically DMA to any 36-bit address, we do need to set the DMA mask to 36. | ||
291 | */ | 296 | */ |
292 | static int fsl_dma_new(struct snd_card *card, struct snd_soc_dai *dai, | 297 | static int fsl_dma_new(struct snd_card *card, struct snd_soc_dai *dai, |
293 | struct snd_pcm *pcm) | 298 | struct snd_pcm *pcm) |
294 | { | 299 | { |
295 | static u64 fsl_dma_dmamask = DMA_BIT_MASK(32); | 300 | static u64 fsl_dma_dmamask = DMA_BIT_MASK(36); |
296 | int ret; | 301 | int ret; |
297 | 302 | ||
298 | if (!card->dev->dma_mask) | 303 | if (!card->dev->dma_mask) |
@@ -301,25 +306,29 @@ static int fsl_dma_new(struct snd_card *card, struct snd_soc_dai *dai, | |||
301 | if (!card->dev->coherent_dma_mask) | 306 | if (!card->dev->coherent_dma_mask) |
302 | card->dev->coherent_dma_mask = fsl_dma_dmamask; | 307 | card->dev->coherent_dma_mask = fsl_dma_dmamask; |
303 | 308 | ||
304 | ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, card->dev, | 309 | /* Some codecs have separate DAIs for playback and capture, so we |
305 | fsl_dma_hardware.buffer_bytes_max, | 310 | * should allocate a DMA buffer only for the streams that are valid. |
306 | &pcm->streams[0].substream->dma_buffer); | 311 | */ |
307 | if (ret) { | 312 | |
308 | dev_err(card->dev, | 313 | if (dai->driver->playback.channels_min) { |
309 | "Can't allocate playback DMA buffer (size=%u)\n", | 314 | ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, card->dev, |
310 | fsl_dma_hardware.buffer_bytes_max); | 315 | fsl_dma_hardware.buffer_bytes_max, |
311 | return -ENOMEM; | 316 | &pcm->streams[0].substream->dma_buffer); |
317 | if (ret) { | ||
318 | dev_err(card->dev, "can't alloc playback dma buffer\n"); | ||
319 | return ret; | ||
320 | } | ||
312 | } | 321 | } |
313 | 322 | ||
314 | ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, card->dev, | 323 | if (dai->driver->capture.channels_min) { |
315 | fsl_dma_hardware.buffer_bytes_max, | 324 | ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, card->dev, |
316 | &pcm->streams[1].substream->dma_buffer); | 325 | fsl_dma_hardware.buffer_bytes_max, |
317 | if (ret) { | 326 | &pcm->streams[1].substream->dma_buffer); |
318 | snd_dma_free_pages(&pcm->streams[0].substream->dma_buffer); | 327 | if (ret) { |
319 | dev_err(card->dev, | 328 | snd_dma_free_pages(&pcm->streams[0].substream->dma_buffer); |
320 | "Can't allocate capture DMA buffer (size=%u)\n", | 329 | dev_err(card->dev, "can't alloc capture dma buffer\n"); |
321 | fsl_dma_hardware.buffer_bytes_max); | 330 | return ret; |
322 | return -ENOMEM; | 331 | } |
323 | } | 332 | } |
324 | 333 | ||
325 | return 0; | 334 | return 0; |
@@ -390,6 +399,10 @@ static int fsl_dma_new(struct snd_card *card, struct snd_soc_dai *dai, | |||
390 | static int fsl_dma_open(struct snd_pcm_substream *substream) | 399 | static int fsl_dma_open(struct snd_pcm_substream *substream) |
391 | { | 400 | { |
392 | struct snd_pcm_runtime *runtime = substream->runtime; | 401 | struct snd_pcm_runtime *runtime = substream->runtime; |
402 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
403 | struct device *dev = rtd->platform->dev; | ||
404 | struct dma_object *dma = | ||
405 | container_of(rtd->platform->driver, struct dma_object, dai); | ||
393 | struct fsl_dma_private *dma_private; | 406 | struct fsl_dma_private *dma_private; |
394 | struct ccsr_dma_channel __iomem *dma_channel; | 407 | struct ccsr_dma_channel __iomem *dma_channel; |
395 | dma_addr_t ld_buf_phys; | 408 | dma_addr_t ld_buf_phys; |
@@ -407,52 +420,45 @@ static int fsl_dma_open(struct snd_pcm_substream *substream) | |||
407 | ret = snd_pcm_hw_constraint_integer(runtime, | 420 | ret = snd_pcm_hw_constraint_integer(runtime, |
408 | SNDRV_PCM_HW_PARAM_PERIODS); | 421 | SNDRV_PCM_HW_PARAM_PERIODS); |
409 | if (ret < 0) { | 422 | if (ret < 0) { |
410 | dev_err(substream->pcm->card->dev, "invalid buffer size\n"); | 423 | dev_err(dev, "invalid buffer size\n"); |
411 | return ret; | 424 | return ret; |
412 | } | 425 | } |
413 | 426 | ||
414 | channel = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1; | 427 | channel = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1; |
415 | 428 | ||
416 | if (dma_global_data.assigned[channel]) { | 429 | if (dma->assigned) { |
417 | dev_err(substream->pcm->card->dev, | 430 | dev_err(dev, "dma channel already assigned\n"); |
418 | "DMA channel already assigned\n"); | ||
419 | return -EBUSY; | 431 | return -EBUSY; |
420 | } | 432 | } |
421 | 433 | ||
422 | dma_private = dma_alloc_coherent(substream->pcm->card->dev, | 434 | dma_private = dma_alloc_coherent(dev, sizeof(struct fsl_dma_private), |
423 | sizeof(struct fsl_dma_private), &ld_buf_phys, GFP_KERNEL); | 435 | &ld_buf_phys, GFP_KERNEL); |
424 | if (!dma_private) { | 436 | if (!dma_private) { |
425 | dev_err(substream->pcm->card->dev, | 437 | dev_err(dev, "can't allocate dma private data\n"); |
426 | "can't allocate DMA private data\n"); | ||
427 | return -ENOMEM; | 438 | return -ENOMEM; |
428 | } | 439 | } |
429 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 440 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
430 | dma_private->ssi_sxx_phys = dma_global_data.ssi_stx_phys; | 441 | dma_private->ssi_sxx_phys = dma->ssi_stx_phys; |
431 | else | 442 | else |
432 | dma_private->ssi_sxx_phys = dma_global_data.ssi_srx_phys; | 443 | dma_private->ssi_sxx_phys = dma->ssi_srx_phys; |
433 | 444 | ||
434 | dma_private->dma_channel = dma_global_data.dma_channel[channel]; | 445 | dma_private->ssi_fifo_depth = dma->ssi_fifo_depth; |
435 | dma_private->irq = dma_global_data.irq[channel]; | 446 | dma_private->dma_channel = dma->channel; |
447 | dma_private->irq = dma->irq; | ||
436 | dma_private->substream = substream; | 448 | dma_private->substream = substream; |
437 | dma_private->ld_buf_phys = ld_buf_phys; | 449 | dma_private->ld_buf_phys = ld_buf_phys; |
438 | dma_private->dma_buf_phys = substream->dma_buffer.addr; | 450 | dma_private->dma_buf_phys = substream->dma_buffer.addr; |
439 | 451 | ||
440 | /* We only support one DMA controller for now */ | ||
441 | dma_private->controller_id = 0; | ||
442 | dma_private->channel_id = channel; | ||
443 | |||
444 | ret = request_irq(dma_private->irq, fsl_dma_isr, 0, "DMA", dma_private); | 452 | ret = request_irq(dma_private->irq, fsl_dma_isr, 0, "DMA", dma_private); |
445 | if (ret) { | 453 | if (ret) { |
446 | dev_err(substream->pcm->card->dev, | 454 | dev_err(dev, "can't register ISR for IRQ %u (ret=%i)\n", |
447 | "can't register ISR for IRQ %u (ret=%i)\n", | ||
448 | dma_private->irq, ret); | 455 | dma_private->irq, ret); |
449 | dma_free_coherent(substream->pcm->card->dev, | 456 | dma_free_coherent(dev, sizeof(struct fsl_dma_private), |
450 | sizeof(struct fsl_dma_private), | ||
451 | dma_private, dma_private->ld_buf_phys); | 457 | dma_private, dma_private->ld_buf_phys); |
452 | return ret; | 458 | return ret; |
453 | } | 459 | } |
454 | 460 | ||
455 | dma_global_data.assigned[channel] = 1; | 461 | dma->assigned = 1; |
456 | 462 | ||
457 | snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); | 463 | snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); |
458 | snd_soc_set_runtime_hwparams(substream, &fsl_dma_hardware); | 464 | snd_soc_set_runtime_hwparams(substream, &fsl_dma_hardware); |
@@ -546,13 +552,15 @@ static int fsl_dma_hw_params(struct snd_pcm_substream *substream, | |||
546 | { | 552 | { |
547 | struct snd_pcm_runtime *runtime = substream->runtime; | 553 | struct snd_pcm_runtime *runtime = substream->runtime; |
548 | struct fsl_dma_private *dma_private = runtime->private_data; | 554 | struct fsl_dma_private *dma_private = runtime->private_data; |
555 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
556 | struct device *dev = rtd->platform->dev; | ||
549 | 557 | ||
550 | /* Number of bits per sample */ | 558 | /* Number of bits per sample */ |
551 | unsigned int sample_size = | 559 | unsigned int sample_bits = |
552 | snd_pcm_format_physical_width(params_format(hw_params)); | 560 | snd_pcm_format_physical_width(params_format(hw_params)); |
553 | 561 | ||
554 | /* Number of bytes per frame */ | 562 | /* Number of bytes per frame */ |
555 | unsigned int frame_size = 2 * (sample_size / 8); | 563 | unsigned int sample_bytes = sample_bits / 8; |
556 | 564 | ||
557 | /* Bus address of SSI STX register */ | 565 | /* Bus address of SSI STX register */ |
558 | dma_addr_t ssi_sxx_phys = dma_private->ssi_sxx_phys; | 566 | dma_addr_t ssi_sxx_phys = dma_private->ssi_sxx_phys; |
@@ -592,7 +600,7 @@ static int fsl_dma_hw_params(struct snd_pcm_substream *substream, | |||
592 | * that offset here. While we're at it, also tell the DMA controller | 600 | * that offset here. While we're at it, also tell the DMA controller |
593 | * how much data to transfer per sample. | 601 | * how much data to transfer per sample. |
594 | */ | 602 | */ |
595 | switch (sample_size) { | 603 | switch (sample_bits) { |
596 | case 8: | 604 | case 8: |
597 | mr |= CCSR_DMA_MR_DAHTS_1 | CCSR_DMA_MR_SAHTS_1; | 605 | mr |= CCSR_DMA_MR_DAHTS_1 | CCSR_DMA_MR_SAHTS_1; |
598 | ssi_sxx_phys += 3; | 606 | ssi_sxx_phys += 3; |
@@ -606,23 +614,42 @@ static int fsl_dma_hw_params(struct snd_pcm_substream *substream, | |||
606 | break; | 614 | break; |
607 | default: | 615 | default: |
608 | /* We should never get here */ | 616 | /* We should never get here */ |
609 | dev_err(substream->pcm->card->dev, | 617 | dev_err(dev, "unsupported sample size %u\n", sample_bits); |
610 | "unsupported sample size %u\n", sample_size); | ||
611 | return -EINVAL; | 618 | return -EINVAL; |
612 | } | 619 | } |
613 | 620 | ||
614 | /* | 621 | /* |
615 | * BWC should always be a multiple of the frame size. BWC determines | 622 | * BWC determines how many bytes are sent/received before the DMA |
616 | * how many bytes are sent/received before the DMA controller checks the | 623 | * controller checks the SSI to see if it needs to stop. BWC should |
617 | * SSI to see if it needs to stop. For playback, the transmit FIFO can | 624 | * always be a multiple of the frame size, so that we always transmit |
618 | * hold three frames, so we want to send two frames at a time. For | 625 | * whole frames. Each frame occupies two slots in the FIFO. The |
619 | * capture, the receive FIFO is triggered when it contains one frame, so | 626 | * parameter for CCSR_DMA_MR_BWC() is rounded down the next power of two |
620 | * we want to receive one frame at a time. | 627 | * (MR[BWC] can only represent even powers of two). |
628 | * | ||
629 | * To simplify the process, we set BWC to the largest value that is | ||
630 | * less than or equal to the FIFO watermark. For playback, this ensures | ||
631 | * that we transfer the maximum amount without overrunning the FIFO. | ||
632 | * For capture, this ensures that we transfer the maximum amount without | ||
633 | * underrunning the FIFO. | ||
634 | * | ||
635 | * f = SSI FIFO depth | ||
636 | * w = SSI watermark value (which equals f - 2) | ||
637 | * b = DMA bandwidth count (in bytes) | ||
638 | * s = sample size (in bytes, which equals frame_size * 2) | ||
639 | * | ||
640 | * For playback, we never transmit more than the transmit FIFO | ||
641 | * watermark, otherwise we might write more data than the FIFO can hold. | ||
642 | * The watermark is equal to the FIFO depth minus two. | ||
643 | * | ||
644 | * For capture, two equations must hold: | ||
645 | * w > f - (b / s) | ||
646 | * w >= b / s | ||
647 | * | ||
648 | * So, b > 2 * s, but b must also be <= s * w. To simplify, we set | ||
649 | * b = s * w, which is equal to | ||
650 | * (dma_private->ssi_fifo_depth - 2) * sample_bytes. | ||
621 | */ | 651 | */ |
622 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 652 | mr |= CCSR_DMA_MR_BWC((dma_private->ssi_fifo_depth - 2) * sample_bytes); |
623 | mr |= CCSR_DMA_MR_BWC(2 * frame_size); | ||
624 | else | ||
625 | mr |= CCSR_DMA_MR_BWC(frame_size); | ||
626 | 653 | ||
627 | out_be32(&dma_channel->mr, mr); | 654 | out_be32(&dma_channel->mr, mr); |
628 | 655 | ||
@@ -631,12 +658,7 @@ static int fsl_dma_hw_params(struct snd_pcm_substream *substream, | |||
631 | 658 | ||
632 | link->count = cpu_to_be32(period_size); | 659 | link->count = cpu_to_be32(period_size); |
633 | 660 | ||
634 | /* Even though the DMA controller supports 36-bit addressing, | 661 | /* The snoop bit tells the DMA controller whether it should tell |
635 | * for simplicity we allow only 32-bit addresses for the audio | ||
636 | * buffer itself. This was enforced in fsl_dma_new() with the | ||
637 | * DMA mask. | ||
638 | * | ||
639 | * The snoop bit tells the DMA controller whether it should tell | ||
640 | * the ECM to snoop during a read or write to an address. For | 662 | * the ECM to snoop during a read or write to an address. For |
641 | * audio, we use DMA to transfer data between memory and an I/O | 663 | * audio, we use DMA to transfer data between memory and an I/O |
642 | * device (the SSI's STX0 or SRX0 register). Snooping is only | 664 | * device (the SSI's STX0 or SRX0 register). Snooping is only |
@@ -651,20 +673,24 @@ static int fsl_dma_hw_params(struct snd_pcm_substream *substream, | |||
651 | * flush out the data for the previous period. So if you | 673 | * flush out the data for the previous period. So if you |
652 | * increased period_bytes_min to a large enough size, you might | 674 | * increased period_bytes_min to a large enough size, you might |
653 | * get more performance by not snooping, and you'll still be | 675 | * get more performance by not snooping, and you'll still be |
654 | * okay. | 676 | * okay. You'll need to update fsl_dma_update_pointers() also. |
655 | */ | 677 | */ |
656 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 678 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
657 | link->source_addr = cpu_to_be32(temp_addr); | 679 | link->source_addr = cpu_to_be32(temp_addr); |
658 | link->source_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP); | 680 | link->source_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP | |
681 | upper_32_bits(temp_addr)); | ||
659 | 682 | ||
660 | link->dest_addr = cpu_to_be32(ssi_sxx_phys); | 683 | link->dest_addr = cpu_to_be32(ssi_sxx_phys); |
661 | link->dest_attr = cpu_to_be32(CCSR_DMA_ATR_NOSNOOP); | 684 | link->dest_attr = cpu_to_be32(CCSR_DMA_ATR_NOSNOOP | |
685 | upper_32_bits(ssi_sxx_phys)); | ||
662 | } else { | 686 | } else { |
663 | link->source_addr = cpu_to_be32(ssi_sxx_phys); | 687 | link->source_addr = cpu_to_be32(ssi_sxx_phys); |
664 | link->source_attr = cpu_to_be32(CCSR_DMA_ATR_NOSNOOP); | 688 | link->source_attr = cpu_to_be32(CCSR_DMA_ATR_NOSNOOP | |
689 | upper_32_bits(ssi_sxx_phys)); | ||
665 | 690 | ||
666 | link->dest_addr = cpu_to_be32(temp_addr); | 691 | link->dest_addr = cpu_to_be32(temp_addr); |
667 | link->dest_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP); | 692 | link->dest_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP | |
693 | upper_32_bits(temp_addr)); | ||
668 | } | 694 | } |
669 | 695 | ||
670 | temp_addr += period_size; | 696 | temp_addr += period_size; |
@@ -689,14 +715,29 @@ static snd_pcm_uframes_t fsl_dma_pointer(struct snd_pcm_substream *substream) | |||
689 | { | 715 | { |
690 | struct snd_pcm_runtime *runtime = substream->runtime; | 716 | struct snd_pcm_runtime *runtime = substream->runtime; |
691 | struct fsl_dma_private *dma_private = runtime->private_data; | 717 | struct fsl_dma_private *dma_private = runtime->private_data; |
718 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
719 | struct device *dev = rtd->platform->dev; | ||
692 | struct ccsr_dma_channel __iomem *dma_channel = dma_private->dma_channel; | 720 | struct ccsr_dma_channel __iomem *dma_channel = dma_private->dma_channel; |
693 | dma_addr_t position; | 721 | dma_addr_t position; |
694 | snd_pcm_uframes_t frames; | 722 | snd_pcm_uframes_t frames; |
695 | 723 | ||
696 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 724 | /* Obtain the current DMA pointer, but don't read the ESAD bits if we |
725 | * only have 32-bit DMA addresses. This function is typically called | ||
726 | * in interrupt context, so we need to optimize it. | ||
727 | */ | ||
728 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | ||
697 | position = in_be32(&dma_channel->sar); | 729 | position = in_be32(&dma_channel->sar); |
698 | else | 730 | #ifdef CONFIG_PHYS_64BIT |
731 | position |= (u64)(in_be32(&dma_channel->satr) & | ||
732 | CCSR_DMA_ATR_ESAD_MASK) << 32; | ||
733 | #endif | ||
734 | } else { | ||
699 | position = in_be32(&dma_channel->dar); | 735 | position = in_be32(&dma_channel->dar); |
736 | #ifdef CONFIG_PHYS_64BIT | ||
737 | position |= (u64)(in_be32(&dma_channel->datr) & | ||
738 | CCSR_DMA_ATR_ESAD_MASK) << 32; | ||
739 | #endif | ||
740 | } | ||
700 | 741 | ||
701 | /* | 742 | /* |
702 | * When capture is started, the SSI immediately starts to fill its FIFO. | 743 | * When capture is started, the SSI immediately starts to fill its FIFO. |
@@ -710,8 +751,7 @@ static snd_pcm_uframes_t fsl_dma_pointer(struct snd_pcm_substream *substream) | |||
710 | 751 | ||
711 | if ((position < dma_private->dma_buf_phys) || | 752 | if ((position < dma_private->dma_buf_phys) || |
712 | (position > dma_private->dma_buf_end)) { | 753 | (position > dma_private->dma_buf_end)) { |
713 | dev_err(substream->pcm->card->dev, | 754 | dev_err(dev, "dma pointer is out of range, halting stream\n"); |
714 | "dma pointer is out of range, halting stream\n"); | ||
715 | return SNDRV_PCM_POS_XRUN; | 755 | return SNDRV_PCM_POS_XRUN; |
716 | } | 756 | } |
717 | 757 | ||
@@ -772,26 +812,28 @@ static int fsl_dma_close(struct snd_pcm_substream *substream) | |||
772 | { | 812 | { |
773 | struct snd_pcm_runtime *runtime = substream->runtime; | 813 | struct snd_pcm_runtime *runtime = substream->runtime; |
774 | struct fsl_dma_private *dma_private = runtime->private_data; | 814 | struct fsl_dma_private *dma_private = runtime->private_data; |
775 | int dir = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1; | 815 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
816 | struct device *dev = rtd->platform->dev; | ||
817 | struct dma_object *dma = | ||
818 | container_of(rtd->platform->driver, struct dma_object, dai); | ||
776 | 819 | ||
777 | if (dma_private) { | 820 | if (dma_private) { |
778 | if (dma_private->irq) | 821 | if (dma_private->irq) |
779 | free_irq(dma_private->irq, dma_private); | 822 | free_irq(dma_private->irq, dma_private); |
780 | 823 | ||
781 | if (dma_private->ld_buf_phys) { | 824 | if (dma_private->ld_buf_phys) { |
782 | dma_unmap_single(substream->pcm->card->dev, | 825 | dma_unmap_single(dev, dma_private->ld_buf_phys, |
783 | dma_private->ld_buf_phys, | 826 | sizeof(dma_private->link), |
784 | sizeof(dma_private->link), DMA_TO_DEVICE); | 827 | DMA_TO_DEVICE); |
785 | } | 828 | } |
786 | 829 | ||
787 | /* Deallocate the fsl_dma_private structure */ | 830 | /* Deallocate the fsl_dma_private structure */ |
788 | dma_free_coherent(substream->pcm->card->dev, | 831 | dma_free_coherent(dev, sizeof(struct fsl_dma_private), |
789 | sizeof(struct fsl_dma_private), | 832 | dma_private, dma_private->ld_buf_phys); |
790 | dma_private, dma_private->ld_buf_phys); | ||
791 | substream->runtime->private_data = NULL; | 833 | substream->runtime->private_data = NULL; |
792 | } | 834 | } |
793 | 835 | ||
794 | dma_global_data.assigned[dir] = 0; | 836 | dma->assigned = 0; |
795 | 837 | ||
796 | return 0; | 838 | return 0; |
797 | } | 839 | } |
@@ -814,6 +856,37 @@ static void fsl_dma_free_dma_buffers(struct snd_pcm *pcm) | |||
814 | } | 856 | } |
815 | } | 857 | } |
816 | 858 | ||
859 | /** | ||
860 | * find_ssi_node -- returns the SSI node that points to his DMA channel node | ||
861 | * | ||
862 | * Although this DMA driver attempts to operate independently of the other | ||
863 | * devices, it still needs to determine some information about the SSI device | ||
864 | * that it's working with. Unfortunately, the device tree does not contain | ||
865 | * a pointer from the DMA channel node to the SSI node -- the pointer goes the | ||
866 | * other way. So we need to scan the device tree for SSI nodes until we find | ||
867 | * the one that points to the given DMA channel node. It's ugly, but at least | ||
868 | * it's contained in this one function. | ||
869 | */ | ||
870 | static struct device_node *find_ssi_node(struct device_node *dma_channel_np) | ||
871 | { | ||
872 | struct device_node *ssi_np, *np; | ||
873 | |||
874 | for_each_compatible_node(ssi_np, NULL, "fsl,mpc8610-ssi") { | ||
875 | /* Check each DMA phandle to see if it points to us. We | ||
876 | * assume that device_node pointers are a valid comparison. | ||
877 | */ | ||
878 | np = of_parse_phandle(ssi_np, "fsl,playback-dma", 0); | ||
879 | if (np == dma_channel_np) | ||
880 | return ssi_np; | ||
881 | |||
882 | np = of_parse_phandle(ssi_np, "fsl,capture-dma", 0); | ||
883 | if (np == dma_channel_np) | ||
884 | return ssi_np; | ||
885 | } | ||
886 | |||
887 | return NULL; | ||
888 | } | ||
889 | |||
817 | static struct snd_pcm_ops fsl_dma_ops = { | 890 | static struct snd_pcm_ops fsl_dma_ops = { |
818 | .open = fsl_dma_open, | 891 | .open = fsl_dma_open, |
819 | .close = fsl_dma_close, | 892 | .close = fsl_dma_close, |
@@ -823,59 +896,114 @@ static struct snd_pcm_ops fsl_dma_ops = { | |||
823 | .pointer = fsl_dma_pointer, | 896 | .pointer = fsl_dma_pointer, |
824 | }; | 897 | }; |
825 | 898 | ||
826 | struct snd_soc_platform fsl_soc_platform = { | 899 | static int __devinit fsl_soc_dma_probe(struct platform_device *pdev, |
827 | .name = "fsl-dma", | 900 | const struct of_device_id *match) |
828 | .pcm_ops = &fsl_dma_ops, | 901 | { |
829 | .pcm_new = fsl_dma_new, | 902 | struct dma_object *dma; |
830 | .pcm_free = fsl_dma_free_dma_buffers, | 903 | struct device_node *np = pdev->dev.of_node; |
831 | }; | 904 | struct device_node *ssi_np; |
832 | EXPORT_SYMBOL_GPL(fsl_soc_platform); | 905 | struct resource res; |
906 | const uint32_t *iprop; | ||
907 | int ret; | ||
833 | 908 | ||
834 | /** | 909 | /* Find the SSI node that points to us. */ |
835 | * fsl_dma_configure: store the DMA parameters from the fabric driver. | 910 | ssi_np = find_ssi_node(np); |
836 | * | 911 | if (!ssi_np) { |
837 | * This function is called by the ASoC fabric driver to give us the DMA and | 912 | dev_err(&pdev->dev, "cannot find parent SSI node\n"); |
838 | * SSI channel information. | 913 | return -ENODEV; |
839 | * | 914 | } |
840 | * Unfortunately, ASoC V1 does make it possible to determine the DMA/SSI | 915 | |
841 | * data when a substream is created, so for now we need to store this data | 916 | ret = of_address_to_resource(ssi_np, 0, &res); |
842 | * into a global variable. This means that we can only support one DMA | 917 | if (ret) { |
843 | * controller, and hence only one SSI. | 918 | dev_err(&pdev->dev, "could not determine resources for %s\n", |
844 | */ | 919 | ssi_np->full_name); |
845 | int fsl_dma_configure(struct fsl_dma_info *dma_info) | 920 | of_node_put(ssi_np); |
921 | return ret; | ||
922 | } | ||
923 | |||
924 | dma = kzalloc(sizeof(*dma) + strlen(np->full_name), GFP_KERNEL); | ||
925 | if (!dma) { | ||
926 | dev_err(&pdev->dev, "could not allocate dma object\n"); | ||
927 | of_node_put(ssi_np); | ||
928 | return -ENOMEM; | ||
929 | } | ||
930 | |||
931 | strcpy(dma->path, np->full_name); | ||
932 | dma->dai.ops = &fsl_dma_ops; | ||
933 | dma->dai.pcm_new = fsl_dma_new; | ||
934 | dma->dai.pcm_free = fsl_dma_free_dma_buffers; | ||
935 | |||
936 | /* Store the SSI-specific information that we need */ | ||
937 | dma->ssi_stx_phys = res.start + offsetof(struct ccsr_ssi, stx0); | ||
938 | dma->ssi_srx_phys = res.start + offsetof(struct ccsr_ssi, srx0); | ||
939 | |||
940 | iprop = of_get_property(ssi_np, "fsl,fifo-depth", NULL); | ||
941 | if (iprop) | ||
942 | dma->ssi_fifo_depth = *iprop; | ||
943 | else | ||
944 | /* Older 8610 DTs didn't have the fifo-depth property */ | ||
945 | dma->ssi_fifo_depth = 8; | ||
946 | |||
947 | of_node_put(ssi_np); | ||
948 | |||
949 | ret = snd_soc_register_platform(&pdev->dev, &dma->dai); | ||
950 | if (ret) { | ||
951 | dev_err(&pdev->dev, "could not register platform\n"); | ||
952 | kfree(dma); | ||
953 | return ret; | ||
954 | } | ||
955 | |||
956 | dma->channel = of_iomap(np, 0); | ||
957 | dma->irq = irq_of_parse_and_map(np, 0); | ||
958 | |||
959 | dev_set_drvdata(&pdev->dev, dma); | ||
960 | |||
961 | return 0; | ||
962 | } | ||
963 | |||
964 | static int __devexit fsl_soc_dma_remove(struct platform_device *pdev) | ||
846 | { | 965 | { |
847 | static int initialized; | 966 | struct dma_object *dma = dev_get_drvdata(&pdev->dev); |
848 | 967 | ||
849 | /* We only support one DMA controller for now */ | 968 | snd_soc_unregister_platform(&pdev->dev); |
850 | if (initialized) | 969 | iounmap(dma->channel); |
851 | return 0; | 970 | irq_dispose_mapping(dma->irq); |
971 | kfree(dma); | ||
852 | 972 | ||
853 | dma_global_data.ssi_stx_phys = dma_info->ssi_stx_phys; | 973 | return 0; |
854 | dma_global_data.ssi_srx_phys = dma_info->ssi_srx_phys; | ||
855 | dma_global_data.dma_channel[0] = dma_info->dma_channel[0]; | ||
856 | dma_global_data.dma_channel[1] = dma_info->dma_channel[1]; | ||
857 | dma_global_data.irq[0] = dma_info->dma_irq[0]; | ||
858 | dma_global_data.irq[1] = dma_info->dma_irq[1]; | ||
859 | dma_global_data.assigned[0] = 0; | ||
860 | dma_global_data.assigned[1] = 0; | ||
861 | |||
862 | initialized = 1; | ||
863 | return 1; | ||
864 | } | 974 | } |
865 | EXPORT_SYMBOL_GPL(fsl_dma_configure); | ||
866 | 975 | ||
867 | static int __init fsl_soc_platform_init(void) | 976 | static const struct of_device_id fsl_soc_dma_ids[] = { |
977 | { .compatible = "fsl,ssi-dma-channel", }, | ||
978 | {} | ||
979 | }; | ||
980 | MODULE_DEVICE_TABLE(of, fsl_soc_dma_ids); | ||
981 | |||
982 | static struct of_platform_driver fsl_soc_dma_driver = { | ||
983 | .driver = { | ||
984 | .name = "fsl-pcm-audio", | ||
985 | .owner = THIS_MODULE, | ||
986 | .of_match_table = fsl_soc_dma_ids, | ||
987 | }, | ||
988 | .probe = fsl_soc_dma_probe, | ||
989 | .remove = __devexit_p(fsl_soc_dma_remove), | ||
990 | }; | ||
991 | |||
992 | static int __init fsl_soc_dma_init(void) | ||
868 | { | 993 | { |
869 | return snd_soc_register_platform(&fsl_soc_platform); | 994 | pr_info("Freescale Elo DMA ASoC PCM Driver\n"); |
995 | |||
996 | return of_register_platform_driver(&fsl_soc_dma_driver); | ||
870 | } | 997 | } |
871 | module_init(fsl_soc_platform_init); | ||
872 | 998 | ||
873 | static void __exit fsl_soc_platform_exit(void) | 999 | static void __exit fsl_soc_dma_exit(void) |
874 | { | 1000 | { |
875 | snd_soc_unregister_platform(&fsl_soc_platform); | 1001 | of_unregister_platform_driver(&fsl_soc_dma_driver); |
876 | } | 1002 | } |
877 | module_exit(fsl_soc_platform_exit); | 1003 | |
1004 | module_init(fsl_soc_dma_init); | ||
1005 | module_exit(fsl_soc_dma_exit); | ||
878 | 1006 | ||
879 | MODULE_AUTHOR("Timur Tabi <timur@freescale.com>"); | 1007 | MODULE_AUTHOR("Timur Tabi <timur@freescale.com>"); |
880 | MODULE_DESCRIPTION("Freescale Elo DMA ASoC PCM module"); | 1008 | MODULE_DESCRIPTION("Freescale Elo DMA ASoC PCM Driver"); |
881 | MODULE_LICENSE("GPL"); | 1009 | MODULE_LICENSE("GPL v2"); |