Lines Matching +full:valid +full:- +full:channels
4 * SPDX-License-Identifier: Apache-2.0
16 * 5) Ideally, HALFMAJOR should be set on a per-channel basis not through a
30 cfg = chan->dev->config; in edma_isr()
31 data = chan->dev->data; in edma_isr()
33 if (chan->state == CHAN_STATE_RELEASING || chan->state == CHAN_STATE_INIT) { in edma_isr()
38 if (!EDMA_ChannelRegRead(data->hal_cfg, chan->id, EDMA_TCD_CH_INT)) { in edma_isr()
44 EDMA_ChannelRegUpdate(data->hal_cfg, chan->id, in edma_isr()
47 if (chan->cyclic_buffer) { in edma_isr()
48 update_size = chan->bsize; in edma_isr()
51 update_size = chan->bsize / 2; in edma_isr()
53 update_size = chan->bsize; in edma_isr()
59 LOG_ERR("chan %d buffer overflow/underrun", chan->id); in edma_isr()
66 if (chan->cb) { in edma_isr()
67 chan->cb(chan->dev, chan->arg, chan->id, DMA_STATUS_COMPLETE); in edma_isr()
78 data = dev->data; in lookup_channel()
79 cfg = dev->config; in lookup_channel()
82 /* optimization: if dma-channels property is present then in lookup_channel()
84 * can be found at index chan_id in the array of channels. in lookup_channel()
86 if (cfg->contiguous_channels) { in lookup_channel()
88 if (chan_id >= data->ctx.dma_channels) { in lookup_channel()
92 return &data->channels[chan_id]; in lookup_channel()
95 /* channels are passed through the valid-channels property. in lookup_channel()
96 * As such, since some channels may be missing we need to in lookup_channel()
97 * look through the entire channels array for an ID match. in lookup_channel()
99 for (i = 0; i < data->ctx.dma_channels; i++) { in lookup_channel()
100 if (data->channels[i].id == chan_id) { in lookup_channel()
101 return &data->channels[i]; in lookup_channel()
117 data = dev->data; in edma_config()
118 cfg = dev->config; in edma_config()
120 if (!dma_cfg->head_block) { in edma_config()
122 return -EINVAL; in edma_config()
126 if (!EDMA_TransferWidthIsValid(data->hal_cfg, dma_cfg->source_data_size)) { in edma_config()
128 dma_cfg->source_data_size); in edma_config()
129 return -EINVAL; in edma_config()
133 if (!EDMA_TransferWidthIsValid(data->hal_cfg, dma_cfg->dest_data_size)) { in edma_config()
135 dma_cfg->dest_data_size); in edma_config()
136 return -EINVAL; in edma_config()
140 if (!EDMA_TransferWidthIsValid(data->hal_cfg, CONFIG_DMA_NXP_EDMA_ALIGN)) { in edma_config()
143 return -EINVAL; in edma_config()
146 /* Scatter-Gather configurations currently not supported */ in edma_config()
147 if (dma_cfg->block_count != 1) { in edma_config()
148 LOG_ERR("number of blocks %d not supported", dma_cfg->block_count); in edma_config()
149 return -ENOTSUP; in edma_config()
153 if (!dma_cfg->head_block->source_address) { in edma_config()
155 return -EINVAL; in edma_config()
159 if (!dma_cfg->head_block->dest_address) { in edma_config()
161 return -EINVAL; in edma_config()
172 * because this doesn't break the 8B boundary of the 64-bit system in edma_config()
175 if (dma_cfg->head_block->source_address % dma_cfg->source_data_size) { in edma_config()
177 dma_cfg->head_block->source_address, in edma_config()
178 dma_cfg->source_data_size); in edma_config()
179 return -EINVAL; in edma_config()
186 if (dma_cfg->head_block->dest_address % dma_cfg->dest_data_size) { in edma_config()
188 dma_cfg->head_block->dest_address, in edma_config()
189 dma_cfg->dest_data_size); in edma_config()
190 return -EINVAL; in edma_config()
197 if (dma_cfg->source_burst_length != in edma_config()
198 dma_cfg->dest_burst_length) { in edma_config()
200 dma_cfg->source_burst_length, in edma_config()
201 dma_cfg->dest_burst_length); in edma_config()
202 return -EINVAL; in edma_config()
214 if (dma_cfg->head_block->block_size % dma_cfg->source_burst_length) { in edma_config()
216 dma_cfg->head_block->block_size, in edma_config()
217 dma_cfg->source_burst_length); in edma_config()
218 return -EINVAL; in edma_config()
231 if (dma_cfg->source_burst_length % in edma_config()
232 MAX(dma_cfg->source_data_size, dma_cfg->dest_data_size)) { in edma_config()
234 dma_cfg->source_burst_length, in edma_config()
235 dma_cfg->source_data_size, in edma_config()
236 dma_cfg->dest_data_size); in edma_config()
237 return -EINVAL; in edma_config()
243 LOG_ERR("channel ID %u is not valid", chan_id); in edma_config()
244 return -EINVAL; in edma_config()
248 chan->bsize = dma_cfg->head_block->block_size; in edma_config()
250 if (dma_cfg->cyclic) { in edma_config()
251 chan->cyclic_buffer = true; in edma_config()
253 chan->stat.read_position = 0; in edma_config()
254 chan->stat.write_position = 0; in edma_config()
256 /* ASSUMPTION: for CONSUMER-type channels, the buffer from in edma_config()
258 * case of PRODUCER-type channels it should be empty. in edma_config()
260 switch (dma_cfg->channel_direction) { in edma_config()
262 chan->type = CHAN_TYPE_CONSUMER; in edma_config()
263 chan->stat.free = 0; in edma_config()
264 chan->stat.pending_length = chan->bsize; in edma_config()
267 chan->type = CHAN_TYPE_PRODUCER; in edma_config()
268 chan->stat.pending_length = 0; in edma_config()
269 chan->stat.free = chan->bsize; in edma_config()
273 dma_cfg->channel_direction); in edma_config()
274 return -ENOTSUP; in edma_config()
277 chan->cyclic_buffer = false; in edma_config()
283 chan_id, chan->state); in edma_config()
284 return -EPERM; in edma_config()
287 ret = get_transfer_type(dma_cfg->channel_direction, &transfer_type); in edma_config()
292 chan->cb = dma_cfg->dma_callback; in edma_config()
293 chan->arg = dma_cfg->user_data; in edma_config()
296 ret = EDMA_ConfigureTransfer(data->hal_cfg, chan_id, in edma_config()
297 dma_cfg->head_block->source_address, in edma_config()
298 dma_cfg->head_block->dest_address, in edma_config()
299 dma_cfg->source_data_size, in edma_config()
300 dma_cfg->dest_data_size, in edma_config()
301 dma_cfg->source_burst_length, in edma_config()
302 dma_cfg->head_block->block_size, in edma_config()
310 if (EDMA_HAS_MUX(data->hal_cfg)) { in edma_config()
311 ret = EDMA_SetChannelMux(data->hal_cfg, chan_id, dma_cfg->dma_slot); in edma_config()
331 EDMA_ChannelRegUpdate(data->hal_cfg, chan_id, in edma_config()
338 EDMA_ChannelRegUpdate(data->hal_cfg, chan_id, EDMA_TCD_CSR, in edma_config()
342 /* dump register status - for debugging purposes */ in edma_config()
345 chan->state = CHAN_STATE_CONFIGURED; in edma_config()
358 data = dev->data; in edma_get_status()
363 LOG_ERR("channel ID %u is not valid", chan_id); in edma_get_status()
364 return -EINVAL; in edma_get_status()
367 if (chan->cyclic_buffer) { in edma_get_status()
370 stat->free = chan->stat.free; in edma_get_status()
371 stat->pending_length = chan->stat.pending_length; in edma_get_status()
378 citer = EDMA_ChannelRegRead(data->hal_cfg, chan_id, EDMA_TCD_CITER); in edma_get_status()
379 biter = EDMA_ChannelRegRead(data->hal_cfg, chan_id, EDMA_TCD_BITER); in edma_get_status()
380 done = EDMA_ChannelRegRead(data->hal_cfg, chan_id, EDMA_TCD_CH_CSR) & in edma_get_status()
383 stat->free = chan->bsize; in edma_get_status()
384 stat->pending_length = 0; in edma_get_status()
386 stat->free = (biter - citer) * (chan->bsize / biter); in edma_get_status()
387 stat->pending_length = chan->bsize - stat->free; in edma_get_status()
391 LOG_DBG("free: %d, pending: %d", stat->free, stat->pending_length); in edma_get_status()
402 data = dev->data; in edma_suspend()
403 cfg = dev->config; in edma_suspend()
408 LOG_ERR("channel ID %u is not valid", chan_id); in edma_suspend()
409 return -EINVAL; in edma_suspend()
417 chan_id, chan->state); in edma_suspend()
418 return -EPERM; in edma_suspend()
424 EDMA_ChannelRegUpdate(data->hal_cfg, chan_id, in edma_suspend()
427 chan->state = CHAN_STATE_SUSPENDED; in edma_suspend()
440 data = dev->data; in edma_stop()
441 cfg = dev->config; in edma_stop()
446 LOG_ERR("channel ID %u is not valid", chan_id); in edma_stop()
447 return -EINVAL; in edma_stop()
450 prev_state = chan->state; in edma_stop()
455 chan_id, chan->state); in edma_stop()
456 return -EPERM; in edma_stop()
470 EDMA_ChannelRegUpdate(data->hal_cfg, chan_id, EDMA_TCD_CH_CSR, 0, in edma_stop()
478 * one needs to re-configure the channel MUX which can only be done in edma_stop()
482 if (EDMA_HAS_MUX(data->hal_cfg)) { in edma_stop()
483 ret = EDMA_SetChannelMux(data->hal_cfg, chan_id, 0); in edma_stop()
492 chan->state = CHAN_STATE_STOPPED; in edma_stop()
503 data = dev->data; in edma_start()
504 cfg = dev->config; in edma_start()
509 LOG_ERR("channel ID %u is not valid", chan_id); in edma_start()
510 return -EINVAL; in edma_start()
516 chan_id, chan->state); in edma_start()
517 return -EPERM; in edma_start()
523 EDMA_ChannelRegUpdate(data->hal_cfg, chan_id, in edma_start()
526 chan->state = CHAN_STATE_STARTED; in edma_start()
539 data = dev->data; in edma_reload()
544 LOG_ERR("channel ID %u is not valid", chan_id); in edma_reload()
545 return -EINVAL; in edma_reload()
549 if (chan->state != CHAN_STATE_STARTED) { in edma_reload()
550 LOG_ERR("reload is only supported on started channels"); in edma_reload()
551 return -EINVAL; in edma_reload()
554 if (chan->cyclic_buffer) { in edma_reload()
580 return -EINVAL; in edma_get_attribute()
604 if (chan->pd_dev) { in edma_channel_filter()
605 ret = pm_device_runtime_get(chan->pd_dev); in edma_channel_filter()
613 irq_enable(chan->irq); in edma_channel_filter()
629 data = dev->data; in edma_channel_release()
633 chan_id, chan->state); in edma_channel_release()
641 chan->id); in edma_channel_release()
646 chan->state = CHAN_STATE_RELEASING; in edma_channel_release()
649 irq_disable(chan->irq); in edma_channel_release()
652 if (chan->pd_dev) { in edma_channel_release()
653 ret = pm_device_runtime_put(chan->pd_dev); in edma_channel_release()
661 chan->state = CHAN_STATE_INIT; in edma_channel_release()
682 if (cfg->regmap_phys == s_edmaConfigs[i].regmap) { in edma_hal_cfg_get()
696 data = dev->data; in edma_init()
697 cfg = dev->config; in edma_init()
699 data->hal_cfg = edma_hal_cfg_get(cfg); in edma_init()
700 if (!data->hal_cfg) { in edma_init()
701 return -ENODEV; in edma_init()
705 device_map(®map, cfg->regmap_phys, cfg->regmap_size, K_MEM_CACHE_NONE); in edma_init()
708 * We can down-cast the virtual address to a 32-bit address because in edma_init()
709 * we know we're working with 32-bit addresses only. in edma_init()
711 data->hal_cfg->regmap = (uint32_t)POINTER_TO_UINT(regmap); in edma_init()
713 cfg->irq_config(); in edma_init()
716 * available channels. As such, it needs to be initialized with NULL in edma_init()
717 * which signifies that all channels are initially available. in edma_init()
719 data->channel_flags = ATOMIC_INIT(0); in edma_init()
720 data->ctx.atomic = &data->channel_flags; in edma_init()
721 data->ctx.dma_channels = data->hal_cfg->channels; in edma_init()
727 * 1) dma-channels and valid-channels should be mutually exclusive.
730 * 2) Number of channels should match the number of interrupts for
731 * said channels (TODO: what about error interrupts?)
732 * 3) The channel-mux property shouldn't be specified unless
733 * the eDMA is MUX-capable (signaled via the EDMA_HAS_CHAN_MUX
746 "number of interrupts needs to match number of channels"); \
767 .channels = channels_##inst, \