From c86271ab2b3fd427275a1be46f1fa3c96d787131 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Tue, 28 Sep 2021 16:35:46 -0700 Subject: [PATCH 1/5] drivers: Intel: hda-dma: remove check for config->cyclic config->cyclic is not relevant for HDA DMAs. So remove the check for it. We set config->cyclic to 1 for both playback and capture for all DAI's anyway. So the check today would never set FIFORDY for host output DMA during set_config. But nevertheless, during the start trigger, FIFORDY is set for all DMA's unconditionally. That is also incorrect and will be fixed in the following commit. For now, just remove the check for cyclic to prepare for FIFORDY bit cleanup. Signed-off-by: Ranjani Sridharan --- src/drivers/intel/hda/hda-dma.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/drivers/intel/hda/hda-dma.c b/src/drivers/intel/hda/hda-dma.c index 8d3e56b40bb6..f45fec67bbe3 100644 --- a/src/drivers/intel/hda/hda-dma.c +++ b/src/drivers/intel/hda/hda-dma.c @@ -757,8 +757,7 @@ static int hda_dma_set_config(struct dma_chan_data *channel, dgcs |= DGCS_SCS; /* set DGCS.FIFORDY for output dma */ - if ((config->cyclic && config->direction == DMA_DIR_MEM_TO_DEV) || - (!config->cyclic && config->direction == DMA_DIR_LMEM_TO_HMEM)) + if (config->direction == DMA_DIR_MEM_TO_DEV || config->direction == DMA_DIR_LMEM_TO_HMEM) dgcs |= DGCS_FIFORDY; dma_chan_reg_write(channel, DGCS, dgcs); From a1158c8ddd7a910ec0f512bb82a26b7142a87a3f Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Tue, 28 Sep 2021 16:30:41 -0700 Subject: [PATCH 2/5] drivers: Intel: hda-dma: FIFORDY bit is only valid for host DMA So, leave this bit untouched for link DMA and only set/clear it for the host DMA for both playback and capture. Signed-off-by: Ranjani Sridharan --- src/drivers/intel/hda/hda-dma.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/drivers/intel/hda/hda-dma.c b/src/drivers/intel/hda/hda-dma.c index f45fec67bbe3..d03a4a93bf6d 100644 --- a/src/drivers/intel/hda/hda-dma.c +++ b/src/drivers/intel/hda/hda-dma.c @@ -390,20 +390,21 @@ static int hda_dma_enable_unlock(struct dma_chan_data *channel) hda_dma_get_dbg_vals(channel, HDA_DBG_PRE, HDA_DBG_BOTH); - /* enable the channel */ - dma_chan_reg_update_bits(channel, DGCS, DGCS_GEN | DGCS_FIFORDY, - DGCS_GEN | DGCS_FIFORDY); - /* full buffer is copied at startup */ hda_chan = dma_chan_get_data(channel); hda_chan->desc_avail = channel->desc_count; + /* enable the channel */ if (channel->direction == DMA_DIR_HMEM_TO_LMEM || channel->direction == DMA_DIR_LMEM_TO_HMEM) { + dma_chan_reg_update_bits(channel, DGCS, DGCS_GEN | DGCS_FIFORDY, + DGCS_FIFORDY | DGCS_GEN); pm_runtime_get(PM_RUNTIME_HOST_DMA_L1, 0); ret = hda_dma_host_start(channel); if (ret < 0) return ret; + } else { + dma_chan_reg_update_bits(channel, DGCS, DGCS_GEN, DGCS_GEN); } /* start link output transfer now */ @@ -613,12 +614,15 @@ static int hda_dma_stop(struct dma_chan_data *channel) tr_dbg(&hdma_tr, "hda-dmac: %d channel %d -> stop", channel->dma->plat_data.id, channel->index); + /* disable the channel */ if (channel->direction == DMA_DIR_HMEM_TO_LMEM || - channel->direction == DMA_DIR_LMEM_TO_HMEM) + channel->direction == DMA_DIR_LMEM_TO_HMEM) { hda_dma_host_stop(channel); - /* disable the channel */ - dma_chan_reg_update_bits(channel, DGCS, DGCS_GEN | DGCS_FIFORDY, 0); + dma_chan_reg_update_bits(channel, DGCS, DGCS_FIFORDY | DGCS_GEN, 0); + } else { + dma_chan_reg_update_bits(channel, DGCS, DGCS_GEN, 0); + } channel->status = COMP_STATE_PREPARE; hda_chan = dma_chan_get_data(channel); hda_chan->state = 0; @@ -756,8 +760,8 @@ static int hda_dma_set_config(struct dma_chan_data *channel, config->src_width <= 2)) dgcs |= DGCS_SCS; - /* set DGCS.FIFORDY for output dma */ - if (config->direction == DMA_DIR_MEM_TO_DEV || config->direction == DMA_DIR_LMEM_TO_HMEM) + /* set DGCS.FIFORDY for input/output host DMA only. It is not relevant for link DMA's */ + if (config->direction == DMA_DIR_HMEM_TO_LMEM || config->direction == DMA_DIR_LMEM_TO_HMEM) dgcs |= DGCS_FIFORDY; dma_chan_reg_write(channel, DGCS, dgcs); From 1973a66ae3987f94ff780256f6183d49fac6528a Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Tue, 28 Sep 2021 11:33:35 -0700 Subject: [PATCH 3/5] drivers: Intel: hda-dma: remove unnecessary code in start/release Host DMA is never paused or released. Remove the code to start host DMA during release and the check for release in hda_dma_host_start(). Signed-off-by: Ranjani Sridharan --- src/drivers/intel/hda/hda-dma.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/src/drivers/intel/hda/hda-dma.c b/src/drivers/intel/hda/hda-dma.c index d03a4a93bf6d..0dc31594bd0e 100644 --- a/src/drivers/intel/hda/hda-dma.c +++ b/src/drivers/intel/hda/hda-dma.c @@ -348,9 +348,8 @@ static int hda_dma_host_start(struct dma_chan_data *channel) struct hda_chan_data *hda_chan = dma_chan_get_data(channel); int ret = 0; - /* Force Host DMA to exit L1 only on start*/ - if (!(hda_chan->state & HDA_STATE_RELEASE)) - pm_runtime_put(PM_RUNTIME_HOST_DMA_L1, 0); + /* Force Host DMA to exit L1 on start */ + pm_runtime_put(PM_RUNTIME_HOST_DMA_L1, 0); if (!hda_chan->irq_disabled) return ret; @@ -566,16 +565,8 @@ static int hda_dma_release(struct dma_chan_data *channel) tr_dbg(&hdma_tr, "hda-dmac: %d channel %d -> release", channel->dma->plat_data.id, channel->index); - /* - * Prepare for the handling of release condition on the first work cb. - * This flag will be unset afterwards. - */ hda_chan->state |= HDA_STATE_RELEASE; - if (channel->direction == DMA_DIR_HMEM_TO_LMEM || - channel->direction == DMA_DIR_LMEM_TO_HMEM) - ret = hda_dma_host_start(channel); - irq_local_enable(flags); return ret; } From 10e25f716b4534b1743beac6afffc15602d816f3 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Tue, 28 Sep 2021 11:36:18 -0700 Subject: [PATCH 4/5] lib: dma: make pause/release ops optional Not all DMA's need a pause/release. Signed-off-by: Ranjani Sridharan --- src/include/sof/lib/dma.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/include/sof/lib/dma.h b/src/include/sof/lib/dma.h index 43726b52441c..fac3d0c6ef9d 100644 --- a/src/include/sof/lib/dma.h +++ b/src/include/sof/lib/dma.h @@ -335,16 +335,18 @@ static inline int dma_copy(struct dma_chan_data *channel, int bytes, static inline int dma_pause(struct dma_chan_data *channel) { - int ret = channel->dma->ops->pause(channel); + if (channel->dma->ops->pause) + return channel->dma->ops->pause(channel); - return ret; + return 0; } static inline int dma_release(struct dma_chan_data *channel) { - int ret = channel->dma->ops->release(channel); + if (channel->dma->ops->release) + return channel->dma->ops->release(channel); - return ret; + return 0; } static inline int dma_status(struct dma_chan_data *channel, From 0e092f2312f12ad3e698b1dddfbeaa118bf34410 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Tue, 28 Sep 2021 11:37:26 -0700 Subject: [PATCH 5/5] drivers: Intel: hda-dma: remove pause/release ops from hda_host_dma_ops Host DMA is never paused/released. So, remove the pause and release ops from the host DMA ops. Signed-off-by: Ranjani Sridharan --- src/drivers/intel/hda/hda-dma.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/drivers/intel/hda/hda-dma.c b/src/drivers/intel/hda/hda-dma.c index 0dc31594bd0e..0e911afd2181 100644 --- a/src/drivers/intel/hda/hda-dma.c +++ b/src/drivers/intel/hda/hda-dma.c @@ -980,8 +980,6 @@ const struct dma_ops hda_host_dma_ops = { .start = hda_dma_start, .stop = hda_dma_stop, .copy = hda_dma_host_copy, - .pause = hda_dma_pause, - .release = hda_dma_release, .status = hda_dma_status, .set_config = hda_dma_set_config, .pm_context_restore = hda_dma_pm_context_restore,