Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 21 additions & 8 deletions sound/soc/sof/intel/hda-pcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
#define SDnFMT_BITS(x) ((x) << 4)
#define SDnFMT_CHAN(x) ((x) << 0)

#define HDA_MAX_PERIOD_TIME_HEADROOM 10

static bool hda_always_enable_dmi_l1;
module_param_named(always_enable_dmi_l1, hda_always_enable_dmi_l1, bool, 0444);
MODULE_PARM_DESC(always_enable_dmi_l1, "SOF HDA always enable DMI l1");
Expand Down Expand Up @@ -291,19 +293,30 @@ int hda_dsp_pcm_open(struct snd_sof_dev *sdev,
* On playback start the DMA will transfer dsp_max_burst_size_in_ms
* amount of data in one initial burst to fill up the host DMA buffer.
* Consequent DMA burst sizes are shorter and their length can vary.
* To make sure that userspace allocate large enough ALSA buffer we need
* to place a constraint on the buffer time.
* To avoid immediate xrun by the initial burst we need to place
* constraint on the period size (via PERIOD_TIME) to cover the size of
* the host buffer.
* We need to add headroom of max 10ms as the firmware needs time to
* settle to the 1ms pacing and initially it can run faster for few
* internal periods.
*
* On capture the DMA will transfer 1ms chunks.
*
* Exact dsp_max_burst_size_in_ms constraint is racy, so set the
* constraint to a minimum of 2x dsp_max_burst_size_in_ms.
*/
if (spcm->stream[direction].dsp_max_burst_size_in_ms)
if (spcm->stream[direction].dsp_max_burst_size_in_ms) {
unsigned int period_time = spcm->stream[direction].dsp_max_burst_size_in_ms;

/*
* add headroom over the maximum burst size to cover the time
* needed for the DMA pace to settle.
* Limit the headroom time to HDA_MAX_PERIOD_TIME_HEADROOM
*/
period_time += min(period_time, HDA_MAX_PERIOD_TIME_HEADROOM);

snd_pcm_hw_constraint_minmax(substream->runtime,
SNDRV_PCM_HW_PARAM_BUFFER_TIME,
spcm->stream[direction].dsp_max_burst_size_in_ms * USEC_PER_MSEC * 2,
SNDRV_PCM_HW_PARAM_PERIOD_TIME,
period_time * USEC_PER_MSEC,
UINT_MAX);
}

/* binding pcm substream to hda stream */
substream->runtime->private_data = &dsp_stream->hstream;
Expand Down
9 changes: 7 additions & 2 deletions sound/soc/sof/ipc4-topology.c
Original file line number Diff line number Diff line change
Expand Up @@ -671,8 +671,13 @@ static int sof_ipc4_widget_setup_pcm(struct snd_sof_widget *swidget)
swidget->tuples,
swidget->num_tuples, sizeof(u32), 1);
/* Set default DMA buffer size if it is not specified in topology */
if (!sps->dsp_max_burst_size_in_ms)
sps->dsp_max_burst_size_in_ms = SOF_IPC4_MIN_DMA_BUFFER_SIZE;
if (!sps->dsp_max_burst_size_in_ms) {
struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget;
struct sof_ipc4_pipeline *pipeline = pipe_widget->private;

sps->dsp_max_burst_size_in_ms = pipeline->use_chain_dma ?
SOF_IPC4_CHAIN_DMA_BUFFER_SIZE : SOF_IPC4_MIN_DMA_BUFFER_SIZE;
}
} else {
/* Capture data is copied from DSP to host in 1ms bursts */
spcm->stream[dir].dsp_max_burst_size_in_ms = 1;
Expand Down
7 changes: 5 additions & 2 deletions sound/soc/sof/ipc4-topology.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,11 @@
#define SOF_IPC4_CHAIN_DMA_NODE_ID 0x7fffffff
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor nit in commit message: the firmware change was for a particular Intel platforms. But yeah, in practise it covers all platforms covered by this ipc4 kernel code at the moment.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the fw change was for all IPC4 platforms (all Intel platforms which can run IPC4), it is fair to say that for IPC4 the host buffer size has been 4ms and not 2ms.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, that is true, but it's just hard to verify this looking at the commit and then looking at the FW commit. Reader has to have outside information that Intel ACE variant happens to be the only IPC4 supporting platform and the various other platforms in SOF (with 2ms default) are never used in IPC4 mode.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CAVS2.5 works (but not officially supported) with IPC4 and that also uses 4ms host buffer. At this time IPC4 as such uses 4ms host buffer on all supported platforms.

Yes, we will have support for this information to be queried from firmware and can get rid of this define, but as far as IPC4 concerns, we have been mistakenly assumed 2ms host buffer when in fact IPC4 is using 4ms.

#define SOF_IPC4_INVALID_NODE_ID 0xffffffff

/* FW requires minimum 2ms DMA buffer size */
#define SOF_IPC4_MIN_DMA_BUFFER_SIZE 2
/* FW requires minimum 4ms DMA buffer size */
#define SOF_IPC4_MIN_DMA_BUFFER_SIZE 4

/* ChainDMA in fw uses 5ms DMA buffer */
#define SOF_IPC4_CHAIN_DMA_BUFFER_SIZE 5

/*
* The base of multi-gateways. Multi-gateways addressing starts from
Expand Down
Loading