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:
parent
122c7be703
commit
00b5114344
2 changed files with 44 additions and 0 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue