Skip to content

Add timeout for HDA DMA Buffer full wait to avoid FW hang #723

Closed

Description

@keyonjie

We are seeing FW hang at waiting HDA DMA buffer full(looks we can't get buffer full at some cases, no matter how long we wait).

To avoid this, we need to implement TODO in below comment in hda-dma.c:hda_dma_host_preload(),

while (!(host_dma_reg_read(dma, chan->index, DGCS) & DGCS_BF) &&
	       (chan->state & HDA_STATE_BF_WAIT))
		; /* TODO: this should timeout and not wait forever */

Activity

  1. added
    blockedprogress blocked by something else, applies to either feature or bug
    on Dec 14, 2018
  2. keyonjie commented on Dec 14, 2018

    @keyonjie
    ContributorAuthor

    @mmaka1 Hi Marcin, I am assigning this to you, please feel free to assign it to anybody in your team who can help on it.

  3. removed
    blockedprogress blocked by something else, applies to either feature or bug
    on Dec 14, 2018
  4. lgirdwood commented on Dec 17, 2018

    @lgirdwood
    Member

    Lets make this timeout PLATFORM specific and define in platform.h

  5. added
    APLApplies to Apollolake platform
    P1Blocker bugs or important features
    on Dec 27, 2018
  6. keyonjie commented on Dec 27, 2018

    @keyonjie
    ContributorAuthor

    some local change which actually workaround this issue:

    diff --git a/src/drivers/intel/cavs/hda-dma.c b/src/drivers/intel/cavs/hda-dma.c
    index 7250f68d..9ea45906 100644
    --- a/src/drivers/intel/cavs/hda-dma.c
    +++ b/src/drivers/intel/cavs/hda-dma.c
    @@ -327,12 +327,14 @@ static int hda_dma_host_preload(struct dma *dma, struct hda_chan_data *chan)
            };
            int i;
            int period_cnt;
    +       int count = 20;
     
            /* waiting for buffer full after start
             * first try is unblocking, then blocking
             */
            while (!(host_dma_reg_read(dma, chan->index, DGCS) & DGCS_BF) &&
    -              (chan->state & HDA_STATE_BF_WAIT))
    +//            (chan->state & HDA_STATE_BF_WAIT))
    +              (chan->state & HDA_STATE_BF_WAIT) && (count-- > 0))
                    ; /* TODO: this should timeout and not wait forever */
     
            if (host_dma_reg_read(dma, chan->index, DGCS) & DGCS_BF) {
    @@ -348,7 +350,9 @@ static int hda_dma_host_preload(struct dma *dma, struct hda_chan_data *chan)
                    }
            } else {
                    /* next call in pre-load state will be blocking */
    -               chan->state |= HDA_STATE_BF_WAIT;
    +//             chan->state |= HDA_STATE_BF_WAIT;
    +               
    +               chan->state &= ~(HDA_STATE_HOST_PRELOAD | HDA_STATE_BF_WAIT);
            }
     
            return 0;
    
  7. self-assigned this
    on Dec 27, 2018
  8. jajanusz commented on Dec 27, 2018

    @jajanusz
    Contributor

    @keyonjie
    Please check if #783 is good enough for you. There are no reproduction steps, so I didn't test it.

  9. wenqingfu commented on Jan 9, 2019

    @wenqingfu

    according to the discussion in #783 , this issue can be closed. @keyonjie will open new issue if there are timeouts on top of it. Please be sure to include more details how to reproduce it next time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

APLApplies to Apollolake platformP1Blocker bugs or important featuresbugSomething isn't working as expected

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions