Skip to content

Commit b5061da

Browse files
fimohamekartben
authored andcommitted
driver: dma: dma_silabs_siwx91x: Add pm policy state support for dma driver
This commit enables the pm policy state lock support for the dma_silabs_siwx91x driver. Signed-off-by: S Mohamed Fiaz <[email protected]>
1 parent 72fac96 commit b5061da

File tree

2 files changed

+75
-17
lines changed

2 files changed

+75
-17
lines changed

drivers/dma/dma_silabs_siwx91x.c

Lines changed: 71 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
#include <zephyr/drivers/dma.h>
1414
#include <zephyr/drivers/clock_control.h>
1515
#include <zephyr/logging/log.h>
16+
#include <zephyr/pm/device.h>
17+
#include <zephyr/pm/policy.h>
1618
#include <zephyr/types.h>
1719
#include "rsi_rom_udma.h"
1820
#include "rsi_rom_udma_wrapper.h"
@@ -39,6 +41,7 @@ struct dma_siwx91x_channel_info {
3941
void *cb_data; /* User callback data */
4042
RSI_UDMA_DESC_T *sg_desc_addr_info; /* Scatter-Gather table start address */
4143
enum dma_xfer_dir xfer_direction; /* mem<->mem ot per<->mem */
44+
bool channel_active; /* Channel active flag */
4245
};
4346

4447
struct dma_siwx91x_config {
@@ -60,6 +63,16 @@ struct dma_siwx91x_data {
6063
*/
6164
};
6265

66+
static void siwx91x_dma_pm_policy_state_lock_get(void)
67+
{
68+
pm_policy_state_lock_get(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES);
69+
}
70+
71+
static void siwx91x_dma_pm_policy_state_lock_put(void)
72+
{
73+
pm_policy_state_lock_put(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES);
74+
}
75+
6376
static enum dma_xfer_dir siwx91x_transfer_direction(uint32_t dir)
6477
{
6578
if (dir == MEMORY_TO_MEMORY) {
@@ -482,7 +495,17 @@ static int siwx91x_dma_start(const struct device *dev, uint32_t channel)
482495
return -EINVAL;
483496
}
484497

498+
/* Get the power management policy state lock */
499+
if (!data->zephyr_channel_info[channel].channel_active) {
500+
siwx91x_dma_pm_policy_state_lock_get();
501+
data->zephyr_channel_info[channel].channel_active = true;
502+
}
503+
485504
if (RSI_UDMA_ChannelEnable(udma_handle, channel) != 0) {
505+
if (data->zephyr_channel_info[channel].channel_active) {
506+
siwx91x_dma_pm_policy_state_lock_put();
507+
data->zephyr_channel_info[channel].channel_active = false;
508+
}
486509
return -EINVAL;
487510
}
488511

@@ -510,6 +533,11 @@ static int siwx91x_dma_stop(const struct device *dev, uint32_t channel)
510533
return -EIO;
511534
}
512535

536+
if (data->zephyr_channel_info[channel].channel_active) {
537+
siwx91x_dma_pm_policy_state_lock_put();
538+
data->zephyr_channel_info[channel].channel_active = false;
539+
}
540+
513541
return 0;
514542
}
515543

@@ -560,8 +588,7 @@ bool siwx91x_dma_chan_filter(const struct device *dev, int channel, void *filter
560588
}
561589
}
562590

563-
/* Function to initialize DMA peripheral */
564-
static int siwx91x_dma_init(const struct device *dev)
591+
static int dma_siwx91x_pm_action(const struct device *dev, enum pm_device_action action)
565592
{
566593
const struct dma_siwx91x_config *cfg = dev->config;
567594
struct dma_siwx91x_data *data = dev->data;
@@ -573,25 +600,45 @@ static int siwx91x_dma_init(const struct device *dev)
573600
};
574601
int ret;
575602

576-
ret = clock_control_on(cfg->clock_dev, cfg->clock_subsys);
577-
if (ret) {
578-
return ret;
579-
}
603+
switch (action) {
604+
case PM_DEVICE_ACTION_RESUME:
605+
break;
606+
case PM_DEVICE_ACTION_SUSPEND:
607+
break;
608+
case PM_DEVICE_ACTION_TURN_ON:
609+
ret = clock_control_on(cfg->clock_dev, cfg->clock_subsys);
610+
if (ret < 0 && ret != -EALREADY) {
611+
return ret;
612+
}
580613

581-
udma_handle = UDMAx_Initialize(&udma_resources, udma_resources.desc, NULL,
582-
(uint32_t *)&data->udma_handle);
583-
if (udma_handle != &data->udma_handle) {
584-
return -EINVAL;
614+
udma_handle = UDMAx_Initialize(&udma_resources, udma_resources.desc, NULL,
615+
(uint32_t *)&data->udma_handle);
616+
if (udma_handle != &data->udma_handle) {
617+
return -EINVAL;
618+
}
619+
620+
if (UDMAx_DMAEnable(&udma_resources, udma_handle) != 0) {
621+
return -EBUSY;
622+
}
623+
break;
624+
case PM_DEVICE_ACTION_TURN_OFF:
625+
break;
626+
default:
627+
return -ENOTSUP;
585628
}
586629

630+
return 0;
631+
}
632+
633+
/* Function to initialize DMA peripheral */
634+
static int siwx91x_dma_init(const struct device *dev)
635+
{
636+
const struct dma_siwx91x_config *cfg = dev->config;
637+
587638
/* Connect the DMA interrupt */
588639
cfg->irq_configure();
589640

590-
if (UDMAx_DMAEnable(&udma_resources, udma_handle) != 0) {
591-
return -EBUSY;
592-
}
593-
594-
return 0;
641+
return pm_device_driver_init(dev, dma_siwx91x_pm_action);
595642
}
596643

597644
static void siwx91x_dma_isr(const struct device *dev)
@@ -639,6 +686,10 @@ static void siwx91x_dma_isr(const struct device *dev)
639686
dev, data->zephyr_channel_info[channel].cb_data, channel, 0);
640687
}
641688
sys_write32(BIT(channel), (mem_addr_t)&cfg->reg->UDMA_DONE_STATUS_REG);
689+
if (data->zephyr_channel_info[channel].channel_active) {
690+
siwx91x_dma_pm_policy_state_lock_put();
691+
data->zephyr_channel_info[channel].channel_active = false;
692+
}
642693
} else {
643694
/* Call UDMA ROM IRQ handler. */
644695
ROMAPI_UDMA_WRAPPER_API->uDMAx_IRQHandler(&udma_resources, udma_resources.desc,
@@ -701,7 +752,10 @@ static DEVICE_API(dma, siwx91x_dma_api) = {
701752
(siwx91x_dma_chan_desc##inst)), \
702753
.irq_configure = siwx91x_dma_irq_configure_##inst, \
703754
}; \
704-
DEVICE_DT_INST_DEFINE(inst, siwx91x_dma_init, NULL, &dma_data_##inst, &dma_cfg_##inst, \
705-
POST_KERNEL, CONFIG_DMA_INIT_PRIORITY, &siwx91x_dma_api);
755+
PM_DEVICE_DT_INST_DEFINE(inst, dma_siwx91x_pm_action); \
756+
DEVICE_DT_INST_DEFINE(inst, siwx91x_dma_init, PM_DEVICE_DT_INST_GET(inst), \
757+
&dma_data_##inst, &dma_cfg_##inst, POST_KERNEL, \
758+
CONFIG_DMA_INIT_PRIORITY, \
759+
&siwx91x_dma_api);
706760

707761
DT_INST_FOREACH_STATUS_OKAY(SIWX91X_DMA_INIT)

dts/arm/silabs/siwg917.dtsi

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,8 @@
309309
clocks = <&clock0 SIWX91X_CLK_DMA0>;
310310
#dma-cells = <1>;
311311
dma-channels = <32>;
312+
power-domains = <&siwx91x_soc_pd>;
313+
zephyr,pm-device-runtime-auto;
312314
status = "disabled";
313315
};
314316

@@ -323,6 +325,8 @@
323325
silabs,sram-region = <&sram_dma1>;
324326
#dma-cells = <1>;
325327
dma-channels = <12>;
328+
power-domains = <&siwx91x_soc_pd>;
329+
zephyr,pm-device-runtime-auto;
326330
status = "disabled";
327331
};
328332

0 commit comments

Comments
 (0)