summaryrefslogtreecommitdiffstats
path: root/sound/hda/hdac_stream.c
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2022-12-05 19:01:57 +0000
committerMark Brown <broonie@kernel.org>2022-12-05 19:01:57 +0000
commit8e378ea10b0fd397007f7e52429c7b27f0143583 (patch)
tree79c7a25024c726932f7f06bb8385778a04b2a807 /sound/hda/hdac_stream.c
parent1b41beaa7a58467505ec3023af8aad74f878b888 (diff)
parent85ac9c8c8eed76e8a320a9e017c6d36e2a52745b (diff)
downloadlinux-8e378ea10b0fd397007f7e52429c7b27f0143583.tar.gz
linux-8e378ea10b0fd397007f7e52429c7b27f0143583.tar.bz2
linux-8e378ea10b0fd397007f7e52429c7b27f0143583.zip
ASoC: Intel: avs: Data probing and fw logging
Merge series from Cezary Rojewski <cezary.rojewski@intel.com>: The patchset focuses on debug functionality for the avs-driver. Two major blocks are covered here: data probing and AudioDSP firmware logging. Both are configured and controlled through debugfs. Data probing is a AudioDSP debug functionality which allows for gathering the actual data that is being routed to or from a module. Helps in debugging its processing capabilities - navigate to a specific module which may have caused a glitch within a pipeline (set of modules bound together). First few allow for assigning compress stream to a HDAudio stream, what is currently limited to pcm substreams only. These patches were already present on this list and reviewed in the past [1]. The next few tidy existing debug-related code up so it's ready for addition of new functionalities and make it clear which part of the avs is debug related and which is not. These also simplify the existing locking around the trace fifo. Afterward, debug-related IPCs are defined along with stub soc-component and compress DAI operations. Not much is done there as it's not a standard PCM streaming scenario. Most code found in compress operations is inherited from the HOST side of HDAudio streaming found in pcm.c file of the driver. Finally, a debugfs file operations are defined. These facilitate connecting to DSP modules from which the data shall be gathered as well as control and configuration of firmware logging. Additionally, entries are added to allow for dumping snapshots of key memory windows.
Diffstat (limited to 'sound/hda/hdac_stream.c')
-rw-r--r--sound/hda/hdac_stream.c51
1 files changed, 32 insertions, 19 deletions
diff --git a/sound/hda/hdac_stream.c b/sound/hda/hdac_stream.c
index 3b250ee7f6a7..8f625402505f 100644
--- a/sound/hda/hdac_stream.c
+++ b/sound/hda/hdac_stream.c
@@ -7,6 +7,7 @@
#include <linux/delay.h>
#include <linux/export.h>
#include <linux/clocksource.h>
+#include <sound/compress_driver.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/hdaudio.h>
@@ -487,11 +488,20 @@ int snd_hdac_stream_setup_periods(struct hdac_stream *azx_dev)
{
struct hdac_bus *bus = azx_dev->bus;
struct snd_pcm_substream *substream = azx_dev->substream;
- struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_compr_stream *cstream = azx_dev->cstream;
+ struct snd_pcm_runtime *runtime = NULL;
+ struct snd_dma_buffer *dmab;
__le32 *bdl;
int i, ofs, periods, period_bytes;
int pos_adj, pos_align;
+ if (substream) {
+ runtime = substream->runtime;
+ dmab = snd_pcm_get_dma_buf(substream);
+ } else if (cstream) {
+ dmab = snd_pcm_get_dma_buf(cstream);
+ }
+
/* reset BDL address */
snd_hdac_stream_writel(azx_dev, SD_BDLPL, 0);
snd_hdac_stream_writel(azx_dev, SD_BDLPU, 0);
@@ -505,7 +515,7 @@ int snd_hdac_stream_setup_periods(struct hdac_stream *azx_dev)
azx_dev->frags = 0;
pos_adj = bus->bdl_pos_adj;
- if (!azx_dev->no_period_wakeup && pos_adj > 0) {
+ if (runtime && !azx_dev->no_period_wakeup && pos_adj > 0) {
pos_align = pos_adj;
pos_adj = DIV_ROUND_UP(pos_adj * runtime->rate, 48000);
if (!pos_adj)
@@ -518,8 +528,7 @@ int snd_hdac_stream_setup_periods(struct hdac_stream *azx_dev)
pos_adj);
pos_adj = 0;
} else {
- ofs = setup_bdle(bus, snd_pcm_get_dma_buf(substream),
- azx_dev,
+ ofs = setup_bdle(bus, dmab, azx_dev,
&bdl, ofs, pos_adj, true);
if (ofs < 0)
goto error;
@@ -529,13 +538,11 @@ int snd_hdac_stream_setup_periods(struct hdac_stream *azx_dev)
for (i = 0; i < periods; i++) {
if (i == periods - 1 && pos_adj)
- ofs = setup_bdle(bus, snd_pcm_get_dma_buf(substream),
- azx_dev, &bdl, ofs,
- period_bytes - pos_adj, 0);
+ ofs = setup_bdle(bus, dmab, azx_dev,
+ &bdl, ofs, period_bytes - pos_adj, 0);
else
- ofs = setup_bdle(bus, snd_pcm_get_dma_buf(substream),
- azx_dev, &bdl, ofs,
- period_bytes,
+ ofs = setup_bdle(bus, dmab, azx_dev,
+ &bdl, ofs, period_bytes,
!azx_dev->no_period_wakeup);
if (ofs < 0)
goto error;
@@ -560,26 +567,32 @@ EXPORT_SYMBOL_GPL(snd_hdac_stream_setup_periods);
int snd_hdac_stream_set_params(struct hdac_stream *azx_dev,
unsigned int format_val)
{
-
- unsigned int bufsize, period_bytes;
struct snd_pcm_substream *substream = azx_dev->substream;
- struct snd_pcm_runtime *runtime;
+ struct snd_compr_stream *cstream = azx_dev->cstream;
+ unsigned int bufsize, period_bytes;
+ unsigned int no_period_wakeup;
int err;
- if (!substream)
+ if (substream) {
+ bufsize = snd_pcm_lib_buffer_bytes(substream);
+ period_bytes = snd_pcm_lib_period_bytes(substream);
+ no_period_wakeup = substream->runtime->no_period_wakeup;
+ } else if (cstream) {
+ bufsize = cstream->runtime->buffer_size;
+ period_bytes = cstream->runtime->fragment_size;
+ no_period_wakeup = 0;
+ } else {
return -EINVAL;
- runtime = substream->runtime;
- bufsize = snd_pcm_lib_buffer_bytes(substream);
- period_bytes = snd_pcm_lib_period_bytes(substream);
+ }
if (bufsize != azx_dev->bufsize ||
period_bytes != azx_dev->period_bytes ||
format_val != azx_dev->format_val ||
- runtime->no_period_wakeup != azx_dev->no_period_wakeup) {
+ no_period_wakeup != azx_dev->no_period_wakeup) {
azx_dev->bufsize = bufsize;
azx_dev->period_bytes = period_bytes;
azx_dev->format_val = format_val;
- azx_dev->no_period_wakeup = runtime->no_period_wakeup;
+ azx_dev->no_period_wakeup = no_period_wakeup;
err = snd_hdac_stream_setup_periods(azx_dev);
if (err < 0)
return err;