Skip to content

Commit 00b5114

Browse files
makarukpnashif
authored andcommitted
dma: hda: enable xrun handling
Enable link under/overruns handling and reporting such events in dma status Signed-off-by: Piotr Makaruk <[email protected]>
1 parent 122c7be commit 00b5114

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed

drivers/dma/dma_intel_adsp_hda.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ int intel_adsp_hda_dma_status(const struct device *dev, uint32_t channel,
190190
struct dma_status *stat)
191191
{
192192
const struct intel_adsp_hda_dma_cfg *const cfg = dev->config;
193+
bool xrun_det;
193194

194195
__ASSERT(channel < cfg->dma_channels, "Channel does not exist");
195196

@@ -203,6 +204,25 @@ int intel_adsp_hda_dma_status(const struct device *dev, uint32_t channel,
203204
stat->pending_length = used;
204205
stat->free = unused;
205206

207+
switch (cfg->direction) {
208+
case MEMORY_TO_PERIPHERAL:
209+
xrun_det = intel_adsp_hda_is_buffer_underrun(cfg->base, cfg->regblock_size,
210+
channel);
211+
if (xrun_det) {
212+
intel_adsp_hda_underrun_clear(cfg->base, cfg->regblock_size, channel);
213+
return -EPIPE;
214+
}
215+
case PERIPHERAL_TO_MEMORY:
216+
xrun_det = intel_adsp_hda_is_buffer_overrun(cfg->base, cfg->regblock_size,
217+
channel);
218+
if (xrun_det) {
219+
intel_adsp_hda_overrun_clear(cfg->base, cfg->regblock_size, channel);
220+
return -EPIPE;
221+
}
222+
default:
223+
break;
224+
}
225+
206226
return 0;
207227
}
208228

soc/xtensa/intel_adsp/common/include/intel_adsp_hda.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,4 +346,28 @@ static inline bool intel_adsp_hda_wp_rp_eq(uint32_t base, uint32_t regblock_size
346346
return *DGBWP(base, regblock_size, sid) == *DGBRP(base, regblock_size, sid);
347347
}
348348

349+
static inline bool intel_adsp_hda_is_buffer_overrun(uint32_t base, uint32_t regblock_size,
350+
uint32_t sid)
351+
{
352+
return (*DGCS(base, regblock_size, sid) & DGCS_BOR) == DGCS_BOR ? 1 : 0;
353+
}
354+
355+
static inline bool intel_adsp_hda_is_buffer_underrun(uint32_t base, uint32_t regblock_size,
356+
uint32_t sid)
357+
{
358+
return (*DGCS(base, regblock_size, sid) & DGCS_BUR) == DGCS_BUR ? 1 : 0;
359+
}
360+
361+
static inline void intel_adsp_hda_overrun_clear(uint32_t base, uint32_t regblock_size,
362+
uint32_t sid)
363+
{
364+
*DGCS(base, regblock_size, sid) |= DGCS_BOR;
365+
}
366+
367+
static inline void intel_adsp_hda_underrun_clear(uint32_t base, uint32_t regblock_size,
368+
uint32_t sid)
369+
{
370+
*DGCS(base, regblock_size, sid) |= DGCS_BUR;
371+
}
372+
349373
#endif /* ZEPHYR_INCLUDE_INTEL_ADSP_HDA_H */

0 commit comments

Comments
 (0)