Skip to content

Commit

Permalink
drivers: gpdma: power flow refactor
Browse files Browse the repository at this point in the history
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 <tomasz.m.leman@intel.com>
  • Loading branch information
tmleman authored and carlescufi committed Apr 25, 2023
1 parent 4805d7b commit 705d1c2
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 19 deletions.
8 changes: 0 additions & 8 deletions drivers/dma/dma_dw_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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;
}
Expand Down
41 changes: 30 additions & 11 deletions drivers/dma/dma_intel_adsp_gpdma.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -173,26 +174,28 @@ 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);
if (ret != 0) {
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.
*/
if (first_use) {
ret = pm_device_runtime_put(dev);
}
#endif

return ret;
}
Expand Down Expand Up @@ -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;
Expand All @@ -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);
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 705d1c2

Please sign in to comment.