Skip to content

Commit 0875f0c

Browse files
authored
Merge pull request #342 from RanderWang/byt
dma: fix dma issue on BYT
2 parents ef3ab58 + fbb001b commit 0875f0c

2 files changed

Lines changed: 51 additions & 0 deletions

File tree

src/drivers/dw-dma.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@
119119
#define INT_UNMASK_ALL 0xFFFF
120120
#define CHAN_ENABLE(chan) (0x101 << chan)
121121
#define CHAN_DISABLE(chan) (0x100 << chan)
122+
#define CHAN_MASK(chan) (0x1 << chan)
122123

123124
#define DW_CFG_CH_SUSPEND 0x100
124125
#define DW_CFG_CH_FIFO_EMPTY 0x200
@@ -474,6 +475,31 @@ static int dw_dma_pause(struct dma *dma, int channel)
474475
return 0;
475476
}
476477

478+
#if defined CONFIG_BAYTRAIL || defined CONFIG_CHERRYTRAIL
479+
static int dw_dma_stop(struct dma *dma, int channel)
480+
{
481+
struct dma_pdata *p = dma_get_drvdata(dma);
482+
int ret = 0;
483+
uint32_t flags;
484+
uint32_t val = 0;
485+
486+
spin_lock_irq(&dma->lock, flags);
487+
488+
trace_dma("DDi");
489+
490+
ret = poll_for_register_delay(dma_base(dma) + DW_DMA_CHAN_EN,
491+
CHAN_MASK(channel), val,
492+
PLATFORM_DMA_TIMEOUT);
493+
if (ret < 0)
494+
trace_dma_error("esp");
495+
496+
dw_write(dma, DW_CLEAR_BLOCK, 0x1 << channel);
497+
p->chan[channel].status = COMP_STATE_PREPARE;
498+
499+
spin_unlock_irq(&dma->lock, flags);
500+
return ret;
501+
}
502+
#else
477503
static int dw_dma_stop(struct dma *dma, int channel)
478504
{
479505
struct dma_pdata *p = dma_get_drvdata(dma);
@@ -508,6 +534,7 @@ static int dw_dma_stop(struct dma *dma, int channel)
508534
spin_unlock_irq(&dma->lock, flags);
509535
return ret;
510536
}
537+
#endif
511538

512539
/* fill in "status" with current DMA channel state and position */
513540
static int dw_dma_status(struct dma *dma, int channel,

src/include/sof/wait.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include <stdint.h>
3737
#include <errno.h>
3838
#include <arch/wait.h>
39+
#include <sof/io.h>
3940
#include <sof/debug.h>
4041
#include <sof/work.h>
4142
#include <sof/timer.h>
@@ -185,4 +186,27 @@ static inline int poll_for_completion_delay(completion_t *comp, uint64_t us)
185186
return 0;
186187
}
187188

189+
static inline int poll_for_register_delay(uint32_t reg,
190+
uint32_t mask,
191+
uint32_t val, uint64_t us)
192+
{
193+
uint64_t tick = clock_us_to_ticks(CLK_CPU, us);
194+
uint32_t tries = DEFAULT_TRY_TIMES;
195+
uint64_t delta = tick / tries;
196+
197+
if (!delta) {
198+
delta = us;
199+
tries = 1;
200+
}
201+
202+
while ((io_reg_read(reg) & mask) != val) {
203+
if (!tries--) {
204+
trace_error(TRACE_CLASS_WAIT, "ewt");
205+
return -EIO;
206+
}
207+
wait_delay(delta);
208+
}
209+
return 0;
210+
}
211+
188212
#endif

0 commit comments

Comments
 (0)