On 2021/04/19 17:46 Lucas Stach <l.stach@xxxxxxxxxxxxxx> wrote: > Am Montag, dem 19.04.2021 um 07:17 +0000 schrieb Robin Gong: > > Hi Lucas, > > > > On 2021/04/14 Lucas Stach <l.stach@xxxxxxxxxxxxxx> wrote: > > > Hi Robin, > > > > > > Am Mittwoch, dem 14.04.2021 um 14:33 +0000 schrieb Robin Gong: > > > > On 2020/05/20 17:43 Lucas Stach <l.stach@xxxxxxxxxxxxxx> wrote: > > > > > Am Mittwoch, den 20.05.2020, 16:20 +0800 schrieb Shengjiu Wang: > > > > > > Hi > > > > > > > > > > > > On Tue, May 19, 2020 at 6:04 PM Lucas Stach > > > > > > <l.stach@xxxxxxxxxxxxxx> > > > > > wrote: > > > > > > > Am Dienstag, den 19.05.2020, 17:41 +0800 schrieb Shengjiu Wang: > > > > > > > > There are two requirements that we need to move the > > > > > > > > request of dma channel from probe to open. > > > > > > > > > > > > > > How do you handle -EPROBE_DEFER return code from the channel > > > > > > > request if you don't do it in probe? > > > > > > > > > > > > I use the dma_request_slave_channel or dma_request_channel > > > > > > instead of dmaengine_pcm_request_chan_of. so there should be > > > > > > not -EPROBE_DEFER return code. > > > > > > > > > > This is a pretty weak argument. The dmaengine device might probe > > > > > after you try to get the channel. Using a function to request > > > > > the channel that doesn't allow you to handle probe deferral is > > > > > IMHO a bug and should be fixed, instead of building even more > > > > > assumptions on top > > > of it. > > > > > > > > > > > > > - When dma device binds with power-domains, the power will > > > > > > > > be enabled when we request dma channel. If the request of > > > > > > > > dma channel happen on probe, then the power-domains will > > > > > > > > be always enabled after kernel boot up, which is not good > > > > > > > > for power saving, so we need to move the request of dma > > > > > > > > channel to .open(); > > > > > > > > > > > > > > This is certainly something which could be fixed in the > > > > > > > dmaengine driver. > > > > > > > > > > > > Dma driver always call the pm_runtime_get_sync in > > > > > > device_alloc_chan_resources, the device_alloc_chan_resources > > > > > > is called when channel is requested. so power is enabled on > > > > > > channel > > > request. > > > > > > > > > > So why can't you fix the dmaengine driver to do that RPM call at > > > > > a later time when the channel is actually going to be used? This > > > > > will allow further power savings with other slave devices than the audio > PCM. > > > > Hi Lucas, > > > > Thanks for your suggestion. I have tried to implement runtime > > > > autosuspend in fsl-edma driver on i.mx8qm/qxp with delay time (2 > > > > sec) for this feature as below (or you can refer to > > > > drivers/dma/qcom/hidma.c), and pm_runtime_get_sync/ > > > > pm_runtime_put_autosuspend in all dmaengine driver interface like > > > > device_alloc_chan_resources/device_prep_slave_sg/device_prep_dma_c > > > > ycli > > > > c/ > > > > device_tx_status... > > > > > > > > > > > > pm_runtime_use_autosuspend(fsl_chan->dev); > > > > pm_runtime_set_autosuspend_delay(fsl_chan-> > dev, > > > 2000); > > > > > > > > That could resolve this audio case since the autosuspend could > > > > suspend runtime after > > > > 2 seconds if there is no further dma transfer but only channel > > > request(device_alloc_chan_resources). > > > > But unfortunately, it cause another issue. As you know, on our > > > > i.mx8qm/qxp, power domain done by scfw > > > > (drivers/firmware/imx/scu-pd.c) > > > over mailbox: > > > > imx_sc_pd_power()->imx_scu_call_rpc()-> > > > > imx_scu_ipc_write()->mbox_send_message() > > > > which means have to 'waits for completion', meanwhile, some driver > > > > like tty will call dmaengine interfaces in non-atomic case as > > > > below, > > > > > > > > static int uart_write(struct tty_struct *tty, const unsigned char > > > > *buf, int count) { > > > > ....... > > > > port = uart_port_lock(state, flags); > > > > ...... > > > > __uart_start(tty); //call > start_tx()->dmaengine_prep_slave_sg... > > > > uart_port_unlock(port, flags); > > > > return ret; > > > > } > > > > > > > > Thus dma runtime resume may happen in that timing window and cause > > > kernel alarm. > > > > I'm not sure whether there are similar limitations on other driver > > > > subsystem. But for me, It looks like the only way to resolve the > > > > contradiction between tty and scu-pd (hardware limitation on > > > > i.mx8qm/qxp) is to give up autosuspend and keep > > > > pm_runtime_get_sync > > > only in device_alloc_chan_resources because request channel is a > > > safe non-atomic phase. > > > > Do you have any idea? Thanks in advance. > > > > > > If you look closely at the driver you used as an example (hidma.c) > > > it looks like there is already something in there, which looks very > > > much like what you need > > > here: > > > > > > In hidma_issue_pending() the driver tries to get the device to runtime > resume. > > > If this doesn't work, maybe due to the power domain code not being > > > able to be called in atomic context, the actual work of waking up > > > the dma hardware and issuing the descriptor is shunted to a tasklet. > > > > > > If I'm reading this right, this is exactly what you need here to be > > > able to call the dmaengine code from atomic context: try the rpm get > > > and issue immediately when possible, otherwise shunt the work to a > > > non- atomic context where you can deal with the requirements of scu-pd. > > Yes, I can schedule_work to worker to runtime resume edma channel by > calling scu-pd. > > But that means all dmaengine interfaces should be taken care, not only > > issue_pending() but also > > dmaengine_terminate_all()/dmaengine_pause()/dmaengine_resume()/ > > dmaengine_tx_status(). Not sure why hidma only take care > > issue_pending. Maybe their user case is just for memcpy/memset so that > > no further complicate case as ALSA or TTY. > > Besides, for autosuspend in cyclic, we have to add pm_runtime_get_sync > > into interrupt handler as qcom/bam_dma.c. but how could resolve the > > scu-pd's non-atmoic limitation in interrupt handler? > > Sure, this all needs some careful analysis on how those functions are called > and what to do about atomic callers, but it should be doable. I don't see any > fundamental issues here. > > I don't see why you would ever need to wake the hardware in an interrupt > handler. Surely the hardware is already awake, as it wouldn't signal an > interrupt otherwise. And for the issue with scu-pd you only care about the > state transition of suspended->running. If the hardware is already > running/awake, the runtime pm state handling is nothing more than bumping > a refcount, which is atomic safe. Putting the HW in suspend is already handled > asynchronously in a worker, so this is also atomic safe. But with autosuspend used, in corner case, may runtime suspended before falling Into edma interrupt handler if timeout happen with the delay value of pm_runtime_set_autosuspend_delay(). Thus, can't touch any edma interrupt status register unless runtime resume edma in interrupt handler while runtime resume function based on scu-pd's power domain may block or sleep. I have a simple workaround that disable runtime suspend in issue_pending worker by calling pm_runtime_forbid() and then enable runtime auto suspend in dmaengine_terminate_all so that we could easily regard that edma channel is always in runtime resume between issue_pending and channel terminated and ignore the above interrupt handler/scu-pd limitation.