Skip to content

Commit 88064d8

Browse files
committed
drivers: dma: sam: add DMA channel suspend and resume support
Add support for XDMA channel read write suspend and read write resume. Signed-off-by: Tony Han <tony.han@microchip.com>
1 parent 2ab4266 commit 88064d8

File tree

1 file changed

+70
-0
lines changed

1 file changed

+70
-0
lines changed

drivers/dma/dma_sam_xdmac.c

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,74 @@ static int sam_xdmac_initialize(const struct device *dev)
404404
return 0;
405405
}
406406

407+
static int xdmac_suspend(const struct device *dev, uint32_t channel)
408+
{
409+
const struct sam_xdmac_dev_cfg *config = dev->config;
410+
struct sam_xdmac_dev_data *const dev_data = dev->data;
411+
uint32_t channel_num = dev_data->dma_ctx.dma_channels;
412+
413+
Xdmac * const xdmac = config->regs;
414+
415+
if (channel >= channel_num) {
416+
LOG_ERR("Channel %d out of range", channel);
417+
return -EINVAL;
418+
}
419+
420+
if (!(xdmac->XDMAC_GS & BIT(channel))) {
421+
LOG_DBG("Channel %d not enabled", channel);
422+
return -EINVAL;
423+
}
424+
425+
#if defined(CONFIG_SOC_ATMEL_SAMV71)
426+
if (xdmac->XDMAC_GRS & BIT(channel) || xdmac->XDMAC_GWS & BIT(channel)) {
427+
#elif defined(CONFIG_SOC_SERIES_SAMA7G5)
428+
if (xdmac->XDMAC_GRSS & BIT(channel) || xdmac->XDMAC_GWSS & BIT(channel)) {
429+
#else
430+
#error Unsupported SoC family
431+
#endif
432+
LOG_DBG("Channel %d already suspended", channel);
433+
return -EINVAL;
434+
}
435+
436+
xdmac->XDMAC_GRWS |= BIT(channel);
437+
438+
return 0;
439+
}
440+
441+
static int xdmac_resume(const struct device *dev, uint32_t channel)
442+
{
443+
const struct sam_xdmac_dev_cfg *config = dev->config;
444+
struct sam_xdmac_dev_data *const dev_data = dev->data;
445+
uint32_t channel_num = dev_data->dma_ctx.dma_channels;
446+
447+
Xdmac * const xdmac = config->regs;
448+
449+
if (channel >= channel_num) {
450+
LOG_ERR("Channel %d out of range", channel);
451+
return -EINVAL;
452+
}
453+
454+
if (!(xdmac->XDMAC_GS & BIT(channel))) {
455+
LOG_DBG("Channel %d not enabled", channel);
456+
return -EINVAL;
457+
}
458+
459+
#if defined(CONFIG_SOC_ATMEL_SAMV71)
460+
if (!(xdmac->XDMAC_GRS & BIT(channel) || xdmac->XDMAC_GWS & BIT(channel))) {
461+
#elif defined(CONFIG_SOC_SERIES_SAMA7G5)
462+
if (!(xdmac->XDMAC_GRSS & BIT(channel) || xdmac->XDMAC_GWSS & BIT(channel))) {
463+
#else
464+
#error Unsupported SoC family
465+
#endif
466+
LOG_DBG("Channel %d not suspended", channel);
467+
return -EINVAL;
468+
}
469+
470+
xdmac->XDMAC_GRWR |= BIT(channel);
471+
472+
return 0;
473+
}
474+
407475
static int sam_xdmac_get_status(const struct device *dev, uint32_t channel,
408476
struct dma_status *status)
409477
{
@@ -433,6 +501,8 @@ static DEVICE_API(dma, sam_xdmac_driver_api) = {
433501
.reload = sam_xdmac_transfer_reload,
434502
.start = sam_xdmac_transfer_start,
435503
.stop = sam_xdmac_transfer_stop,
504+
.suspend = xdmac_suspend,
505+
.resume = xdmac_resume,
436506
.get_status = sam_xdmac_get_status,
437507
};
438508

0 commit comments

Comments
 (0)