Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 367
Fixes for HDA-DMA driver#4820
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
Fixes for HDA-DMA driver #4820
Changes from all commits
c86271aa1158c81973a6610e25f70e092f2File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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; | ||
| @@ -390,20 +389,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 */ | ||
| @@ -565,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; | ||
plbossart marked this conversation as resolved.
Outdated
Uh oh!There was an error while loading. Please reload this page. | ||
| if (channel->direction == DMA_DIR_HMEM_TO_LMEM || | ||
| channel->direction == DMA_DIR_LMEM_TO_HMEM) | ||
| ret = hda_dma_host_start(channel); | ||
Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same, not able to follow this simplification - not sure why we did a host_start in a dma_release in the first place. Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah, this change looks unrelated to RELEASE removal ? Line 570 also sets the RELEASE state, should we remove RELEASE completely ? | ||
| irq_local_enable(flags); | ||
| return ret; | ||
| } | ||
| @@ -613,12 +605,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,9 +751,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->cyclic && config->direction == DMA_DIR_MEM_TO_DEV) || | ||
| (!config->cyclic && 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) | ||
Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would agree with @keyonjie that it's not clear why we need to keep setting this FIFORDY bit in hda_dma_set_config(), when it's already set in enable_dma() and cleared in stop_dma() | ||
| dgcs |= DGCS_FIFORDY; | ||
| dma_chan_reg_write(channel, DGCS, dgcs); | ||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since we set/clear DGCS_FIFORDY explicitly in start/stop, do we need to preset it in _set_config() here? Collaborator There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this seems to directly contradict the stated purpose of f96878a
| ||
| @@ -986,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, | ||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "hda_dma_pause/release declared but not used"? CollaboratorAuthor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sorry dont get it? it is used in link DMA ops Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Oh, makes sense then, maybe better to rename them to hda_dma_link_pause/release(). | ||
| .status = hda_dma_status, | ||
| .set_config = hda_dma_set_config, | ||
| .pm_context_restore = hda_dma_pm_context_restore, | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the original logic is that we don't need to force L1 exit for the pause/release iteration, while we need it for a _start, as there will be preloading for a hda_dma_start() while there isn't for the _release().
We do have dma_pause() and dma_release() calling in dai.c, even though there might not be trigger pause/release IPCs from the Linux host side, so I would suggest to keep this as it is in case it doesn't bring any issues like Xruns to us.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@keyonjie DAI uses link DMA and we have the ops for link DMA here. There is no need for host DMA pause/release when it is not used