dma: hda: enable xrun handling

Enable link under/overruns handling and reporting such events in dma
status

Signed-off-by: Piotr Makaruk <piotr.makaruk@intel.com>
This commit is contained in:
Piotr Makaruk 2022-12-23 12:50:00 +01:00 committed by Anas Nashif
commit 00b5114344
2 changed files with 44 additions and 0 deletions

View file

@ -190,6 +190,7 @@ int intel_adsp_hda_dma_status(const struct device *dev, uint32_t channel,
struct dma_status *stat)
{
const struct intel_adsp_hda_dma_cfg *const cfg = dev->config;
bool xrun_det;
__ASSERT(channel < cfg->dma_channels, "Channel does not exist");
@ -203,6 +204,25 @@ int intel_adsp_hda_dma_status(const struct device *dev, uint32_t channel,
stat->pending_length = used;
stat->free = unused;
switch (cfg->direction) {
case MEMORY_TO_PERIPHERAL:
xrun_det = intel_adsp_hda_is_buffer_underrun(cfg->base, cfg->regblock_size,
channel);
if (xrun_det) {
intel_adsp_hda_underrun_clear(cfg->base, cfg->regblock_size, channel);
return -EPIPE;
}
case PERIPHERAL_TO_MEMORY:
xrun_det = intel_adsp_hda_is_buffer_overrun(cfg->base, cfg->regblock_size,
channel);
if (xrun_det) {
intel_adsp_hda_overrun_clear(cfg->base, cfg->regblock_size, channel);
return -EPIPE;
}
default:
break;
}
return 0;
}

View file

@ -346,4 +346,28 @@ static inline bool intel_adsp_hda_wp_rp_eq(uint32_t base, uint32_t regblock_size
return *DGBWP(base, regblock_size, sid) == *DGBRP(base, regblock_size, sid);
}
static inline bool intel_adsp_hda_is_buffer_overrun(uint32_t base, uint32_t regblock_size,
uint32_t sid)
{
return (*DGCS(base, regblock_size, sid) & DGCS_BOR) == DGCS_BOR ? 1 : 0;
}
static inline bool intel_adsp_hda_is_buffer_underrun(uint32_t base, uint32_t regblock_size,
uint32_t sid)
{
return (*DGCS(base, regblock_size, sid) & DGCS_BUR) == DGCS_BUR ? 1 : 0;
}
static inline void intel_adsp_hda_overrun_clear(uint32_t base, uint32_t regblock_size,
uint32_t sid)
{
*DGCS(base, regblock_size, sid) |= DGCS_BOR;
}
static inline void intel_adsp_hda_underrun_clear(uint32_t base, uint32_t regblock_size,
uint32_t sid)
{
*DGCS(base, regblock_size, sid) |= DGCS_BUR;
}
#endif /* ZEPHYR_INCLUDE_INTEL_ADSP_HDA_H */