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

drivers: dma: intel-adsp-hda: Correct DGCS:SCS bit for 32bit sample size #63784

Merged

Conversation

ujfalusi
Copy link
Collaborator

@ujfalusi ujfalusi commented Oct 11, 2023

If the channel was used for 16bit in the once, subsequent 32bit sample size audio will be broken since the SCS bit remains set.

Example sequence with SOF:
normal audio playback with 16bit
ChainDMA audio playback with 16bit
normal audio playback with 16bit

The last playback results garbled audio.

Introduce intel_adsp_hda_set_sample_container_size() helper function to handle the SCS bit and use it in the driver.

kv2019i
kv2019i previously approved these changes Oct 11, 2023
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.

Excellent find @ujfalusi !

This fixes SOF bug tracked as thesofproject/sof#8236

abonislawski
abonislawski previously approved these changes Oct 11, 2023
tmleman
tmleman previously approved these changes Oct 11, 2023
Copy link

@jsarha jsarha left a comment

Choose a reason for hiding this comment

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

Makes perfect sense.

jxstelter
jxstelter previously approved these changes Oct 11, 2023
@mengdonglin
Copy link

If the channel was used for 16bit in the once, subsequent 32bit sample size audio will be broken since the SCS bit remains set.

Example sequence with SOF:
normal audio playback with 16bit
ChainDMA audio playback with 16bit
normal audio playback with 16bit
The last playback results garbled audio.

@ujfalusi I have silly question. The last normal playback is still 16bit, why it results garbled audio? Or does chain DMA uses 16bit container, and normal playback use 32bit container with 16bit valid?

@ujfalusi
Copy link
Collaborator Author

If the channel was used for 16bit in the once, subsequent 32bit sample size audio will be broken since the SCS bit remains set.
Example sequence with SOF:
normal audio playback with 16bit
ChainDMA audio playback with 16bit
normal audio playback with 16bit
The last playback results garbled audio.

@ujfalusi I have silly question. The last normal playback is still 16bit, why it results garbled audio? Or does chain DMA uses 16bit container, and normal playback use 32bit container with 16bit valid?

Yes, that is correct:
With ChainDMA the linkDMA is configured to the same format as the hostDMA - the firmware merely forwards the data stream.
When ChainDMA is not used the linkDMA is most of the time have fixed configuration of 32bit sample size.
The firmware converts the 16bit from host to 32bit internally and it is (tries to) sending 32bit sample size to the codec, but the linkDMA retained the SCS=1 from the ChainDMA use, the codec is also configured to expect 32bit data, but the configuration of HDA and DMA is off and that causes garbled audio.

drivers/dma/dma_intel_adsp_hda.c Outdated Show resolved Hide resolved
@ujfalusi
Copy link
Collaborator Author

Changes since v1:

  • Braces added around the if () else statements

fabiobaltieri
fabiobaltieri previously approved these changes Oct 11, 2023
@fabiobaltieri fabiobaltieri added this to the v3.5.0 milestone Oct 11, 2023
abonislawski
abonislawski previously approved these changes Oct 11, 2023
Copy link
Collaborator

@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.

The host side is fine, the link has a change that's not very clear @ujfalusi

*DGCS(cfg->base, cfg->regblock_size, channel) |= DGCS_SCS;
} else {
*DGCS(cfg->base, cfg->regblock_size, channel) &= ~DGCS_SCS;
Copy link
Collaborator

Choose a reason for hiding this comment

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

this one changes the behavior if res != 0, is this intentional @ujfalusi?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Oh, I have missed that, sorry I will update as soon as I can.

*DGCS(cfg->base, cfg->regblock_size, channel) |= DGCS_SCS;
} else {
*DGCS(cfg->base, cfg->regblock_size, channel) &= ~DGCS_SCS;
Copy link
Collaborator

Choose a reason for hiding this comment

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

same here, change with res!=0?

Copy link
Collaborator

@teburd teburd left a comment

Choose a reason for hiding this comment

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

Missed the ret != 0 drop that @plbossart found while looking at this on my phone screen. This does need fixing before this should be merged, so marked -1

@teburd teburd added the bug The issue is a bug, or the PR is fixing a bug label Oct 11, 2023
@ujfalusi ujfalusi force-pushed the peter/pr/hda_dma_scs_bit_clear_01 branch from 50b473e to 59600b2 Compare October 11, 2023 15:41
@ujfalusi
Copy link
Collaborator Author

Changes since v2:

  • do not ignore the res from intel_adsp_hda_set_buffer() in the linkDMA configurations

@ujfalusi
Copy link
Collaborator Author

One more try, sorry, I missed something else

@ujfalusi ujfalusi force-pushed the peter/pr/hda_dma_scs_bit_clear_01 branch from 59600b2 to b9a3498 Compare October 11, 2023 15:53
@ujfalusi
Copy link
Collaborator Author

Changes since v3:

  • corrected the copy-paste issue of replacing dest_data_size with source_data_size.

If the channel was used for 16bit in the once, subsequent 32bit sample size
audio will be broken since the SCS bit remains set.

Example sequence with SOF:
normal audio playback with 16bit
ChainDMA audio playback with 16bit
normal audio playback with 16bit

The last playback results garbled audio.

Introduce intel_adsp_hda_set_sample_container_size() helper function
to handle the SCS bit and use it in the driver.


Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
@zephyrbot zephyrbot added the platform: Intel ADSP Intel Audio platforms label Oct 12, 2023
@ujfalusi
Copy link
Collaborator Author

Changes since v4:

  • a bit more elegant way is to introduce intel_adsp_hda_set_sample_container_size() and use that in the driver
  • the resulting code is easier to read and shorter.

*DGCS(base, regblock_size, sid) |= DGCS_SCS;
} else {
*DGCS(base, regblock_size, sid) &= ~DGCS_SCS;
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

do we need braces for the if/else?

Copy link
Collaborator

Choose a reason for hiding this comment

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

@ranj063 yes, this is actually required in Zephyr

@jhedberg jhedberg merged commit 8dfa116 into zephyrproject-rtos:main Oct 12, 2023
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: DMA Direct Memory Access bug The issue is a bug, or the PR is fixing a bug platform: Intel ADSP Intel Audio platforms
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet