Skip to content

Commit

Permalink
drivers: dma: intel_adsp_hda: Fix L1 exit condition
Browse files Browse the repository at this point in the history
Transition to a low power DMI L1 state should be allowed only after all
pending DMA channels transfers have started.

Signed-off-by: Serhiy Katsyuba <[email protected]>
  • Loading branch information
serhiy-katsyuba-intel committed Mar 5, 2024
1 parent 1b76f82 commit 710c901
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 5 deletions.
21 changes: 16 additions & 5 deletions drivers/dma/dma_intel_adsp_hda.c
Original file line number Diff line number Diff line change
Expand Up @@ -454,15 +454,26 @@ void intel_adsp_hda_dma_isr(void)
cfg = host_dev[i]->config;

for (j = 0; j < dma_ctx->dma_channels; j++) {
if (atomic_test_bit(dma_ctx->atomic, j)) {
clear_l1_exit |=
intel_adsp_hda_check_buffer_interrupt(cfg->base,
cfg->regblock_size,
j);
if (!atomic_test_bit(dma_ctx->atomic, j))
continue;

if (!intel_adsp_hda_is_buffer_interrupt_enabled(cfg->base,
cfg->regblock_size, j))
continue;

if (intel_adsp_hda_check_buffer_interrupt(cfg->base,
cfg->regblock_size, j)) {
clear_l1_exit = true;
intel_adsp_hda_disable_buffer_interrupt(cfg->base,
cfg->regblock_size, j);
intel_adsp_hda_clear_buffer_interrupt(cfg->base,
cfg->regblock_size, j);
} else {
/*
* Postpone entering L1 state until all enabled interrupts
* arrived, i.e. transfer started on all channels.
*/
return;
}
}
}
Expand Down
13 changes: 13 additions & 0 deletions soc/intel/intel_adsp/common/include/intel_adsp_hda.h
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,19 @@ static inline void intel_adsp_hda_disable_buffer_interrupt(uint32_t base, uint32
*DGCS(base, regblock_size, sid) &= ~DGCS_BSCIE;
}

/**
* @brief Check if BSC interrupt enabled
*
* @param base Base address of the IP register block
* @param regblock_size Register block size
* @param sid Stream ID
*/
static inline bool intel_adsp_hda_is_buffer_interrupt_enabled(uint32_t base,
uint32_t regblock_size, uint32_t sid)
{
return (*DGCS(base, regblock_size, sid) & DGCS_BSCIE) == DGCS_BSCIE;
}

static inline void intel_adsp_force_dmi_l0_state(void)
{
#ifdef CONFIG_SOC_SERIES_INTEL_ADSP_ACE
Expand Down

0 comments on commit 710c901

Please sign in to comment.