Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TEST] Deep-buffer with better DPCM locking #3201

Closed
wants to merge 49 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
13da002
ALSA: HDA: hdac_ext_stream: use consistent prefixes for variables
plbossart Sep 14, 2021
2396cc0
ASoC: SOF: Intel: hdac_ext_stream: consistent prefixes for variables/…
plbossart Sep 14, 2021
b096ecc
ASoC/SoundWire: dai: expand 'stream' concept beyond SoundWire
plbossart Aug 31, 2021
e5da9fc
ASoC: Intel/SOF: use set_stream() instead of set_tdm_slots() for HDAudio
plbossart Aug 31, 2021
d71ca51
ASOC: SOF: Intel: use snd_soc_dai_get_widget()
plbossart Aug 31, 2021
532860c
ASoC: SOF: Intel: hda-dai: remove support for TRIGGER_RESUME
plbossart Aug 31, 2021
2966f4d
ASOC: SOF: Intel: hda-dai: consistent naming for HDA DAI and HDA link…
plbossart Aug 31, 2021
77a3cf9
ASoC: SOF: Intel: hda-dai: simplify hda_dai_widget_update() prototype
plbossart Aug 31, 2021
71301fc
ASoC: SOF: Intel: hda-dai: split dailink and dai operations
plbossart Aug 31, 2021
269c3c2
ASoC: SOF: Intel: hda-dai: regroup dai and dailink operations
plbossart Sep 8, 2021
f902111
soundwire: intel: remove unnecessary initialization
plbossart Sep 9, 2021
70d78d3
soundwire: stream: remove unused parameter in sdw_stream_add_slave
plbossart Aug 27, 2021
5490a5a
soundwire: stream: add slave runtime to list earlier
plbossart Aug 27, 2021
7a1dcb7
soundwire: stream: simplify check on port range
plbossart Sep 9, 2021
c6ce553
soundwire: stream: add alloc/config/free helpers for ports
plbossart Sep 8, 2021
ec8d21f
soundwire: stream: split port allocation and configuration loops
plbossart Sep 9, 2021
7f134d6
soundwire: stream: split alloc and config in two functions
plbossart Sep 9, 2021
86bba9d
soundwire: stream: add 'slave' prefix for port range checks
plbossart Sep 9, 2021
aad6f1e
soundwire: stream: group sdw_port and sdw_master/slave_port functions
plbossart Sep 9, 2021
78b7f69
soundwire: stream: simplify sdw_alloc_master_rt()
plbossart Sep 9, 2021
15a7633
soundwire: stream: split sdw_alloc_master_rt() in alloc and config
plbossart Sep 9, 2021
cc559b1
soundwire: stream: move sdw_alloc_slave_rt() before 'master' helpers
plbossart Sep 9, 2021
62de7f5
soundwire: stream: split sdw_alloc_slave_rt() in alloc and config
plbossart Sep 9, 2021
b9e7394
soundwire: stream: group sdw_stream_ functions
plbossart Sep 9, 2021
e85b0a4
soundwire: stream: rename and move master/slave_rt_free routines
plbossart Sep 9, 2021
96a1736
soundwire: stream: move list addition to sdw_slave_alloc_rt()
plbossart Sep 9, 2021
793b7b0
soundwire: stream: separate alloc and config within sdw_stream_add_xxx()
plbossart Sep 9, 2021
87adb12
soundwire: stream: introduce sdw_slave_rt_find() helper
plbossart Sep 9, 2021
d3af764
soundwire: stream: sdw_stream_add_ functions can be called multiple t…
plbossart Sep 9, 2021
1bc7109
soundwire: stream: make enable/disable/deprepare idempotent
plbossart Aug 13, 2021
aa4d479
ASoC/soundwire: intel: simplify callbacks for params/hw_free
plbossart Aug 25, 2021
2527e30
Revert "soundwire: intel: trap TRIGGER_SUSPEND in .trigger callback"
plbossart Sep 9, 2021
63c98d0
soundwire: intel: improve suspend flows
ranj063 Jun 30, 2021
031ac4b
ASoC: SOF: sof-audio: flag errors on pipeline teardown
plbossart Aug 17, 2021
d3ce86b
ASOC: SOF: Intel: hda-dai: add hda_dai_hw_free_ipc() helper
plbossart Sep 14, 2021
ca8b267
ASoC: SOF: Intel: hda-dai: move code to deal with hda dai/dailink sus…
plbossart Sep 14, 2021
f5edd38
ASoC: SOF: Intel: hda-dai: reset dma_data and release stream
plbossart Sep 16, 2021
d4f82c0
ASoC: soc-pcm: remove snd_soc_dpcm_fe_can_update()
plbossart Sep 30, 2021
2ff7d5b
ASoC: soc-pcm: don't export local functions, use static
plbossart Sep 30, 2021
142815a
ASoC: soc-pcm: use proper indentation on 'continue'
plbossart Oct 7, 2021
eb0cba2
ASoC: soc-pcm: introduce snd_soc_dpcm_lock/unlock()
plbossart Sep 29, 2021
78efd2c
ASoC: soc-pcm: protect for_each_dpcm_be() loops
plbossart Oct 7, 2021
4ef2c8e
ASoC: soc-compress: protect for_each_dpcm_be() loops
plbossart Oct 7, 2021
baa9f3e
ASoC: sh: rcar: protect for_each_dpcm_be() loops
plbossart Oct 7, 2021
4c03c19
ASoC: fsl: asrc_dma: protect for_each_dpcm_be() loops
plbossart Oct 7, 2021
01ffb83
ASoC: soc-pcm: extend snd_soc_dpcm_lock() for non-atomic cases
plbossart Oct 7, 2021
ddbfd9d
ASoC: soc-pcm: serialize BE triggers
plbossart Oct 7, 2021
8a4bd38
ASoC: soc-pcm: test refcount before triggering
plbossart Aug 16, 2021
0ac4b26
ASoC: soc-pcm: fix BE handling of PAUSE_RELEASE
plbossart Aug 24, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions drivers/soundwire/cadence_master.h
Expand Up @@ -86,6 +86,7 @@ struct sdw_cdns_stream_config {
* @link_id: Master link id
* @hw_params: hw_params to be applied in .prepare step
* @suspended: status set when suspended, to be used in .prepare
* @paused: status set in .trigger, to be used in suspend
*/
struct sdw_cdns_dma_data {
char *name;
Expand All @@ -96,6 +97,7 @@ struct sdw_cdns_dma_data {
int link_id;
struct snd_pcm_hw_params *hw_params;
bool suspended;
bool paused;
};

/**
Expand Down
106 changes: 83 additions & 23 deletions drivers/soundwire/intel.c
Expand Up @@ -711,15 +711,15 @@ intel_pdi_alh_configure(struct sdw_intel *sdw, struct sdw_cdns_pdi *pdi)
}

static int intel_params_stream(struct sdw_intel *sdw,
struct snd_pcm_substream *substream,
int stream,
struct snd_soc_dai *dai,
struct snd_pcm_hw_params *hw_params,
int link_id, int alh_stream_id)
{
struct sdw_intel_link_res *res = sdw->link_res;
struct sdw_intel_stream_params_data params_data;

params_data.substream = substream;
params_data.stream = stream; /* direction */
params_data.dai = dai;
params_data.hw_params = hw_params;
params_data.link_id = link_id;
Expand All @@ -732,14 +732,14 @@ static int intel_params_stream(struct sdw_intel *sdw,
}

static int intel_free_stream(struct sdw_intel *sdw,
struct snd_pcm_substream *substream,
int stream,
struct snd_soc_dai *dai,
int link_id)
{
struct sdw_intel_link_res *res = sdw->link_res;
struct sdw_intel_stream_free_data free_data;

free_data.substream = substream;
free_data.stream = stream; /* direction */
free_data.dai = dai;
free_data.link_id = link_id;

Expand Down Expand Up @@ -871,12 +871,13 @@ static int intel_hw_params(struct snd_pcm_substream *substream,
sdw_cdns_config_stream(cdns, ch, dir, pdi);

/* store pdi and hw_params, may be needed in prepare step */
dma->paused = false;
dma->suspended = false;
dma->pdi = pdi;
dma->hw_params = params;

/* Inform DSP about PDI stream number */
ret = intel_params_stream(sdw, substream, dai, params,
ret = intel_params_stream(sdw, substream->stream, dai, params,
sdw->instance,
pdi->intel_alh_id);
if (ret)
Expand Down Expand Up @@ -953,7 +954,7 @@ static int intel_prepare(struct snd_pcm_substream *substream,
sdw_cdns_config_stream(cdns, ch, dir, dma->pdi);

/* Inform DSP about PDI stream number */
ret = intel_params_stream(sdw, substream, dai,
ret = intel_params_stream(sdw, substream->stream, dai,
dma->hw_params,
sdw->instance,
dma->pdi->intel_alh_id);
Expand Down Expand Up @@ -987,7 +988,7 @@ intel_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
return ret;
}

ret = intel_free_stream(sdw, substream, dai, sdw->instance);
ret = intel_free_stream(sdw, substream->stream, dai, sdw->instance);
if (ret < 0) {
dev_err(dai->dev, "intel_free_stream: failed %d\n", ret);
return ret;
Expand Down Expand Up @@ -1041,15 +1042,7 @@ static int intel_trigger(struct snd_pcm_substream *substream, int cmd, struct sn
struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai);
struct sdw_intel *sdw = cdns_to_intel(cdns);
struct sdw_cdns_dma_data *dma;

/*
* The .prepare callback is used to deal with xruns and resume operations. In the case
* of xruns, the DMAs and SHIM registers cannot be touched, but for resume operations the
* DMAs and SHIM registers need to be initialized.
* the .trigger callback is used to track the suspend case only.
*/
if (cmd != SNDRV_PCM_TRIGGER_SUSPEND)
return 0;
int ret;

dma = snd_soc_dai_get_dma_data(dai, substream);
if (!dma) {
Expand All @@ -1058,9 +1051,75 @@ static int intel_trigger(struct snd_pcm_substream *substream, int cmd, struct sn
return -EIO;
}

dma->suspended = true;
switch (cmd) {
case SNDRV_PCM_TRIGGER_SUSPEND:

/*
* The .prepare callback is used to deal with xruns and resume operations.
* In the case of xruns, the DMAs and SHIM registers cannot be touched,
* but for resume operations the DMAs and SHIM registers need to be initialized.
* the .trigger callback is used to track the suspend case only.
*/

dma->suspended = true;

return intel_free_stream(sdw, substream, dai, sdw->instance);
ret = intel_free_stream(sdw, substream->stream, dai, sdw->instance);
break;

case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
dma->paused = true;
break;
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
dma->paused = false;
break;
default:
break;
}

return ret;
}

static int intel_component_dais_suspend(struct snd_soc_component *component)
{
struct snd_soc_dai *dai;

/*
* In the corner case where a SUSPEND happens during a PAUSE, the ALSA core
* does not throw the TRIGGER_SUSPEND. This leaves the DAIs in an unbalanced state.
* Since the component suspend is called last, we can trap this corner case
* and force the DAIs to release their resources.
*/
for_each_component_dais(component, dai) {
struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai);
struct sdw_intel *sdw = cdns_to_intel(cdns);
struct sdw_cdns_dma_data *dma;
int stream;
int ret;

dma = dai->playback_dma_data;
stream = SNDRV_PCM_STREAM_PLAYBACK;
if (!dma) {
dma = dai->capture_dma_data;
stream = SNDRV_PCM_STREAM_CAPTURE;
}

if (!dma)
continue;

if (dma->suspended)
continue;

if (dma->paused) {
dma->suspended = true;

ret = intel_free_stream(sdw, stream, dai, sdw->instance);
if (ret < 0)
return ret;
}
}

return 0;
}

static const struct snd_soc_dai_ops intel_pcm_dai_ops = {
Expand All @@ -1070,8 +1129,8 @@ static const struct snd_soc_dai_ops intel_pcm_dai_ops = {
.hw_free = intel_hw_free,
.trigger = intel_trigger,
.shutdown = intel_shutdown,
.set_sdw_stream = intel_pcm_set_sdw_stream,
.get_sdw_stream = intel_get_sdw_stream,
.set_stream = intel_pcm_set_sdw_stream,
.get_stream = intel_get_sdw_stream,
};

static const struct snd_soc_dai_ops intel_pdm_dai_ops = {
Expand All @@ -1081,12 +1140,13 @@ static const struct snd_soc_dai_ops intel_pdm_dai_ops = {
.hw_free = intel_hw_free,
.trigger = intel_trigger,
.shutdown = intel_shutdown,
.set_sdw_stream = intel_pdm_set_sdw_stream,
.get_sdw_stream = intel_get_sdw_stream,
.set_stream = intel_pdm_set_sdw_stream,
.get_stream = intel_get_sdw_stream,
};

static const struct snd_soc_component_driver dai_component = {
.name = "soundwire",
.suspend = intel_component_dais_suspend,
};

static int intel_create_dai(struct sdw_cdns *cdns,
Expand Down Expand Up @@ -1554,7 +1614,7 @@ static int __maybe_unused intel_pm_prepare(struct device *dev)
struct sdw_intel *sdw = cdns_to_intel(cdns);
struct sdw_bus *bus = &cdns->bus;
u32 clock_stop_quirks;
int ret = 0;
int ret;

if (bus->prop.hw_disabled || !sdw->startup_done) {
dev_dbg(dev, "SoundWire master %d is disabled or not-started, ignoring\n",
Expand Down
8 changes: 4 additions & 4 deletions drivers/soundwire/qcom.c
Expand Up @@ -1019,8 +1019,8 @@ static int qcom_swrm_startup(struct snd_pcm_substream *substream,
ctrl->sruntime[dai->id] = sruntime;

for_each_rtd_codec_dais(rtd, i, codec_dai) {
ret = snd_soc_dai_set_sdw_stream(codec_dai, sruntime,
substream->stream);
ret = snd_soc_dai_set_stream(codec_dai, sruntime,
substream->stream);
if (ret < 0 && ret != -ENOTSUPP) {
dev_err(dai->dev, "Failed to set sdw stream on %s\n",
codec_dai->name);
Expand All @@ -1046,8 +1046,8 @@ static const struct snd_soc_dai_ops qcom_swrm_pdm_dai_ops = {
.hw_free = qcom_swrm_hw_free,
.startup = qcom_swrm_startup,
.shutdown = qcom_swrm_shutdown,
.set_sdw_stream = qcom_swrm_set_sdw_stream,
.get_sdw_stream = qcom_swrm_get_sdw_stream,
.set_stream = qcom_swrm_set_sdw_stream,
.get_stream = qcom_swrm_get_sdw_stream,
};

static const struct snd_soc_component_driver qcom_swrm_dai_component = {
Expand Down