Skip to content

Commit c1574ab

Browse files
committed
ASoC: SOF: hda: couple host and link DMA during FE hw_free
Host and link DMA are decoupled during FE hw_params. So, they must be coupled in hw_free if the link DMA channel is idle. Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
1 parent 6a64045 commit c1574ab

File tree

7 files changed

+46
-0
lines changed

7 files changed

+46
-0
lines changed

sound/soc/sof/intel/apl.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ const struct snd_sof_dsp_ops sof_apl_ops = {
6161
.pcm_open = hda_dsp_pcm_open,
6262
.pcm_close = hda_dsp_pcm_close,
6363
.pcm_hw_params = hda_dsp_pcm_hw_params,
64+
.pcm_hw_free = hda_dsp_stream_hw_free,
6465
.pcm_trigger = hda_dsp_pcm_trigger,
6566
.pcm_pointer = hda_dsp_pcm_pointer,
6667

sound/soc/sof/intel/cnl.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ const struct snd_sof_dsp_ops sof_cnl_ops = {
217217
.pcm_open = hda_dsp_pcm_open,
218218
.pcm_close = hda_dsp_pcm_close,
219219
.pcm_hw_params = hda_dsp_pcm_hw_params,
220+
.pcm_hw_free = hda_dsp_stream_hw_free,
220221
.pcm_trigger = hda_dsp_pcm_trigger,
221222
.pcm_pointer = hda_dsp_pcm_pointer,
222223

sound/soc/sof/intel/hda-stream.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,26 @@ int hda_dsp_stream_hw_params(struct snd_sof_dev *sdev,
438438
return ret;
439439
}
440440

441+
int hda_dsp_stream_hw_free(struct snd_sof_dev *sdev,
442+
struct snd_pcm_substream *substream)
443+
{
444+
struct hdac_stream *stream = substream->runtime->private_data;
445+
struct hdac_ext_stream *link_dev = container_of(stream,
446+
struct hdac_ext_stream,
447+
hstream);
448+
struct hdac_bus *bus = sof_to_bus(sdev);
449+
u32 mask = 0x1 << stream->index;
450+
451+
spin_lock(&bus->reg_lock);
452+
/* couple host and link DMA if link DMA channel is idle */
453+
if (!link_dev->link_locked)
454+
snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR,
455+
SOF_HDA_REG_PP_PPCTL, mask, 0);
456+
spin_unlock(&bus->reg_lock);
457+
458+
return 0;
459+
}
460+
441461
irqreturn_t hda_dsp_stream_interrupt(int irq, void *context)
442462
{
443463
struct hdac_bus *bus = context;

sound/soc/sof/intel/hda.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,8 @@ int hda_dsp_pcm_hw_params(struct snd_sof_dev *sdev,
466466
struct snd_pcm_substream *substream,
467467
struct snd_pcm_hw_params *params,
468468
struct sof_ipc_stream_params *ipc_params);
469+
int hda_dsp_stream_hw_free(struct snd_sof_dev *sdev,
470+
struct snd_pcm_substream *substream);
469471
int hda_dsp_pcm_trigger(struct snd_sof_dev *sdev,
470472
struct snd_pcm_substream *substream, int cmd);
471473
snd_pcm_uframes_t hda_dsp_pcm_pointer(struct snd_sof_dev *sdev,

sound/soc/sof/ops.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,17 @@ snd_sof_pcm_platform_hw_params(struct snd_sof_dev *sdev,
287287
return 0;
288288
}
289289

290+
/* host stream hw free */
291+
static inline int
292+
snd_sof_pcm_platform_hw_free(struct snd_sof_dev *sdev,
293+
struct snd_pcm_substream *substream)
294+
{
295+
if (sof_ops(sdev) && sof_ops(sdev)->pcm_hw_free)
296+
return sof_ops(sdev)->pcm_hw_free(sdev, substream);
297+
298+
return 0;
299+
}
300+
290301
/* host stream trigger */
291302
static inline int
292303
snd_sof_pcm_platform_trigger(struct snd_sof_dev *sdev,

sound/soc/sof/pcm.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,13 @@ static int sof_pcm_hw_free(struct snd_pcm_substream *substream)
251251

252252
cancel_work_sync(&spcm->stream[substream->stream].period_elapsed_work);
253253

254+
if (ret < 0)
255+
return ret;
256+
257+
ret = snd_sof_pcm_platform_hw_free(sdev, substream);
258+
if (ret < 0)
259+
dev_err(sdev->dev, "error: platform hw free failed\n");
260+
254261
return ret;
255262
}
256263

sound/soc/sof/sof-priv.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,10 @@ struct snd_sof_dsp_ops {
143143
struct snd_pcm_hw_params *params,
144144
struct sof_ipc_stream_params *ipc_params); /* optional */
145145

146+
/* host stream hw_free */
147+
int (*pcm_hw_free)(struct snd_sof_dev *sdev,
148+
struct snd_pcm_substream *substream); /* optional */
149+
146150
/* host stream trigger */
147151
int (*pcm_trigger)(struct snd_sof_dev *sdev,
148152
struct snd_pcm_substream *substream,

0 commit comments

Comments
 (0)