drivers: dma: intel-adsp-hda: Correct DGCS:SCS bit for 32bit sample 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>
This commit is contained in:
parent
16bb226593
commit
8dfa116750
2 changed files with 32 additions and 16 deletions
|
@ -53,10 +53,8 @@ int intel_adsp_hda_dma_host_in_config(const struct device *dev,
|
||||||
*DGMBS(cfg->base, cfg->regblock_size, channel) =
|
*DGMBS(cfg->base, cfg->regblock_size, channel) =
|
||||||
blk_cfg->block_size & HDA_ALIGN_MASK;
|
blk_cfg->block_size & HDA_ALIGN_MASK;
|
||||||
|
|
||||||
if (dma_cfg->source_data_size <= 3) {
|
intel_adsp_hda_set_sample_container_size(cfg->base, cfg->regblock_size, channel,
|
||||||
/* set the sample container set bit to 16bits */
|
dma_cfg->source_data_size);
|
||||||
*DGCS(cfg->base, cfg->regblock_size, channel) |= DGCS_SCS;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
@ -90,10 +88,8 @@ int intel_adsp_hda_dma_host_out_config(const struct device *dev,
|
||||||
*DGMBS(cfg->base, cfg->regblock_size, channel) =
|
*DGMBS(cfg->base, cfg->regblock_size, channel) =
|
||||||
blk_cfg->block_size & HDA_ALIGN_MASK;
|
blk_cfg->block_size & HDA_ALIGN_MASK;
|
||||||
|
|
||||||
if (dma_cfg->dest_data_size <= 3) {
|
intel_adsp_hda_set_sample_container_size(cfg->base, cfg->regblock_size, channel,
|
||||||
/* set the sample container set bit to 16bits */
|
dma_cfg->dest_data_size);
|
||||||
*DGCS(cfg->base, cfg->regblock_size, channel) |= DGCS_SCS;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
@ -120,10 +116,9 @@ int intel_adsp_hda_dma_link_in_config(const struct device *dev,
|
||||||
buf = (uint8_t *)(uintptr_t)(blk_cfg->dest_address);
|
buf = (uint8_t *)(uintptr_t)(blk_cfg->dest_address);
|
||||||
res = intel_adsp_hda_set_buffer(cfg->base, cfg->regblock_size, channel, buf,
|
res = intel_adsp_hda_set_buffer(cfg->base, cfg->regblock_size, channel, buf,
|
||||||
blk_cfg->block_size);
|
blk_cfg->block_size);
|
||||||
|
if (res == 0) {
|
||||||
if (res == 0 && dma_cfg->dest_data_size <= 3) {
|
intel_adsp_hda_set_sample_container_size(cfg->base, cfg->regblock_size, channel,
|
||||||
/* set the sample container set bit to 16bits */
|
dma_cfg->dest_data_size);
|
||||||
*DGCS(cfg->base, cfg->regblock_size, channel) |= DGCS_SCS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
@ -152,10 +147,9 @@ 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,
|
res = intel_adsp_hda_set_buffer(cfg->base, cfg->regblock_size, channel, buf,
|
||||||
blk_cfg->block_size);
|
blk_cfg->block_size);
|
||||||
|
if (res == 0) {
|
||||||
if (res == 0 && dma_cfg->source_data_size <= 3) {
|
intel_adsp_hda_set_sample_container_size(cfg->base, cfg->regblock_size, channel,
|
||||||
/* set the sample container set bit to 16bits */
|
dma_cfg->source_data_size);
|
||||||
*DGCS(cfg->base, cfg->regblock_size, channel) |= DGCS_SCS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
|
|
@ -469,4 +469,26 @@ static inline uint32_t intel_adsp_hda_check_buffer_interrupt(uint32_t base, uint
|
||||||
return (*DGCS(base, regblock_size, sid) & DGCS_BSC) == DGCS_BSC;
|
return (*DGCS(base, regblock_size, sid) & DGCS_BSC) == DGCS_BSC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the Sample Container Size (SCS)
|
||||||
|
*
|
||||||
|
* Sample Container Size indicates the container size of the audio samples in local memory
|
||||||
|
* SCS bit must cleared to 0 for 32bit sample size (HD Audio container size)
|
||||||
|
* SCS bit must be set to 1 for non 32bit sample sizes
|
||||||
|
*
|
||||||
|
* @param base Base address of the IP register block
|
||||||
|
* @param regblock_size Register block size
|
||||||
|
* @param sid Stream ID
|
||||||
|
* @param sample_size
|
||||||
|
*/
|
||||||
|
static inline void intel_adsp_hda_set_sample_container_size(uint32_t base, uint32_t regblock_size,
|
||||||
|
uint32_t sid, uint32_t sample_size)
|
||||||
|
{
|
||||||
|
if (sample_size <= 3) {
|
||||||
|
*DGCS(base, regblock_size, sid) |= DGCS_SCS;
|
||||||
|
} else {
|
||||||
|
*DGCS(base, regblock_size, sid) &= ~DGCS_SCS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* ZEPHYR_INCLUDE_INTEL_ADSP_HDA_H */
|
#endif /* ZEPHYR_INCLUDE_INTEL_ADSP_HDA_H */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue