* delayed dma trigger @ 2006-10-23 8:49 Johannes Berg 2006-10-23 13:23 ` Takashi Iwai 0 siblings, 1 reply; 7+ messages in thread From: Johannes Berg @ 2006-10-23 8:49 UTC (permalink / raw) To: alsa-devel; +Cc: Takashi Iwai, Benjamin Berg, Paul Collins Hi, For AOA, there are some DMA engine programming pitfalls I wasn't aware of previously (actually, I was aware of the bug it triggered but not quite why it happened). But now we have two questions about the trigger callback. (1) When correctly using the i2s bus (aoa isn't at the moment), it is not possible to immediately stop doing DMA, the DMA engine has to finish the current period first, then go into a stop condition, and only after that we can stop the engine completely. Hence, this can take quite a while (up to the period length). Is it ok to set the stop condition and return from the trigger function without having DMA stopped? It'll be completely stopped asynchronously on the next interrupt, and we'd have to make the hw_free callback wait for that, I guess. (2) Relating to that, if a start trigger comes in before the DMA engine is stopped, it would be nice if we could just clear the stop condition and let it continue to run. Can recording start at any arbitrary period in the buffer relying only on the pointer callback? [Actually, come to think of it, isn't this required for proper 'pause' function during playback or recording? I guess aoa is wrong now then?] johannes ------------------------------------------------------------------------- Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: delayed dma trigger 2006-10-23 8:49 delayed dma trigger Johannes Berg @ 2006-10-23 13:23 ` Takashi Iwai 2006-10-23 13:46 ` Johannes Berg 0 siblings, 1 reply; 7+ messages in thread From: Takashi Iwai @ 2006-10-23 13:23 UTC (permalink / raw) To: Johannes Berg; +Cc: alsa-devel, Paul Collins, Benjamin Berg At Mon, 23 Oct 2006 10:49:51 +0200, Johannes Berg wrote: > > Hi, > > For AOA, there are some DMA engine programming pitfalls I wasn't aware > of previously (actually, I was aware of the bug it triggered but not > quite why it happened). But now we have two questions about the trigger > callback. > > (1) > When correctly using the i2s bus (aoa isn't at the moment), it is not > possible to immediately stop doing DMA, the DMA engine has to finish the > current period first, then go into a stop condition, and only after that > we can stop the engine completely. Hence, this can take quite a while > (up to the period length). Is it ok to set the stop condition and return > from the trigger function without having DMA stopped? It'll be > completely stopped asynchronously on the next interrupt, and we'd have > to make the hw_free callback wait for that, I guess. Yes, but hw_free isn't enough. You'd need a DMA sync in prepare callback since a typical repeated play flow is like: open -> hw_params -> prepare -> trigger(START) -> running -> trigger(STOP) -> prepare -> trigger(START) -> ... > (2) > Relating to that, if a start trigger comes in before the DMA engine is > stopped, it would be nice if we could just clear the stop condition and > let it continue to run. Can recording start at any arbitrary period in > the buffer relying only on the pointer callback? > [Actually, come to think of it, isn't this required for proper 'pause' > function during playback or recording? I guess aoa is wrong now then?] Well, you can of course trick in the lowlevel code as if DMA is newly started. For PCM middle layer, it doesn't matter. But, the value returned from pointer callback must be reset to zero once after prepare callback is called. So, the lowlevel code should handle an offset from the actual DMA pointer value in such a case. Takashi ------------------------------------------------------------------------- Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: delayed dma trigger 2006-10-23 13:23 ` Takashi Iwai @ 2006-10-23 13:46 ` Johannes Berg 2006-10-23 14:11 ` Takashi Iwai 0 siblings, 1 reply; 7+ messages in thread From: Johannes Berg @ 2006-10-23 13:46 UTC (permalink / raw) To: Takashi Iwai; +Cc: alsa-devel, Paul Mackerras, Paul Collins, Benjamin Berg Paul (Collins), sorry about that, I didn't mean to CC you. Please ignore. Paul (Mackeras), sorry as well, I meant to CC you on the original mail instead of Paul Collins. I've left all the quoted text instead. Takashi, thanks for your reply. > > For AOA, there are some DMA engine programming pitfalls I wasn't aware > > of previously (actually, I was aware of the bug it triggered but not > > quite why it happened). But now we have two questions about the trigger > > callback. > > > > (1) > > When correctly using the i2s bus (aoa isn't at the moment), it is not > > possible to immediately stop doing DMA, the DMA engine has to finish the > > current period first, then go into a stop condition, and only after that > > we can stop the engine completely. Hence, this can take quite a while > > (up to the period length). Is it ok to set the stop condition and return > > from the trigger function without having DMA stopped? It'll be > > completely stopped asynchronously on the next interrupt, and we'd have > > to make the hw_free callback wait for that, I guess. > > Yes, but hw_free isn't enough. You'd need a DMA sync in prepare > callback since a typical repeated play flow is like: > open -> hw_params -> prepare -> trigger(START) -> > running -> trigger(STOP) -> > prepare -> trigger(START) -> ... Right, but prepare can sleep as well so it's easy to do. Though if the prepare doesn't actually change anything, couldn't we not stop the DMA and just continue? > > (2) > > Relating to that, if a start trigger comes in before the DMA engine is > > stopped, it would be nice if we could just clear the stop condition and > > let it continue to run. Can recording start at any arbitrary period in > > the buffer relying only on the pointer callback? > > [Actually, come to think of it, isn't this required for proper 'pause' > > function during playback or recording? I guess aoa is wrong now then?] > > Well, you can of course trick in the lowlevel code as if DMA is newly > started. For PCM middle layer, it doesn't matter. > > But, the value returned from pointer callback must be reset to zero > once after prepare callback is called. So, the lowlevel code should > handle an offset from the actual DMA pointer value in such a case. Let me put it in my words to see if I understand things correctly. Let me always use a picture like this |...|...|...|...| for the sample buffer, where the | indicates a new period. First, pause/resume. If we pause playing in the middle of some period |...|...|...|...| ^ pause request here what we'll have to do is make it play until the period ends: |...|...|...|...| ^ pauses here Then, if we want to resume playing, we should probably continue at exactly that same spot, right? Currently, I think I restart at the first period. Now, with stop/play instead of pause/resume, does the picture change? There's a prepare between the trigger calls, and that could give us a whole new buffer, right? And the period size might even be different. Hence, we'll need to create a whole new set of DBDMA commands after waiting for the stop to complete, I guess. But if the prepare can give us a whole new buffer, what guarantees that the old buffer is still there to do DMA on after triggering a stop? Or does one need to close/re-open the device to change buffers/periodsize/...? Anyway, except for that I'd think that in the play/resume trigger, we can see if things are stopped and if it's still running we just clear the stop condition. If in prepare we wait for it to stop completely, that's fine since we'll have created a whole new dbdma command set. Correct me if I'm wrong. johannes ------------------------------------------------------------------------- Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: delayed dma trigger 2006-10-23 13:46 ` Johannes Berg @ 2006-10-23 14:11 ` Takashi Iwai 2006-10-23 14:31 ` Johannes Berg 0 siblings, 1 reply; 7+ messages in thread From: Takashi Iwai @ 2006-10-23 14:11 UTC (permalink / raw) To: Johannes Berg; +Cc: alsa-devel, Paul Mackerras, Benjamin Berg [Removed Paul Collins from Cc now] At Mon, 23 Oct 2006 15:46:52 +0200, Johannes Berg wrote: > > > > For AOA, there are some DMA engine programming pitfalls I wasn't aware > > > of previously (actually, I was aware of the bug it triggered but not > > > quite why it happened). But now we have two questions about the trigger > > > callback. > > > > > > (1) > > > When correctly using the i2s bus (aoa isn't at the moment), it is not > > > possible to immediately stop doing DMA, the DMA engine has to finish the > > > current period first, then go into a stop condition, and only after that > > > we can stop the engine completely. Hence, this can take quite a while > > > (up to the period length). Is it ok to set the stop condition and return > > > from the trigger function without having DMA stopped? It'll be > > > completely stopped asynchronously on the next interrupt, and we'd have > > > to make the hw_free callback wait for that, I guess. > > > > Yes, but hw_free isn't enough. You'd need a DMA sync in prepare > > callback since a typical repeated play flow is like: > > open -> hw_params -> prepare -> trigger(START) -> > > running -> trigger(STOP) -> > > prepare -> trigger(START) -> ... > > Right, but prepare can sleep as well so it's easy to do. Though if the > prepare doesn't actually change anything, couldn't we not stop the DMA > and just continue? It's up to you. My point is the prepare callback is called anyway, and if you want to resolve the DMA call conflict, prepare callback is the right place. But, if trigger(START) checks whether the DMA is already is running and just continues, then yes, you don't have to wait in prepare. > > > (2) > > > Relating to that, if a start trigger comes in before the DMA engine is > > > stopped, it would be nice if we could just clear the stop condition and > > > let it continue to run. Can recording start at any arbitrary period in > > > the buffer relying only on the pointer callback? > > > [Actually, come to think of it, isn't this required for proper 'pause' > > > function during playback or recording? I guess aoa is wrong now then?] > > > > Well, you can of course trick in the lowlevel code as if DMA is newly > > started. For PCM middle layer, it doesn't matter. > > > > But, the value returned from pointer callback must be reset to zero > > once after prepare callback is called. So, the lowlevel code should > > handle an offset from the actual DMA pointer value in such a case. > > Let me put it in my words to see if I understand things correctly. > Let me always use a picture like this > |...|...|...|...| > for the sample buffer, where the | indicates a new period. > > First, pause/resume. If we pause playing in the middle of some period > |...|...|...|...| > ^ pause request here > what we'll have to do is make it play until the period ends: > |...|...|...|...| > ^ pauses here > Then, if we want to resume playing, we should probably continue at > exactly that same spot, right? Currently, I think I restart at the first > period. Ah now I understood what you meant. > Now, with stop/play instead of pause/resume, does the picture change? > There's a prepare between the trigger calls, and that could give us a > whole new buffer, right? And the period size might even be different. > Hence, we'll need to create a whole new set of DBDMA commands after > waiting for the stop to complete, I guess. Yes, almost. The prepare callback won't assign any new buffers but just reset the positions to zero in most cases. But, the app could resize the buffer, so yes, it can happen after the following sequence: stop -> hw_free -> hw_params -> prepare -> start > But if the prepare can give us a whole new buffer, what guarantees that > the old buffer is still there to do DMA on after triggering a stop? Or > does one need to close/re-open the device to change > buffers/periodsize/...? It's hw_free/hw_params call as mentioned in the above. > Anyway, except for that I'd think that in the play/resume trigger, we > can see if things are stopped and if it's still running we just clear > the stop condition. If in prepare we wait for it to stop completely, > that's fine since we'll have created a whole new dbdma command set. Sounds feasible. You can add a check whether you can reuse the running DBDMA (i.e. period/buffer address and size are unchanged), for example. But, still I think a DMA sync in prepare would be an easier solution since the same check would be needed for hw_free anyway. Another merit is that the trigger(START) callback does start the stream at the very same moment it's issued. With the continous DBDMA, the start of stream might be delayed than the triggered time. Takashi ------------------------------------------------------------------------- Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: delayed dma trigger 2006-10-23 14:11 ` Takashi Iwai @ 2006-10-23 14:31 ` Johannes Berg 2006-10-24 15:07 ` Takashi Iwai 0 siblings, 1 reply; 7+ messages in thread From: Johannes Berg @ 2006-10-23 14:31 UTC (permalink / raw) To: Takashi Iwai; +Cc: alsa-devel, Paul Mackerras, Benjamin Berg On Mon, 2006-10-23 at 16:11 +0200, Takashi Iwai wrote: > [Removed Paul Collins from Cc now] Thanks. > > Right, but prepare can sleep as well so it's easy to do. Though if the > > prepare doesn't actually change anything, couldn't we not stop the DMA > > and just continue? > > It's up to you. My point is the prepare callback is called anyway, > and if you want to resolve the DMA call conflict, prepare callback is > the right place. But, if trigger(START) checks whether the DMA is > already is running and just continues, then yes, you don't have to > wait in prepare. But is prepare also called between pause/resume? I was assuming it isn't. > > Now, with stop/play instead of pause/resume, does the picture change? > > There's a prepare between the trigger calls, and that could give us a > > whole new buffer, right? And the period size might even be different. > > Hence, we'll need to create a whole new set of DBDMA commands after > > waiting for the stop to complete, I guess. > > Yes, almost. The prepare callback won't assign any new buffers but > just reset the positions to zero in most cases. But, the app could > resize the buffer, so yes, it can happen after the following sequence: > stop -> hw_free -> hw_params -> prepare -> start Ah, good, so if we only sync in hw_free we should in theory be fine since that's the point where the buffers go away, and changes are only made after hw_params. > > Anyway, except for that I'd think that in the play/resume trigger, we > > can see if things are stopped and if it's still running we just clear > > the stop condition. If in prepare we wait for it to stop completely, > > that's fine since we'll have created a whole new dbdma command set. > > Sounds feasible. You can add a check whether you can reuse the > running DBDMA (i.e. period/buffer address and size are unchanged), for > example. > > But, still I think a DMA sync in prepare would be an easier solution > since the same check would be needed for hw_free anyway. > Another merit is that the trigger(START) callback does start the > stream at the very same moment it's issued. With the continous DBDMA, > the start of stream might be delayed than the triggered time. I agree, mostly mental exercise to make sure I understand things correctly. Technical details for us now... I guess what we'll do is * wait for dma to stop completely in hw_free and at the beginning of prepare * create a new set of commands in prepare as I do now (except they need to be different with S0 for the stop condition etc) * in the start/resume trigger, simply turn on the DMA engine or if it's still running clear the stop condition [1] * in the pause/stop trigger just set the stop condition * in the interrupt sync up internal state if we have done a stop and disable the DMA engine completely (clear RUN bit) That way, since prepare isn't called between pause/resume, we'll get perfect pause operation unlike now, and since prepare resets the dbdma command pointer it'll start at the beginning of the buffer when we enable the dma engine in the start/resume trigger. johannes ------------------------------------------------------------------------- Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: delayed dma trigger 2006-10-23 14:31 ` Johannes Berg @ 2006-10-24 15:07 ` Takashi Iwai 2006-10-24 15:13 ` Johannes Berg 0 siblings, 1 reply; 7+ messages in thread From: Takashi Iwai @ 2006-10-24 15:07 UTC (permalink / raw) To: Johannes Berg; +Cc: alsa-devel, Paul Mackerras, Benjamin Berg At Mon, 23 Oct 2006 16:31:07 +0200, Johannes Berg wrote: > > > > Right, but prepare can sleep as well so it's easy to do. Though if the > > > prepare doesn't actually change anything, couldn't we not stop the DMA > > > and just continue? > > > > It's up to you. My point is the prepare callback is called anyway, > > and if you want to resolve the DMA call conflict, prepare callback is > > the right place. But, if trigger(START) checks whether the DMA is > > already is running and just continues, then yes, you don't have to > > wait in prepare. > > But is prepare also called between pause/resume? I was assuming it > isn't. It won't be called unless PCM_INFO_PAUSE bit flag is set. It means that the driver doesn't support the hardware pause/resume function. The pseudo pause/resume is just like a stop -> reset -> start sequence. In other words, once when you set SNDRV_PCM_INFO_PAUSE flag, the driver has to stop the stream by trigger(PAUSE_PUSH) and restart the stream by trigger(PAUSE_RELEASE) call without prepare callback. Takashi ------------------------------------------------------------------------- Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: delayed dma trigger 2006-10-24 15:07 ` Takashi Iwai @ 2006-10-24 15:13 ` Johannes Berg 0 siblings, 0 replies; 7+ messages in thread From: Johannes Berg @ 2006-10-24 15:13 UTC (permalink / raw) To: Takashi Iwai; +Cc: alsa-devel, Paul Mackerras, Benjamin Berg On Tue, 2006-10-24 at 17:07 +0200, Takashi Iwai wrote: > It won't be called unless PCM_INFO_PAUSE bit flag is set. It means > that the driver doesn't support the hardware pause/resume function. > The pseudo pause/resume is just like a stop -> reset -> start > sequence. > > In other words, once when you set SNDRV_PCM_INFO_PAUSE flag, the > driver has to stop the stream by trigger(PAUSE_PUSH) and restart the > stream by trigger(PAUSE_RELEASE) call without prepare callback. Ok, then we can safely set that flag once we fix it as I outlined and if someone does pause-release very quickly we won't pause at all. should be fine. Who wants to do the patch? :) Many thanks, Johannes ------------------------------------------------------------------------- Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2006-10-24 15:12 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2006-10-23 8:49 delayed dma trigger Johannes Berg 2006-10-23 13:23 ` Takashi Iwai 2006-10-23 13:46 ` Johannes Berg 2006-10-23 14:11 ` Takashi Iwai 2006-10-23 14:31 ` Johannes Berg 2006-10-24 15:07 ` Takashi Iwai 2006-10-24 15:13 ` Johannes Berg
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.