Skip to content

Commit

Permalink
drivers: dma: intel-adsp-hda: Correct DGCS:SCS bit for 32bit sample size
Browse files Browse the repository at this point in the history
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.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
  • Loading branch information
ujfalusi committed Oct 11, 2023
1 parent e0192e1 commit 50b473e
Showing 1 changed file with 31 additions and 7 deletions.
38 changes: 31 additions & 7 deletions drivers/dma/dma_intel_adsp_hda.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,15 @@ int intel_adsp_hda_dma_host_in_config(const struct device *dev,
*DGMBS(cfg->base, cfg->regblock_size, channel) =
blk_cfg->block_size & HDA_ALIGN_MASK;

/*
* The Sample Container Size (SCS) bit
* must be set to 0 for 32bit sample size (HD Audio container size)
* otherwise it must be set to 1 for sample size container
*/
if (dma_cfg->source_data_size <= 3) {
/* set the sample container set bit to 16bits */
*DGCS(cfg->base, cfg->regblock_size, channel) |= DGCS_SCS;
} else {
*DGCS(cfg->base, cfg->regblock_size, channel) &= ~DGCS_SCS;
}
}

Expand Down Expand Up @@ -90,9 +96,15 @@ int intel_adsp_hda_dma_host_out_config(const struct device *dev,
*DGMBS(cfg->base, cfg->regblock_size, channel) =
blk_cfg->block_size & HDA_ALIGN_MASK;

if (dma_cfg->dest_data_size <= 3) {
/* set the sample container set bit to 16bits */
/*
* The Sample Container Size (SCS) bit
* must be set to 0 for 32bit sample size (HD Audio container size)
* otherwise it must be set to 1 for sample size container
*/
if (dma_cfg->source_data_size <= 3) {
*DGCS(cfg->base, cfg->regblock_size, channel) |= DGCS_SCS;
} else {
*DGCS(cfg->base, cfg->regblock_size, channel) &= ~DGCS_SCS;
}
}

Expand Down Expand Up @@ -121,9 +133,15 @@ int intel_adsp_hda_dma_link_in_config(const struct device *dev,
res = intel_adsp_hda_set_buffer(cfg->base, cfg->regblock_size, channel, buf,
blk_cfg->block_size);

if (res == 0 && dma_cfg->dest_data_size <= 3) {
/* set the sample container set bit to 16bits */
/*
* The Sample Container Size (SCS) bit
* must be set to 0 for 32bit sample size (HD Audio container size)
* otherwise it must be set to 1 for sample size container
*/
if (dma_cfg->source_data_size <= 3) {
*DGCS(cfg->base, cfg->regblock_size, channel) |= DGCS_SCS;
} else {
*DGCS(cfg->base, cfg->regblock_size, channel) &= ~DGCS_SCS;
}

return res;
Expand Down Expand Up @@ -153,9 +171,15 @@ int intel_adsp_hda_dma_link_out_config(const struct device *dev,
res = intel_adsp_hda_set_buffer(cfg->base, cfg->regblock_size, channel, buf,
blk_cfg->block_size);

if (res == 0 && dma_cfg->source_data_size <= 3) {
/* set the sample container set bit to 16bits */
/*
* The Sample Container Size (SCS) bit
* must be set to 0 for 32bit sample size (HD Audio container size)
* otherwise it must be set to 1 for sample size container
*/
if (dma_cfg->source_data_size <= 3) {
*DGCS(cfg->base, cfg->regblock_size, channel) |= DGCS_SCS;
} else {
*DGCS(cfg->base, cfg->regblock_size, channel) &= ~DGCS_SCS;
}

return res;
Expand Down

0 comments on commit 50b473e

Please sign in to comment.