Skip to content

Commit 6b54837

Browse files
committed
ASoC: SOF: Intel: hda-sdw-bpt: don't use hda_cl_prepare/cleanup helpers
We use the host and link DMA SoundWire BTP. But hda_cl_prepare() doesn't reserve the link DMA as code loader doesn't need. It works fine because we assume the SwoundWire BPT will not run with audio streams simultaneously. Create dedicated prepare/cleanup functions to allow running BTP and audio stream simultaneously. Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
1 parent 33deb34 commit 6b54837

1 file changed

Lines changed: 85 additions & 2 deletions

File tree

sound/soc/sof/intel/hda-sdw-bpt.c

Lines changed: 85 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,89 @@ static int chain_dma_trigger(struct snd_sof_dev *sdev, unsigned int stream_tag,
9090
return sof_ipc_tx_message_no_reply(sdev->ipc, &msg, 0);
9191
}
9292

93+
static struct hdac_ext_stream *
94+
hda_sdw_prepare(struct device *dev, unsigned int format, unsigned int size,
95+
struct snd_dma_buffer *dmab, int direction)
96+
{
97+
struct snd_sof_dev *sdev = dev_get_drvdata(dev);
98+
struct hdac_ext_stream *hext_stream ;
99+
struct hdac_stream *hstream;
100+
int ret;
101+
102+
hext_stream = hda_dsp_stream_pair_get(sdev, direction, 0);
103+
if (!hext_stream) {
104+
dev_err(sdev->dev, "%s: no stream available\n", __func__);
105+
return ERR_PTR(-ENODEV);
106+
}
107+
hstream = &hext_stream->hstream;
108+
hstream->substream = NULL;
109+
110+
ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV_SG, dev, size, dmab);
111+
if (ret < 0) {
112+
dev_err(sdev->dev, "%s: memory alloc failed: %d\n",
113+
__func__, ret);
114+
goto out_put;
115+
}
116+
117+
hstream->period_bytes = 0; /* initialize period_bytes */
118+
hstream->format_val = format;
119+
hstream->bufsize = size;
120+
121+
ret = hda_dsp_stream_hw_params(sdev, hext_stream, dmab, NULL);
122+
if (ret < 0) {
123+
dev_err(sdev->dev, "%s: hdac prepare failed: %d\n", __func__, ret);
124+
goto out_free;
125+
}
126+
hda_dsp_stream_spib_config(sdev, hext_stream, HDA_DSP_SPIB_ENABLE, size);
127+
128+
return hext_stream;
129+
130+
out_free:
131+
snd_dma_free_pages(dmab);
132+
dmab->area = NULL;
133+
dmab->bytes = 0;
134+
hstream->bufsize = 0;
135+
hstream->format_val = 0;
136+
out_put:
137+
hda_dsp_stream_pair_put(sdev, direction, hstream->stream_tag);
138+
return ERR_PTR(ret);
139+
}
140+
141+
static int hda_sdw_cleanup(struct device *dev, struct snd_dma_buffer *dmab,
142+
struct hdac_ext_stream *hext_stream)
143+
{
144+
struct snd_sof_dev *sdev = dev_get_drvdata(dev);
145+
struct hdac_stream *hstream = hdac_stream(hext_stream);
146+
int sd_offset = SOF_STREAM_SD_OFFSET(hstream);
147+
int ret = 0;
148+
149+
if (hstream->direction == SNDRV_PCM_STREAM_PLAYBACK)
150+
ret = hda_dsp_stream_spib_config(sdev, hext_stream, HDA_DSP_SPIB_DISABLE, 0);
151+
else
152+
snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, sd_offset,
153+
SOF_HDA_SD_CTL_DMA_START, 0);
154+
155+
hda_dsp_stream_pair_put(sdev, hstream->direction, hstream->stream_tag);
156+
157+
hstream->substream = NULL;
158+
159+
/* reset BDL address */
160+
snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
161+
sd_offset + SOF_HDA_ADSP_REG_SD_BDLPL, 0);
162+
snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
163+
sd_offset + SOF_HDA_ADSP_REG_SD_BDLPU, 0);
164+
165+
snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR, sd_offset, 0);
166+
167+
snd_dma_free_pages(dmab);
168+
dmab->area = NULL;
169+
dmab->bytes = 0;
170+
hstream->bufsize = 0;
171+
hstream->format_val = 0;
172+
173+
return ret;
174+
}
175+
93176
static int hda_sdw_bpt_dma_prepare(struct device *dev, struct hdac_ext_stream **sdw_bpt_stream,
94177
struct snd_dma_buffer *dmab_bdl, u32 bpt_num_bytes,
95178
unsigned int num_channels, int direction)
@@ -118,7 +201,7 @@ static int hda_sdw_bpt_dma_prepare(struct device *dev, struct hdac_ext_stream **
118201

119202
dev_dbg(dev, "direction %d format_val %#x\n", direction, format);
120203

121-
bpt_stream = hda_cl_prepare(dev, format, bpt_num_bytes, dmab_bdl, false, direction, false);
204+
bpt_stream = hda_sdw_prepare(dev, format, bpt_num_bytes, dmab_bdl, direction);
122205
if (IS_ERR(bpt_stream)) {
123206
dev_err(sdev->dev, "%s: SDW BPT DMA prepare failed: dir %d\n",
124207
__func__, direction);
@@ -162,7 +245,7 @@ static int hda_sdw_bpt_dma_deprepare(struct device *dev, struct hdac_ext_stream
162245
u32 mask;
163246
int ret;
164247

165-
ret = hda_cl_cleanup(sdev->dev, dmab_bdl, false, sdw_bpt_stream);
248+
ret = hda_sdw_cleanup(sdev->dev, dmab_bdl, sdw_bpt_stream);
166249
if (ret < 0) {
167250
dev_err(sdev->dev, "%s: SDW BPT DMA cleanup failed\n",
168251
__func__);

0 commit comments

Comments
 (0)