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

dai: use ibs/obs for dma buffer size calculation #8983

Merged
merged 1 commit into from
Apr 5, 2024

Conversation

iganakov
Copy link
Contributor

Use ibs/obs size from ipc4_base_module_cfg to properly calculate period_count. It is especially important when FW aggregation mode is enabled and there are multiple DMAs allocated under one copier instance. That way period count for every DMA will be correctly evaluated and used for DMA buffer size calculation.
E.g. if dma_buffer_size received in Copier gtw config is 7680 bytes and FW should aggregate two streams 1ch/24_32bit/48kHz and 3ch/24_32bit/48kHz into one 4ch/24_32bit/48kHz stream, then FW will have to allocate two DMA's with sizes
1920 and 5760 bytes respectively and same 10 ms period for both to avoid glitches.

Copy link
Collaborator

@kv2019i kv2019i left a comment

Choose a reason for hiding this comment

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

Some questions inline.

else
dma_buff_ms_size = dd->ipc_config.dma_buffer_size / copier_cfg->base.obs;

period_count = MAX(period_count, dma_buff_ms_size);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Not quite following the logic. Period size may not always be 1ms, so how come we mix "period_count" and "dma_buff_ms_size" here? Or is the assumption that copier "ibs" must be aligned to period size of the pipeline. This would be good to capture in a comment. The variable name still needs to be corrected, it needs to be "dma_buff_size_in_periods" or something like that.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ibs/obs size depends on module processing domain, in case of Copier(LL) period will be 1ms. In Copier gtw config we receive DMA size aligned with ibs/obs. Based on previous assumptions we can calculate DMA buffer length in ms, which is also DMA period_count. I agree the name of the variable and comment should be changed.

@iganakov iganakov force-pushed the iganakov/dai_dma_buff_size branch from 95ea8f4 to fdb4a42 Compare March 26, 2024 12:47
Copy link
Member

@plbossart plbossart left a comment

Choose a reason for hiding this comment

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

not following this at all, sorry.

* should aggregate two streams 1ch/24_32bit/48kHz and 3ch/24_32bit/48kHz into one
* 4ch/24_32bit/48kHz stream, then FW will have to allocate two DMA's with sizes
* 1920 and 5760 bytes respectively and same 10 ms length (period_count) for both
* to avoid glitches.
Copy link
Member

Choose a reason for hiding this comment

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

this explanation is very very hard to follow. For playback we typically send the same data to different links. For capture, we typically have a symmetry between the number of channels on different links.

The explanation with 1 and 3 channels does not describe which scenario you are trying to address, and whether this is an actual use case in a product or a test configuration.

In addition, the aggregation is at the link level, and one would hope that we don't have a 10ms buffer? There's clearly a problem if we again have to rely on more buffers to get this solution to work properly...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@plbossart there is no need for any additional buffers. I'm not going to change FW aggregation mechanism.
I found a bug in Windows production scenario (actual use case). When trying to aggregate two streams with different number of channels e.g. 1ch and 3ch (mono and 2.1) and 10ms DMA buffer requested from driver multiple glitches and first stream delay were observed. This change fixes that special case.

else
dma_buff_length_ms = dd->ipc_config.dma_buffer_size / copier_cfg->base.obs;

period_count = MAX(period_count, dma_buff_length_ms);
Copy link
Member

@plbossart plbossart Mar 26, 2024

Choose a reason for hiding this comment

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

Comparing period_count and milliseconds doesn't seem quite right. Maybe it works for the special case of a period being exactly one ms...

Copy link
Collaborator

Choose a reason for hiding this comment

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

@iganakov Can you modify the variable/comments here? This file is generic SOF code and the assumption of period to be 1ms only applies to current Intel IPC4 configurations. I.e. in the same function, we use "dev->frames" to calculate period size. It's very odd in the same function to assume a hardcoded period size later on.

I'd propose:

uint32_t dma_buff_length_periods;

/* copier ibs/obs is set to size of one period */
if (dev->direction == SOF_IPC_STREAM_CAPTURE)
		dma_buff_length_periods = dd->ipc_config.dma_buffer_size / copier_cfg->base.ibs;
else
		dma_buff_length_periods = dd->ipc_config.dma_buffer_size / copier_cfg->base.obs;

period_count = MAX(period_count, dma_buff_length_periods);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It seems reasonable, thanks @kv2019i

Copy link
Collaborator

@kv2019i kv2019i left a comment

Choose a reason for hiding this comment

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

Left my proposal how to address the period/ms problem.

else
dma_buff_length_ms = dd->ipc_config.dma_buffer_size / copier_cfg->base.obs;

period_count = MAX(period_count, dma_buff_length_ms);
Copy link
Collaborator

Choose a reason for hiding this comment

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

@iganakov Can you modify the variable/comments here? This file is generic SOF code and the assumption of period to be 1ms only applies to current Intel IPC4 configurations. I.e. in the same function, we use "dev->frames" to calculate period size. It's very odd in the same function to assume a hardcoded period size later on.

I'd propose:

uint32_t dma_buff_length_periods;

/* copier ibs/obs is set to size of one period */
if (dev->direction == SOF_IPC_STREAM_CAPTURE)
		dma_buff_length_periods = dd->ipc_config.dma_buffer_size / copier_cfg->base.ibs;
else
		dma_buff_length_periods = dd->ipc_config.dma_buffer_size / copier_cfg->base.obs;

period_count = MAX(period_count, dma_buff_length_periods);

Use ibs/obs size from ipc4_base_module_cfg to properly calculate
period_count. It is especially important when FW aggregation mode
is enabled and there are multiple DMAs allocated under one copier
instance. That way period count for every DMA will be correctly
evaluated and used for DMA buffer size calculation.

Signed-off-by: Ievgen Ganakov <ievgen.ganakov@intel.com>
@iganakov iganakov force-pushed the iganakov/dai_dma_buff_size branch from fdb4a42 to 8c40f41 Compare April 5, 2024 09:42
@kv2019i kv2019i merged commit 2126e28 into thesofproject:main Apr 5, 2024
43 of 45 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants