On 12/04/2016 03:33 AM, Matt Ranostay wrote:
- Also setting of the QoS latency for the FIFO which varies upon the buffer
*/
- size. Approximately 2.3 milliseconds per FIFO location.
void omap_mcbsp_start(struct omap_mcbsp *mcbsp, int tx, int rx) { int enable_srg = 0;
int latency = mcbsp->pdata->buffer_size * 23;
I think this is not correct. The McBSP FIFO time depends on the sample rate and on the number of channels the audio is using. With 8KHz mono you have 12 times more time per FIFO element compared to 48KHz stereo.
As it has been discussed with Tony we should calculate the QoS latency in hw_params:
Ok yeah missed that part of the thread but it makes sense. Just one question should the latency value be only based on the TX FIFO threshold? I assume capture and transmit have two different settings.
Yes, I believe we should apply the lowest QoS when both direction is active. If the second stream needs lower QoS, we should switch to use that, if it would need longer, we should keep the QoS placed for the first stream.
latency_ms = ((FIFOsize - FIFOthreshold) / channels) * 1000/sampling-rate
On OMAP3.McBSP2 for example (44.1KHz, stereo): FIFO threshold 128
- DMA request will be triggered when 128 slots are free in the FIFO
- at that point we have still 1152 words in the FIFO.
- if the C wakeup latency is longer then what it takes to play out the
samples from the FIFO (13.06ms), we will drain the FIFO and got underflow.
- in this case the QOS should be set as 13.06ms
FIFO threshold 1024
- DMA request will be triggered when 1024 slots are free in the FIFO
- at that point we have still 256 words in the FIFO.
- if the C wakeup latency is longer then what it takes to play out the
samples from the FIFO (2.9ms), we will drain the FIFO and got underflow.
- in this case the QOS should be 2.9ms
On other McBSPs with 128 word FIFO the required latency is shorter to ensure we don't drain the FIFO.
u16 w;
/* Prevent omap hardware from hitting off between fifo fills */
if (latency)
pm_qos_add_request(&mcbsp->pm_qos_req,
PM_QOS_CPU_DMA_LATENCY, latency);
if (mcbsp->st_data) omap_st_start(mcbsp);
@@ -731,6 +741,8 @@ void omap_mcbsp_stop(struct omap_mcbsp *mcbsp, int tx, int rx)
if (mcbsp->st_data) omap_st_stop(mcbsp);
pm_qos_remove_request(&mcbsp->pm_qos_req);
}
int omap2_mcbsp_set_clks_src(struct omap_mcbsp *mcbsp, u8 fck_src_id) @@ -1098,6 +1110,9 @@ int omap_mcbsp_init(struct platform_device *pdev)
void omap_mcbsp_cleanup(struct omap_mcbsp *mcbsp) {
if (pm_qos_request_active(&mcbsp->pm_qos_req))
pm_qos_remove_request(&mcbsp->pm_qos_req);
if (mcbsp->pdata->buffer_size) sysfs_remove_group(&mcbsp->dev->kobj, &additional_attr_group);
diff --git a/sound/soc/omap/mcbsp.h b/sound/soc/omap/mcbsp.h index 61e93b1c185d..e603f33f4082 100644 --- a/sound/soc/omap/mcbsp.h +++ b/sound/soc/omap/mcbsp.h @@ -325,6 +325,8 @@ struct omap_mcbsp { unsigned int in_freq; int clk_div; int wlen;
struct pm_qos_request pm_qos_req;
};
void omap_mcbsp_config(struct omap_mcbsp *mcbsp,
-- Péter