Skip to content

Commit 102b7ad

Browse files
authored
Merge pull request #386 from xiulipan/merge12_3
Merge stable 1.2 (part 3) scheduler and BYT part into master
2 parents 504c2cc + 5b39370 commit 102b7ad

5 files changed

Lines changed: 113 additions & 32 deletions

File tree

src/arch/xtensa/include/arch/task.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,9 @@ static void _irq_task(void *arg)
138138
uint32_t flags;
139139

140140
spin_lock_irq(&irq_task->lock, flags);
141+
142+
interrupt_clear(irq_task->irq);
143+
141144
list_for_item_safe(clist, tlist, &irq_task->list) {
142145

143146
task = container_of(clist, struct task, irq_list);
@@ -152,8 +155,6 @@ static void _irq_task(void *arg)
152155
spin_lock_irq(&irq_task->lock, flags);
153156
}
154157

155-
interrupt_clear(irq_task->irq);
156-
157158
spin_unlock_irq(&irq_task->lock, flags);
158159
}
159160

src/drivers/intel/dw-dma.c

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

124125
#define DW_CFG_CH_SUSPEND 0x100
125126
#define DW_CFG_CH_FIFO_EMPTY 0x200
@@ -491,6 +492,31 @@ static int dw_dma_pause(struct dma *dma, int channel)
491492
return 0;
492493
}
493494

495+
#if defined CONFIG_BAYTRAIL || defined CONFIG_CHERRYTRAIL
496+
static int dw_dma_stop(struct dma *dma, int channel)
497+
{
498+
struct dma_pdata *p = dma_get_drvdata(dma);
499+
int ret = 0;
500+
uint32_t flags;
501+
uint32_t val = 0;
502+
503+
spin_lock_irq(&dma->lock, flags);
504+
505+
trace_dma("DDi");
506+
507+
ret = poll_for_register_delay(dma_base(dma) + DW_DMA_CHAN_EN,
508+
CHAN_MASK(channel), val,
509+
PLATFORM_DMA_TIMEOUT);
510+
if (ret < 0)
511+
trace_dma_error("esp");
512+
513+
dw_write(dma, DW_CLEAR_BLOCK, 0x1 << channel);
514+
p->chan[channel].status = COMP_STATE_PREPARE;
515+
516+
spin_unlock_irq(&dma->lock, flags);
517+
return ret;
518+
}
519+
#else
494520
static int dw_dma_stop(struct dma *dma, int channel)
495521
{
496522
struct dma_pdata *p = dma_get_drvdata(dma);
@@ -528,6 +554,7 @@ static int dw_dma_stop(struct dma *dma, int channel)
528554
spin_unlock_irq(&dma->lock, flags);
529555
return ret;
530556
}
557+
#endif
531558

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

src/include/sof/wait.h

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,18 @@
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>
4243
#include <sof/interrupt.h>
4344
#include <sof/trace.h>
4445
#include <sof/lock.h>
46+
#include <sof/clock.h>
47+
#include <platform/clk.h>
4548
#include <platform/interrupt.h>
4649
#include <sof/drivers/timer.h>
50+
#include <platform/platform.h>
4751

4852
#if DEBUG_LOCKS
4953
#define wait_atomic_check \
@@ -54,6 +58,8 @@
5458
#define wait_atomic_check
5559
#endif
5660

61+
#define DEFAULT_TRY_TIMES 8
62+
5763
typedef struct {
5864
uint32_t complete;
5965
struct work work;
@@ -158,4 +164,50 @@ static inline void wait_delay(uint64_t number_of_clks)
158164
idelay(PLATFORM_DEFAULT_DELAY);
159165
}
160166

167+
static inline int poll_for_completion_delay(completion_t *comp, uint64_t us)
168+
{
169+
uint64_t tick = clock_us_to_ticks(CLK_CPU, us);
170+
uint32_t tries = DEFAULT_TRY_TIMES;
171+
uint64_t delta = tick / tries;
172+
173+
if (!delta) {
174+
delta = us;
175+
tries = 1;
176+
}
177+
178+
while (!wait_is_completed(comp)) {
179+
if (!tries--) {
180+
trace_error(TRACE_CLASS_WAIT, "ewt");
181+
return -EIO;
182+
}
183+
184+
wait_delay(delta);
185+
}
186+
187+
return 0;
188+
}
189+
190+
static inline int poll_for_register_delay(uint32_t reg,
191+
uint32_t mask,
192+
uint32_t val, uint64_t us)
193+
{
194+
uint64_t tick = clock_us_to_ticks(CLK_CPU, us);
195+
uint32_t tries = DEFAULT_TRY_TIMES;
196+
uint64_t delta = tick / tries;
197+
198+
if (!delta) {
199+
delta = us;
200+
tries = 1;
201+
}
202+
203+
while ((io_reg_read(reg) & mask) != val) {
204+
if (!tries--) {
205+
trace_error(TRACE_CLASS_WAIT, "ewt");
206+
return -EIO;
207+
}
208+
wait_delay(delta);
209+
}
210+
return 0;
211+
}
212+
161213
#endif

src/ipc/ipc.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -501,8 +501,9 @@ int ipc_get_page_descriptors(struct dma *dmac, uint8_t *page_table,
501501
}
502502

503503
/* wait for DMA to complete */
504-
complete.timeout = PLATFORM_HOST_DMA_TIMEOUT;
505-
ret = wait_for_completion_timeout(&complete);
504+
ret = poll_for_completion_delay(&complete, PLATFORM_DMA_TIMEOUT);
505+
if (ret < 0)
506+
trace_ipc_error("eDt");
506507

507508
/* compressed page tables now in buffer at _ipc->page_table */
508509
out:

src/lib/schedule.c

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -102,13 +102,9 @@ static inline struct task *edf_get_next(uint64_t current,
102102
uint64_t delta;
103103
uint64_t deadline;
104104
int reschedule = 0;
105-
uint32_t flags;
106105

107-
spin_lock_irq(&sch->lock, flags);
108-
109106
/* any tasks in the scheduler ? */
110107
if (list_is_empty(&sch->list)) {
111-
spin_unlock_irq(&sch->lock, flags);
112108
return NULL;
113109
}
114110

@@ -159,7 +155,6 @@ static inline struct task *edf_get_next(uint64_t current,
159155
}
160156
}
161157

162-
spin_unlock_irq(&sch->lock, flags);
163158
return next_task;
164159
}
165160

@@ -187,35 +182,40 @@ static struct task *schedule_edf(void)
187182

188183
tracev_pipe("edf");
189184

190-
/* get the current time */
191-
current = platform_timer_get(platform_timer);
192-
193-
/* get next task to be scheduled */
194-
task = edf_get_next(current, NULL);
195-
196185
interrupt_clear(PLATFORM_SCHEDULE_IRQ);
197186

198-
/* any tasks ? */
199-
if (task == NULL)
200-
return NULL;
187+
while (!list_is_empty(&sch->list)) {
188+
spin_lock_irq(&sch->lock, flags);
201189

202-
/* can task be started now ? */
203-
if (task->start > current) {
204-
/* no, then schedule wake up */
205-
future_task = task;
206-
} else {
207-
/* yes, run current task */
208-
task->start = current;
190+
/* get the current time */
191+
current = platform_timer_get(platform_timer);
209192

210-
/* init task for running */
211-
wait_init(&task->complete);
212-
spin_lock_irq(&sch->lock, flags);
213-
task->state = TASK_STATE_RUNNING;
214-
list_item_del(&task->list);
193+
/* get next task to be scheduled */
194+
task = edf_get_next(current, NULL);
215195
spin_unlock_irq(&sch->lock, flags);
216196

217-
/* now run task at correct run level */
218-
run_task(task);
197+
/* any tasks ? */
198+
if (!task)
199+
return NULL;
200+
201+
/* can task be started now ? */
202+
if (task->start <= current) {
203+
/* yes, run current task */
204+
task->start = current;
205+
206+
/* init task for running */
207+
spin_lock_irq(&sch->lock, flags);
208+
task->state = TASK_STATE_RUNNING;
209+
list_item_del(&task->list);
210+
spin_unlock_irq(&sch->lock, flags);
211+
212+
/* now run task at correct run level */
213+
run_task(task);
214+
} else {
215+
/* no, then schedule wake up */
216+
future_task = task;
217+
break;
218+
}
219219
}
220220

221221
/* tell caller about future task */

0 commit comments

Comments
 (0)