Skip to content

Commit 0ce5332

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 0ce5332

File tree

1 file changed

+68
-0
lines changed

1 file changed

+68
-0
lines changed

drivers/dma/dma_sam_xdmac.c

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,72 @@ 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_SERIES_SAMX7X)
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+
}
434+
435+
xdmac->XDMAC_GRWS |= BIT(channel);
436+
437+
return 0;
438+
}
439+
440+
static int xdmac_resume(const struct device *dev, uint32_t channel)
441+
{
442+
const struct sam_xdmac_dev_cfg *config = dev->config;
443+
struct sam_xdmac_dev_data *const dev_data = dev->data;
444+
uint32_t channel_num = dev_data->dma_ctx.dma_channels;
445+
446+
Xdmac * const xdmac = config->regs;
447+
448+
if (channel >= channel_num) {
449+
LOG_ERR("Channel %d out of range", channel);
450+
return -EINVAL;
451+
}
452+
453+
if (!(xdmac->XDMAC_GS & BIT(channel))) {
454+
LOG_DBG("Channel %d not enabled", channel);
455+
return -EINVAL;
456+
}
457+
458+
#if defined(CONFIG_SOC_SERIES_SAMX7X)
459+
if (!(xdmac->XDMAC_GRS & BIT(channel) || xdmac->XDMAC_GWS & BIT(channel))) {
460+
#elif defined(CONFIG_SOC_SERIES_SAMA7G5)
461+
if (!(xdmac->XDMAC_GRSS & BIT(channel) || xdmac->XDMAC_GWSS & BIT(channel))) {
462+
#else
463+
#error Unsupported SoC family
464+
#endif
465+
LOG_DBG("Channel %d not suspended", channel);
466+
}
467+
468+
xdmac->XDMAC_GRWR |= BIT(channel);
469+
470+
return 0;
471+
}
472+
407473
static int sam_xdmac_get_status(const struct device *dev, uint32_t channel,
408474
struct dma_status *status)
409475
{
@@ -433,6 +499,8 @@ static DEVICE_API(dma, sam_xdmac_driver_api) = {
433499
.reload = sam_xdmac_transfer_reload,
434500
.start = sam_xdmac_transfer_start,
435501
.stop = sam_xdmac_transfer_stop,
502+
.suspend = xdmac_suspend,
503+
.resume = xdmac_resume,
436504
.get_status = sam_xdmac_get_status,
437505
};
438506

0 commit comments

Comments
 (0)