From 705d1c2c0405e9c776756292cdfb68660eaf222c Mon Sep 17 00:00:00 2001 From: Tomasz Leman Date: Mon, 6 Feb 2023 15:58:34 +0100 Subject: [PATCH] drivers: gpdma: power flow refactor This patch is refactoring device power flow routine. DMA instance will not be power up after kernel initialization if device power management is enabled. Power menager will power up device and its power domain if device will be in use and disable it when it's no longer needed. The DMA disabling part has not yet been implemented. Signed-off-by: Tomasz Leman --- drivers/dma/dma_dw_common.c | 8 ------ drivers/dma/dma_intel_adsp_gpdma.c | 41 ++++++++++++++++++++++-------- 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/drivers/dma/dma_dw_common.c b/drivers/dma/dma_dw_common.c index 4f1ce57d4d28ff..70b820b345f8b7 100644 --- a/drivers/dma/dma_dw_common.c +++ b/drivers/dma/dma_dw_common.c @@ -665,7 +665,6 @@ int dw_dma_suspend(const struct device *dev, uint32_t channel) int dw_dma_setup(const struct device *dev) { const struct dw_dma_dev_cfg *const dev_cfg = dev->config; - struct dw_dma_dev_data *const dev_data = dev->data; int i, ret = 0; @@ -718,13 +717,6 @@ int dw_dma_setup(const struct device *dev) #endif /* CONFIG_DMA_DW_FIFO_PARTITION */ /* TODO add baytrail/cherrytrail workaround */ - - - /* Setup context and atomics for channels */ - dev_data->dma_ctx.magic = DMA_MAGIC; - dev_data->dma_ctx.dma_channels = DW_MAX_CHAN; - dev_data->dma_ctx.atomic = dev_data->channels_atomic; - out: return ret; } diff --git a/drivers/dma/dma_intel_adsp_gpdma.c b/drivers/dma/dma_intel_adsp_gpdma.c index 2435fdbf6883dd..e0de3254f397e5 100644 --- a/drivers/dma/dma_intel_adsp_gpdma.c +++ b/drivers/dma/dma_intel_adsp_gpdma.c @@ -162,6 +162,7 @@ static int intel_adsp_gpdma_config(const struct device *dev, uint32_t channel, static int intel_adsp_gpdma_start(const struct device *dev, uint32_t channel) { int ret = 0; +#if CONFIG_PM_DEVICE bool first_use = false; enum pm_device_state state; @@ -173,12 +174,12 @@ static int intel_adsp_gpdma_start(const struct device *dev, uint32_t channel) first_use = state != PM_DEVICE_STATE_ACTIVE; if (first_use) { ret = pm_device_runtime_get(dev); + if (ret < 0) { + return ret; + } } } - - if (ret < 0) { - return ret; - } +#endif intel_adsp_gpdma_llp_enable(dev, channel); ret = dw_dma_start(dev, channel); @@ -186,6 +187,7 @@ static int intel_adsp_gpdma_start(const struct device *dev, uint32_t channel) intel_adsp_gpdma_llp_disable(dev, channel); } +#if CONFIG_PM_DEVICE /* Device usage is counted by the calls of dw_dma_start and dw_dma_stop. For the first use, * we need to make sure that the pm_device_runtime_get and pm_device_runtime_put functions * calls are balanced. @@ -193,6 +195,7 @@ static int intel_adsp_gpdma_start(const struct device *dev, uint32_t channel) if (first_use) { ret = pm_device_runtime_put(dev); } +#endif return ret; } @@ -286,7 +289,7 @@ static int intel_adsp_gpdma_enable(const struct device *dev) } #endif -int intel_adsp_gpdma_init(const struct device *dev) +static int intel_adsp_gpdma_power_on(const struct device *dev) { const struct intel_adsp_gpdma_cfg *const dev_cfg = dev->config; int ret; @@ -295,11 +298,6 @@ int intel_adsp_gpdma_init(const struct device *dev) /* Power up */ ret = intel_adsp_gpdma_enable(dev); - if (ret == 0) { - pm_device_init_suspended(dev); - ret = pm_device_runtime_enable(dev); - } - if (ret != 0) { LOG_ERR("%s: dma %s failed to initialize", __func__, dev->name); @@ -368,12 +366,33 @@ int intel_adsp_gpdma_get_attribute(const struct device *dev, uint32_t type, uint return 0; } +int intel_adsp_gpdma_init(const struct device *dev) +{ + struct dw_dma_dev_data *const dev_data = dev->data; + + /* Setup context and atomics for channels */ + dev_data->dma_ctx.magic = DMA_MAGIC; + dev_data->dma_ctx.dma_channels = DW_MAX_CHAN; + dev_data->dma_ctx.atomic = dev_data->channels_atomic; +#if CONFIG_PM_DEVICE + if (pm_device_on_power_domain(dev)) { + pm_device_init_off(dev); + } else { + pm_device_init_suspended(dev); + } + + return pm_device_runtime_enable(dev); +#else + return intel_adsp_gpdma_power_on(dev); +#endif +} #ifdef CONFIG_PM_DEVICE static int gpdma_pm_action(const struct device *dev, enum pm_device_action action) { switch (action) { - case PM_DEVICE_ACTION_SUSPEND: case PM_DEVICE_ACTION_RESUME: + return intel_adsp_gpdma_power_on(dev); + case PM_DEVICE_ACTION_SUSPEND: case PM_DEVICE_ACTION_TURN_ON: case PM_DEVICE_ACTION_TURN_OFF: break;