Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
a0ec843
platform: cavs: include missing headers
tlauda Sep 30, 2019
a5b2bfb
dma: add interrupt operation
tlauda Sep 11, 2019
38c97c5
dma: add interrupt ops implementations
tlauda Sep 11, 2019
b9d40e2
host: use blocking copy for one shot mode
tlauda Sep 12, 2019
0b7fcbe
pipeline: allocate pipe_task only if needed
tlauda Sep 13, 2019
9f03946
pipeline: add preload_task
tlauda Sep 13, 2019
bf48d13
dma: add core to dma_chan_data structure
tlauda Sep 13, 2019
2eaa862
component: add comp_is_scheduling_source function
tlauda Sep 13, 2019
ea6c803
dma: add scheduling_source
tlauda Sep 13, 2019
59d0ac9
schedule: rename SOF_SCHEDULE_LL to SOF_SCHEDULE_LL_TIMER
tlauda Sep 13, 2019
4626d3f
schedule: add SOF_SCHEDULE_LL_DMA
tlauda Sep 13, 2019
2572604
dma: move CAVS_PLATFORM_NUM_DMACS to specific platforms
tlauda Sep 13, 2019
2bd632a
hda-dma: remove HDA_DMA_MAX_CHANS definition
tlauda Sep 13, 2019
b6c4c03
dma: add PLATFORM_MAX_DMA_CHAN definition
tlauda Sep 16, 2019
ac06873
dma: imx8: add missing dma_chan_irq macro
tlauda Sep 20, 2019
a7af43f
schedule: implement DMA scheduling domain
tlauda Sep 16, 2019
bae6f2c
dw-dma: add PLATFORM_NUM_DW_DMACS definition
tlauda Sep 16, 2019
c7d4d9b
dma: extract dma array
tlauda Sep 16, 2019
f24e9a7
dw-dma: rename DMA_AGGREGATED_IRQ definition
tlauda Sep 16, 2019
6c7ea6b
dw-dma: add PLATFORM_DW_DMA_INDEX definition
tlauda Sep 16, 2019
726e576
platform: hsw: increase system heap size
tlauda Oct 1, 2019
93c56c7
schedule: use DMA multi channel scheduling domain
tlauda Sep 16, 2019
5797156
dw-dma: remove double channel index assignment
tlauda Sep 16, 2019
3c3f106
dw-dma: cleanup and remove irq related code
tlauda Sep 16, 2019
98f4007
dma: remove unused DMA_CB_STATUS_IGNORE
tlauda Sep 16, 2019
4062fc0
dma: remove unused DMA_CB_STATUS_SPLIT
tlauda Sep 16, 2019
ebe4749
host: remove not needed set of DMA_CB_STATUS_END
tlauda Sep 16, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -85,16 +85,16 @@ config HW_LLI
Any platforms with hardware linked list support
should set this.

config DMA_AGGREGATED_IRQ
config DW_DMA_AGGREGATED_IRQ
bool
default n
help
Some platforms cannot register interrupt per DMA channel
Some platforms cannot register interrupt per DW-DMA channel
and have the possibility only to register interrupts per
DMA controller, which require manual handling of aggregated
irq.

Any platforms with DMA aggregated interrupts support
Any platforms with DW-DMA aggregated interrupts support
should set this.

config DMA_SUSPEND_DRAIN
Expand Down
1 change: 1 addition & 0 deletions src/arch/xtensa/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ int slave_core_init(struct sof *sof)
trace_point(TRACE_BOOT_PLATFORM_SCHED);
scheduler_init_edf(sof);
scheduler_init_ll(platform_timer_domain);
scheduler_init_ll(platform_dma_domain);

/* initialize IDC mechanism */
trace_point(TRACE_BOOT_PLATFORM_IDC);
Expand Down
37 changes: 8 additions & 29 deletions src/audio/dai.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,18 +73,17 @@ struct dai_data {
uint64_t wallclock; /* wall clock at stream start */
};

static void dai_buffer_process(struct comp_dev *dev, struct dma_cb_data *next)
/* this is called by DMA driver every time descriptor has completed */
static void dai_dma_cb(void *data, uint32_t type, struct dma_cb_data *next)
{
struct comp_dev *dev = (struct comp_dev *)data;
struct dai_data *dd = comp_get_drvdata(dev);
struct dma_sg_config *config = &dd->config;
uint32_t bytes = next->elem.size;
void *buffer_ptr;

tracev_dai_with_ids(dev, "dai_buffer_process()");
tracev_dai_with_ids(dev, "dai_dma_cb()");

/* lli needs to be reloaded if irq is disabled */
next->status = config->irq_disabled ? DMA_CB_STATUS_RELOAD :
DMA_CB_STATUS_IGNORE;
next->status = DMA_CB_STATUS_RELOAD;

/* stop dma copy for pause/stop/xrun */
if (dev->state != COMP_STATE_ACTIVE || dd->xrun) {
Expand Down Expand Up @@ -126,27 +125,6 @@ static void dai_buffer_process(struct comp_dev *dev, struct dma_cb_data *next)
}
}

/* this is called by DMA driver every time descriptor has completed */
static void dai_dma_cb(void *data, uint32_t type, struct dma_cb_data *next)
{
struct comp_dev *dev = (struct comp_dev *)data;

tracev_dai_with_ids(dev, "dai_dma_cb()");

switch (type) {
case DMA_CB_TYPE_IRQ:
pipeline_schedule_copy(dev->pipeline, 0);
break;
case DMA_CB_TYPE_COPY:
dai_buffer_process(dev, next);
break;
default:
trace_dai_error_with_ids(dev, "dai_dma_cb() error: Wrong "
"callback type = %u", type);
break;
}
}

static struct comp_dev *dai_new(struct sof_ipc_comp *comp)
{
struct comp_dev *dev;
Expand Down Expand Up @@ -248,6 +226,7 @@ static int dai_playback_params(struct comp_dev *dev, uint32_t period_bytes)
config->irq_disabled = pipeline_is_timer_driven(dev->pipeline);
config->dest_dev = dai_get_handshake(dd->dai, dev->params.direction,
dd->stream_id);
config->is_scheduling_source = comp_is_scheduling_source(dev);

trace_dai_with_ids(dev, "dai_playback_params() "
"dest_dev = %d stream_id = %d "
Expand Down Expand Up @@ -313,6 +292,7 @@ static int dai_capture_params(struct comp_dev *dev, uint32_t period_bytes)
config->irq_disabled = pipeline_is_timer_driven(dev->pipeline);
config->src_dev = dai_get_handshake(dd->dai, dev->params.direction,
dd->stream_id);
config->is_scheduling_source = comp_is_scheduling_source(dev);

/* TODO: Make this code platform-specific or move it driver callback */
if (dai_get_info(dd->dai, DAI_INFO_TYPE) == SOF_DAI_INTEL_DMIC) {
Expand Down Expand Up @@ -820,8 +800,7 @@ static int dai_config(struct comp_dev *dev, struct sof_ipc_dai_config *config)
}

/* set up callback */
dma_set_cb(dd->chan, DMA_CB_TYPE_IRQ | DMA_CB_TYPE_COPY,
dai_dma_cb, dev);
dma_set_cb(dd->chan, DMA_CB_TYPE_COPY, dai_dma_cb, dev);
dev->is_dma_connected = 1;
}

Expand Down
98 changes: 34 additions & 64 deletions src/audio/host.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,8 @@ struct host_data {
struct hc_buf *source;
struct hc_buf *sink;

/* helpers used in split transactions */
/* helper used in split transactions */
uint32_t split_value;
uint32_t last_split_value;

uint32_t dma_copy_align; /**< Minimal chunk of data possible to be
* copied by dma connected to host
Expand Down Expand Up @@ -176,21 +175,12 @@ static void host_update_position(struct comp_dev *dev, uint32_t bytes)
* This means we must check we do not overflow host period/buffer/page
* boundaries on each transfer and split the DMA transfer if we do overflow.
*/
static void host_dma_cb_irq(struct comp_dev *dev, struct dma_cb_data *next)
static void host_one_shot_cb(struct comp_dev *dev, uint32_t bytes)
{
struct host_data *hd = comp_get_drvdata(dev);
struct dma_sg_elem *local_elem = hd->config.elem_array.elems;
struct dma_sg_elem *source_elem;
struct dma_sg_elem *sink_elem;
uint32_t curr_split_value = 0;
uint32_t next_bytes = 0;
uint32_t bytes = hd->last_split_value ? hd->last_split_value :
local_elem->size;

tracev_host("host_dma_cb_irq()");

/* update position */
host_update_position(dev, bytes);

/* update src and dest positions and check for overflow */
local_elem->src += bytes;
Expand All @@ -215,31 +205,6 @@ static void host_dma_cb_irq(struct comp_dev *dev, struct dma_cb_data *next)
local_elem->dest = sink_elem->dest;
}
}

/* we need to perform split transfer */
if (hd->split_value) {
/* check for possible double split */
curr_split_value = host_dma_get_split(hd, hd->split_value);
if (curr_split_value) {
next_bytes = hd->split_value - curr_split_value;
hd->split_value = curr_split_value;
} else {
next_bytes = hd->split_value;
hd->split_value = 0;
}

hd->last_split_value = next_bytes;

next->elem.src = local_elem->src;
next->elem.dest = local_elem->dest;
next->elem.size = next_bytes;
next->status = DMA_CB_STATUS_SPLIT;
return;
}

hd->last_split_value = 0;

next->status = DMA_CB_STATUS_END;
}

/* This is called by DMA driver every time when DMA completes its current
Expand All @@ -248,21 +213,17 @@ static void host_dma_cb_irq(struct comp_dev *dev, struct dma_cb_data *next)
static void host_dma_cb(void *data, uint32_t type, struct dma_cb_data *next)
{
struct comp_dev *dev = (struct comp_dev *)data;
struct host_data *hd = comp_get_drvdata(dev);
uint32_t bytes = next->elem.size;

tracev_host("host_dma_cb()");

switch (type) {
case DMA_CB_TYPE_IRQ:
host_dma_cb_irq(dev, next);
break;
case DMA_CB_TYPE_COPY:
host_update_position(dev, next->elem.size);
break;
default:
trace_host_error("host_dma_cb() error: Wrong callback type "
"= %u", type);
break;
}
/* update position */
host_update_position(dev, bytes);

/* callback for one shot copy */
if (hd->copy_type == COMP_COPY_ONE_SHOT)
host_one_shot_cb(dev, bytes);
}

static int create_local_elems(struct comp_dev *dev, uint32_t buffer_count,
Expand Down Expand Up @@ -522,7 +483,7 @@ static void host_buffer_cb(void *data, uint32_t bytes)
{
struct comp_dev *dev = (struct comp_dev *)data;
struct host_data *hd = comp_get_drvdata(dev);
uint32_t copy_bytes = host_buffer_get_copy_bytes(dev);
uint32_t copy_bytes = 0;
uint32_t flags = 0;
int ret;

Expand All @@ -533,18 +494,28 @@ static void host_buffer_cb(void *data, uint32_t bytes)
else if (hd->copy_type == COMP_COPY_ONE_SHOT)
flags |= DMA_COPY_ONE_SHOT;

/* reconfigure transfer */
ret = dma_set_config(hd->chan, &hd->config);
if (ret < 0) {
trace_host_error("host_buffer_cb() error: dma_set_config() "
"failed, ret = %u", ret);
return;
}
/* copy including all split transfers */
do {
copy_bytes = host_buffer_get_copy_bytes(dev);

ret = dma_copy(hd->chan, copy_bytes, flags);
if (ret < 0)
trace_host_error("host_buffer_cb() error: dma_copy() failed, "
"ret = %u", ret);
/* reconfigure transfer */
ret = dma_set_config(hd->chan, &hd->config);
if (ret < 0) {
trace_host_error("host_buffer_cb() error: "
"dma_set_config() failed, ret = %u",
ret);
hd->split_value = 0;
return;
}

ret = dma_copy(hd->chan, copy_bytes, flags);
if (ret < 0) {
trace_host_error("host_buffer_cb() error: dma_copy() "
"failed, ret = %u", ret);
hd->split_value = 0;
return;
}
} while (hd->split_value);
}

/* configure the DMA params and descriptors for host buffer IO */
Expand Down Expand Up @@ -654,6 +625,7 @@ static int host_params(struct comp_dev *dev)
config->dest_width = comp_sample_bytes(dev);
config->cyclic = 0;
config->irq_disabled = pipeline_is_timer_driven(dev->pipeline);
config->is_scheduling_source = comp_is_scheduling_source(dev);

host_elements_reset(dev);

Expand Down Expand Up @@ -688,8 +660,7 @@ static int host_params(struct comp_dev *dev)
}

/* set up callback */
dma_set_cb(hd->chan, DMA_CB_TYPE_IRQ |
DMA_CB_TYPE_COPY, host_dma_cb, dev);
dma_set_cb(hd->chan, DMA_CB_TYPE_COPY, host_dma_cb, dev);

return 0;
}
Expand All @@ -711,7 +682,6 @@ static int host_prepare(struct comp_dev *dev)
hd->local_pos = 0;
hd->report_pos = 0;
hd->split_value = 0;
hd->last_split_value = 0;
dev->position = 0;

return 0;
Expand Down
Loading