fsl_ssi.c: Roberto's problem: ssi hangs after some number of samples
diff mbox

Message ID CAG5mAdz+RDM8r1o+Q5WHhQM134Lp7Dxn78+ixX1D_u7G=WqE8w@mail.gmail.com
State New
Headers show

Commit Message

Caleb Crome Nov. 5, 2015, 9:34 p.m. UTC
On Thu, Nov 5, 2015 at 3:48 AM, Roberto Fichera <kernel@tekno-soft.it> wrote:
> On 11/05/2015 12:30 PM, Fabio Estevam wrote:
>> On Thu, Nov 5, 2015 at 8:03 AM, Roberto Fichera <kernel@tekno-soft.it> wrote:
>>
>>> Following your suggestion, I've increased the buffer size to 2K and set the period to fifo_length - 2 (13),
>>> with that I'm now running substantially smooth except 3 EVTERR on RX DMA over 4 million of interrupts.
>>>
>>> Thanks Nicolin! I'm quite happy now!
>> That's good progress, Roberto.
>>
>> It would be nice if you and Caleb could post the patches to the mailing list.
>>

Yes, when I get something quite solid, I'd like to submit it all to
the list, and hope to get it into the kernel so nobody else has to go
through this pain again.

>
> Indeed! Now the TDM is stable, I've also found the reason of the EVTERRs, which was related to some stale
> code I've used to enable and disable both RDMAE and TDMAE bits to try to reset the transfers.
> Once removed that code everything is looks ok now.
>
> Regarding patches, well, from my side there isn't nothing special compared to the original fsl_ssi.c code.
> I'm basically running against a very skinny fsl_ssi.c version, I've just setup a bit larger DMA buffer, from
> 16bytes to 2K, and now reduced the DMA period to 8 because I'm mostly comfortable with that size to simplify
> sampling exchange against DAHDI subsystem within my DMA callbacks.
>
> In a few words, my problem was related due to a DMA buffer too small.
>
> What eventually might be interesting to have is the INTRMASK and EVTERR DMA setting to trigger DMA
> related errors, but I guess this need to be discussed elsewhere.

I have implemented roberto's patch on the 4.2 kernel, and I get a huge
number of EVTERR interrupts.  Something like 7200/second at 16kHz
sample rate.  But strangely, the audio seems to be correct.

My patch is slightly different in that it just enables EVTERR for all
channels, not just for the SSI.  Might as well see if there are any
other problems.

And it puts the stats file at
/sys/kernel/debug/20ec000.sdma/stats

When I aplay a file for 10 seconds I get ~366 EVTERR interrupts.
When I arecord for 10 seconds, I get 1 EVTERR interrupt
When I run my application for 10 seconds, which does full duplex, I
get 72703 EVTERR interrupts, but the data integrity checks out okay.

Interstingly, when I enable dual fifo, it goes from about 7200
EVTERR's/sec to about 18 EVTERRs/sec.  Much better, but still a long
way from working perfectly.

When I get a 'hang' from my application (no more portaudio callbacks),
I'm actually getting repeated calls to sdma_prep_dma_cyclic, though I
don't know how that call gets triggered.  But once that starts
happening, no more audio data gets through.

Here is my version of Roberto's patch for reporting the EVTERR on a
4.2 kernel.  It includes Dual fifo.

The
/sys/kernel/debug/20ec000.sdma/stats
file is cleared by reading, so it's easy to check how many EVTERRs
since the last read of the file.


Thanks again for looking at this.

-Caleb

---------- Forwarded message ----------
From: Caleb Crome <caleb@crome.org>
Date: Thu, Nov 5, 2015 at 1:16 PM
Subject: [PATCH] DMA: imx-sdma: add reporting of EVTERR DMA errors to fsl dma.
To: ccrome@gmail.com
Cc: Caleb Crome <caleb@crome.org>


Add roberto's patch to the 4.x kernel for report EVTERR DMA errors in
SSI transfers.  From userspace, you can see errors in the

/sys/kernel/debug/20ec000.sdma/stats

file.
---
 drivers/dma/imx-sdma.c | 113 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 113 insertions(+)


 /*
@@ -726,11 +745,25 @@ static irqreturn_t sdma_int_handler(int irq, void *dev_id)
        struct sdma_engine *sdma = dev_id;
        unsigned long stat;

+       long unsigned int evterr;
+
+        /* read the EVTERR register */
+        evterr = readl_relaxed(sdma->regs + SDMA_H_EVTERR);
+        if ( evterr )
+        {
+           int bitnr;
+           for_each_set_bit(bitnr, &evterr, sizeof(u32) * BITS_PER_BYTE)
+                  sdma->evterrchannel[bitnr]++;
+       }
+
        stat = readl_relaxed(sdma->regs + SDMA_H_INTR);
        /* not interested in channel 0 interrupts */
        stat &= ~1;
        writel_relaxed(stat, sdma->regs + SDMA_H_INTR);

+        /* we are interested only to channels not in error status */
+        stat &= ~evterr;
+
        while (stat) {
                int channel = fls(stat) - 1;
                struct sdma_channel *sdmac = &sdma->channel[channel];
@@ -904,10 +937,17 @@ static int sdma_disable_channel(struct dma_chan *chan)
        struct sdma_channel *sdmac = to_sdma_chan(chan);
        struct sdma_engine *sdma = sdmac->sdma;
        int channel = sdmac->channel;
+       u32 msk;

        writel_relaxed(BIT(channel), sdma->regs + SDMA_H_STATSTOP);
        sdmac->status = DMA_ERROR;

+       if ((sdmac->peripheral_type == IMX_DMATYPE_SSI_SP) ||
+           (sdmac->peripheral_type == IMX_DMATYPE_SSI_DUAL)) {
+               msk = readl(sdma->regs + SDMA_H_INTRMSK);
+               writel(msk & ~(BIT(channel)), sdma->regs + SDMA_H_INTRMSK);
+       }
+
        return 0;
 }

@@ -1166,6 +1206,8 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg(

        dev_dbg(sdma->dev, "setting up %d entries for channel %d.\n",
                        sg_len, channel);
+       printk(KERN_INFO "setting up %d entries for channel %d.\n",
+                       sg_len, channel);

        sdmac->direction = direction;
        ret = sdma_load_context(sdmac);
@@ -1259,6 +1301,8 @@ static struct dma_async_tx_descriptor
*sdma_prep_dma_cyclic(

        dev_dbg(sdma->dev, "%s channel: %d\n", __func__, channel);

+       printk(KERN_INFO "%s channel: %d, periods = %d\n", __func__,
channel, num_periods);
+       printk(KERN_INFO "buf_len = %d, period_len = %d\n", buf_len,
period_len);
        if (sdmac->status == DMA_IN_PROGRESS)
                return NULL;

@@ -1650,6 +1694,71 @@ static struct dma_chan *sdma_xlate(struct
of_phandle_args *dma_spec,
        return dma_request_channel(mask, sdma_filter_fn, &data);
 }

+#define SDMA_SHOW_REG(reg) \
+    do { \
+                u32 _val = readl(sdma->regs + reg); \
+        seq_printf(s, "\t" #reg "=0x%08x\n", _val); \
+    } while (0)
+
+static int sdma_show_chan_status(struct seq_file *s, void *unused)
+{
+       struct sdma_engine *sdma = s->private;
+       // struct dma_chan *chan = (struct dma_chan *)priv;
+       //struct sdma_channel *sdmac = to_sdma_chan(chan);
+       //struct sdma_engine *sdma = sdmac->sdma;
+        int i;
+
+        //seq_printf(s, "SDMA channel %d status\n", sdmac->channel);
+        SDMA_SHOW_REG(SDMA_H_STATSTOP);
+        SDMA_SHOW_REG(SDMA_H_START);
+        SDMA_SHOW_REG(SDMA_H_EVTOVR);
+        SDMA_SHOW_REG(SDMA_H_EVTPEND);
+        SDMA_SHOW_REG(SDMA_H_EVTERR);
+        SDMA_SHOW_REG(SDMA_H_DSPOVR);
+        SDMA_SHOW_REG(SDMA_H_HOSTOVR);
+        SDMA_SHOW_REG(SDMA_H_INTR);
+        SDMA_SHOW_REG(SDMA_H_INTRMSK);
+        SDMA_SHOW_REG(SDMACORE_EVENTS);
+        SDMA_SHOW_REG(SDMACORE_EVENTS2);
+
+        seq_printf(s, "\nSDMA EVTERR channel counters:\n");
+        for(i=0; i < MAX_DMA_CHANNELS; i++)
+               if (sdma->evterrchannel[i])  {
+                       seq_printf(s, "\t%03d = %u\n", i,
sdma->evterrchannel[i]);
+                       sdma->evterrchannel[i] = 0;
+               }
+
+       return 0;
+}
+
+static int fsl_sdma_stats_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, sdma_show_chan_status, inode->i_private);
+}
+
+static const struct file_operations fsl_sdma_stats_ops = {
+       .open = fsl_sdma_stats_open,
+       .read = seq_read,
+       .llseek = seq_lseek,
+       .release = single_release,
+};
+
+int fsl_sdma_debugfs_create(struct sdma_engine *sdma, struct device *dev)
+{
+       sdma->dbg_dir = debugfs_create_dir(dev_name(dev), NULL);
+       if (!sdma->dbg_dir)
+               return -ENOMEM;
+
+       sdma->dbg_stats = debugfs_create_file("stats", S_IRUGO,
+                       sdma->dbg_dir, sdma, &fsl_sdma_stats_ops);
+       if (!sdma->dbg_stats) {
+               debugfs_remove(sdma->dbg_dir);
+               return -ENOMEM;
+       }
+       return 0;
+}
+
+
 static int sdma_probe(struct platform_device *pdev)
 {
        const struct of_device_id *of_id =
@@ -1785,6 +1894,10 @@ static int sdma_probe(struct platform_device *pdev)
                }
        }

+       ret = fsl_sdma_debugfs_create(sdma, &pdev->dev);
+       if (ret)
+               goto err_init;
+
        sdma->dma_device.dev = &pdev->dev;

        sdma->dma_device.device_alloc_chan_resources =
sdma_alloc_chan_resources;
--
2.1.4

Comments

Roberto Fichera Nov. 5, 2015, 10:08 p.m. UTC | #1
On 11/05/2015 10:34 PM, Caleb Crome wrote:
> On Thu, Nov 5, 2015 at 3:48 AM, Roberto Fichera <kernel@tekno-soft.it> wrote:
>> On 11/05/2015 12:30 PM, Fabio Estevam wrote:
>>> On Thu, Nov 5, 2015 at 8:03 AM, Roberto Fichera <kernel@tekno-soft.it> wrote:
>>>
>>>> Following your suggestion, I've increased the buffer size to 2K and set the period to fifo_length - 2 (13),
>>>> with that I'm now running substantially smooth except 3 EVTERR on RX DMA over 4 million of interrupts.
>>>>
>>>> Thanks Nicolin! I'm quite happy now!
>>> That's good progress, Roberto.
>>>
>>> It would be nice if you and Caleb could post the patches to the mailing list.
>>>
> Yes, when I get something quite solid, I'd like to submit it all to
> the list, and hope to get it into the kernel so nobody else has to go
> through this pain again.
>
>> Indeed! Now the TDM is stable, I've also found the reason of the EVTERRs, which was related to some stale
>> code I've used to enable and disable both RDMAE and TDMAE bits to try to reset the transfers.
>> Once removed that code everything is looks ok now.
>>
>> Regarding patches, well, from my side there isn't nothing special compared to the original fsl_ssi.c code.
>> I'm basically running against a very skinny fsl_ssi.c version, I've just setup a bit larger DMA buffer, from
>> 16bytes to 2K, and now reduced the DMA period to 8 because I'm mostly comfortable with that size to simplify
>> sampling exchange against DAHDI subsystem within my DMA callbacks.
>>
>> In a few words, my problem was related due to a DMA buffer too small.
>>
>> What eventually might be interesting to have is the INTRMASK and EVTERR DMA setting to trigger DMA
>> related errors, but I guess this need to be discussed elsewhere.
> I have implemented roberto's patch on the 4.2 kernel, and I get a huge
> number of EVTERR interrupts.  Something like 7200/second at 16kHz
> sample rate.  But strangely, the audio seems to be correct.

I've notice that clearing the EVTERR bit seems restarting the given SDMA.

> My patch is slightly different in that it just enables EVTERR for all
> channels, not just for the SSI.  Might as well see if there are any
> other problems.

Oh yes! This will overload the SDMA isr. How bigger is your audio buffer?
In your case I guess you will need something like 16KHz * 16 channels *
2 bytes (16bits) = 512K minimum.
I would try to start from 1MB or maybe more.

>
> And it puts the stats file at
> /sys/kernel/debug/20ec000.sdma/stats
>
> When I aplay a file for 10 seconds I get ~366 EVTERR interrupts.
> When I arecord for 10 seconds, I get 1 EVTERR interrupt
> When I run my application for 10 seconds, which does full duplex, I
> get 72703 EVTERR interrupts, but the data integrity checks out okay.
>
> Interstingly, when I enable dual fifo, it goes from about 7200
> EVTERR's/sec to about 18 EVTERRs/sec.  Much better, but still a long
> way from working perfectly.
>

Cyclic DMA is particular scatter-gater DMA list dedicated for repetitive
tasks looping over the same buffer, so audio.
The associated callback is triggered every period (fifo_depth-2) but the
job will last only when the buffer is
filled in the request length. All this "tasks" will be managed by SDMA
ISR. You can follow the SG_LOOP flag if you
want understand more.

> When I get a 'hang' from my application (no more portaudio callbacks),
> I'm actually getting repeated calls to sdma_prep_dma_cyclic, though I
> don't know how that call gets triggered.  But once that starts
> happening, no more audio data gets through.

If I remember correctly portaudio has a thread that controls your
callback that receive/play all samples, but I don't remember if the
callback is responsible to stop recording or playing in case of error.
I've to check this in my last app.
Caleb Crome Nov. 5, 2015, 10:25 p.m. UTC | #2
On Thu, Nov 5, 2015 at 2:08 PM, Roberto Fichera <kernel@tekno-soft.it> wrote:
> On 11/05/2015 10:34 PM, Caleb Crome wrote:
>> On Thu, Nov 5, 2015 at 3:48 AM, Roberto Fichera <kernel@tekno-soft.it> wrote:
>>> On 11/05/2015 12:30 PM, Fabio Estevam wrote:
>>>> On Thu, Nov 5, 2015 at 8:03 AM, Roberto Fichera <kernel@tekno-soft.it> wrote:
>>>>
>>>>> Following your suggestion, I've increased the buffer size to 2K and set the period to fifo_length - 2 (13),
>>>>> with that I'm now running substantially smooth except 3 EVTERR on RX DMA over 4 million of interrupts.
>>>>>
>>>>> Thanks Nicolin! I'm quite happy now!
>>>> That's good progress, Roberto.
>>>>
>>>> It would be nice if you and Caleb could post the patches to the mailing list.
>>>>
>> Yes, when I get something quite solid, I'd like to submit it all to
>> the list, and hope to get it into the kernel so nobody else has to go
>> through this pain again.
>>
>>> Indeed! Now the TDM is stable, I've also found the reason of the EVTERRs, which was related to some stale
>>> code I've used to enable and disable both RDMAE and TDMAE bits to try to reset the transfers.
>>> Once removed that code everything is looks ok now.
>>>
>>> Regarding patches, well, from my side there isn't nothing special compared to the original fsl_ssi.c code.
>>> I'm basically running against a very skinny fsl_ssi.c version, I've just setup a bit larger DMA buffer, from
>>> 16bytes to 2K, and now reduced the DMA period to 8 because I'm mostly comfortable with that size to simplify
>>> sampling exchange against DAHDI subsystem within my DMA callbacks.
>>>
>>> In a few words, my problem was related due to a DMA buffer too small.
>>>
>>> What eventually might be interesting to have is the INTRMASK and EVTERR DMA setting to trigger DMA
>>> related errors, but I guess this need to be discussed elsewhere.
>> I have implemented roberto's patch on the 4.2 kernel, and I get a huge
>> number of EVTERR interrupts.  Something like 7200/second at 16kHz
>> sample rate.  But strangely, the audio seems to be correct.
>
> I've notice that clearing the EVTERR bit seems restarting the given SDMA.
>
>> My patch is slightly different in that it just enables EVTERR for all
>> channels, not just for the SSI.  Might as well see if there are any
>> other problems.
>
> Oh yes! This will overload the SDMA isr.

It didn't seem to.  There didn't seem to be any other DMA happening in
my system, definitely none that made the EVTRR trigger.  However, I
changed it back to the way you had it.  No differences, still got a
TON of EVTERRs.

> How bigger is your audio buffer?
> In your case I guess you will need something like 16KHz * 16 channels *
> 2 bytes (16bits) = 512K minimum.
> I would try to start from 1MB or maybe more.

That's 2 seconds of audio!  We definitely need less buffering than
that.    We pretty much need a latency of 100ms, worst case, or 1600
frames, or 51,200 bytes.

I did change the max buffer size to 1MB though, but I'm not sure how
much is actually being used.

>
>>
>> And it puts the stats file at
>> /sys/kernel/debug/20ec000.sdma/stats
>>
>> When I aplay a file for 10 seconds I get ~366 EVTERR interrupts.
>> When I arecord for 10 seconds, I get 1 EVTERR interrupt
>> When I run my application for 10 seconds, which does full duplex, I
>> get 72703 EVTERR interrupts, but the data integrity checks out okay.
>>
>> Interstingly, when I enable dual fifo, it goes from about 7200
>> EVTERR's/sec to about 18 EVTERRs/sec.  Much better, but still a long
>> way from working perfectly.
>>
>
> Cyclic DMA is particular scatter-gater DMA list dedicated for repetitive
> tasks looping over the same buffer, so audio.
> The associated callback is triggered every period (fifo_depth-2) but the
> job will last only when the buffer is
> filled in the request length. All this "tasks" will be managed by SDMA
> ISR. You can follow the SG_LOOP flag if you
> want understand more.

I don't want to understand more.  I just want it to work  :-)



>
>> When I get a 'hang' from my application (no more portaudio callbacks),
>> I'm actually getting repeated calls to sdma_prep_dma_cyclic, though I
>> don't know how that call gets triggered.  But once that starts
>> happening, no more audio data gets through.
>
> If I remember correctly portaudio has a thread that controls your
> callback that receive/play all samples, but I don't remember if the
> callback is responsible to stop recording or playing in case of error.
> I've to check this in my last app.
>

Yeah, it does normally restart by itself.
Roberto Fichera Nov. 5, 2015, 10:40 p.m. UTC | #3
On 11/05/2015 11:25 PM, Caleb Crome wrote:
> On Thu, Nov 5, 2015 at 2:08 PM, Roberto Fichera <kernel@tekno-soft.it> wrote:
>> On 11/05/2015 10:34 PM, Caleb Crome wrote:
>>> On Thu, Nov 5, 2015 at 3:48 AM, Roberto Fichera <kernel@tekno-soft.it> wrote:
>>>> On 11/05/2015 12:30 PM, Fabio Estevam wrote:
>>>>> On Thu, Nov 5, 2015 at 8:03 AM, Roberto Fichera <kernel@tekno-soft.it> wrote:
>>>>>
>>>>>> Following your suggestion, I've increased the buffer size to 2K and set the period to fifo_length - 2 (13),
>>>>>> with that I'm now running substantially smooth except 3 EVTERR on RX DMA over 4 million of interrupts.
>>>>>>
>>>>>> Thanks Nicolin! I'm quite happy now!
>>>>> That's good progress, Roberto.
>>>>>
>>>>> It would be nice if you and Caleb could post the patches to the mailing list.
>>>>>
>>> Yes, when I get something quite solid, I'd like to submit it all to
>>> the list, and hope to get it into the kernel so nobody else has to go
>>> through this pain again.
>>>
>>>> Indeed! Now the TDM is stable, I've also found the reason of the EVTERRs, which was related to some stale
>>>> code I've used to enable and disable both RDMAE and TDMAE bits to try to reset the transfers.
>>>> Once removed that code everything is looks ok now.
>>>>
>>>> Regarding patches, well, from my side there isn't nothing special compared to the original fsl_ssi.c code.
>>>> I'm basically running against a very skinny fsl_ssi.c version, I've just setup a bit larger DMA buffer, from
>>>> 16bytes to 2K, and now reduced the DMA period to 8 because I'm mostly comfortable with that size to simplify
>>>> sampling exchange against DAHDI subsystem within my DMA callbacks.
>>>>
>>>> In a few words, my problem was related due to a DMA buffer too small.
>>>>
>>>> What eventually might be interesting to have is the INTRMASK and EVTERR DMA setting to trigger DMA
>>>> related errors, but I guess this need to be discussed elsewhere.
>>> I have implemented roberto's patch on the 4.2 kernel, and I get a huge
>>> number of EVTERR interrupts.  Something like 7200/second at 16kHz
>>> sample rate.  But strangely, the audio seems to be correct.
>> I've notice that clearing the EVTERR bit seems restarting the given SDMA.
>>
>>> My patch is slightly different in that it just enables EVTERR for all
>>> channels, not just for the SSI.  Might as well see if there are any
>>> other problems.
>> Oh yes! This will overload the SDMA isr.
> It didn't seem to.  There didn't seem to be any other DMA happening in
> my system, definitely none that made the EVTRR trigger.  However, I
> changed it back to the way you had it.  No differences, still got a
> TON of EVTERRs.

This might be related to SDMA request when another is pending.

>
>> How bigger is your audio buffer?
>> In your case I guess you will need something like 16KHz * 16 channels *
>> 2 bytes (16bits) = 512K minimum.
>> I would try to start from 1MB or maybe more.
> That's 2 seconds of audio!  We definitely need less buffering than
> that.    We pretty much need a latency of 100ms, worst case, or 1600
> frames, or 51,200 bytes.

I haven't checked in detail how the DAI buffering is working, but likely
the samples are passed not in buffer size chunks but instead with less
granularity. Having a large buffer gives more chance to the SSI to not
overlap DMA requests, hence no more EVTERRs.

I would give it a try.
>
> I did change the max buffer size to 1MB though, but I'm not sure how
> much is actually being used.

I guess it's 64K, look for IMX_SSI_DMABUF_SIZE.
Caleb Crome Nov. 5, 2015, 10:49 p.m. UTC | #4
On Thu, Nov 5, 2015 at 2:40 PM, Roberto Fichera <kernel@tekno-soft.it> wrote:
> On 11/05/2015 11:25 PM, Caleb Crome wrote:
>> On Thu, Nov 5, 2015 at 2:08 PM, Roberto Fichera <kernel@tekno-soft.it> wrote:
>>> On 11/05/2015 10:34 PM, Caleb Crome wrote:
>>>> On Thu, Nov 5, 2015 at 3:48 AM, Roberto Fichera <kernel@tekno-soft.it> wrote:
>>>>> On 11/05/2015 12:30 PM, Fabio Estevam wrote:
>>>>>> On Thu, Nov 5, 2015 at 8:03 AM, Roberto Fichera <kernel@tekno-soft.it> wrote:
>>>>>>
>>>>>>> Following your suggestion, I've increased the buffer size to 2K and set the period to fifo_length - 2 (13),
>>>>>>> with that I'm now running substantially smooth except 3 EVTERR on RX DMA over 4 million of interrupts.
>>>>>>>
>>>>>>> Thanks Nicolin! I'm quite happy now!
>>>>>> That's good progress, Roberto.
>>>>>>
>>>>>> It would be nice if you and Caleb could post the patches to the mailing list.
>>>>>>
>>>> Yes, when I get something quite solid, I'd like to submit it all to
>>>> the list, and hope to get it into the kernel so nobody else has to go
>>>> through this pain again.
>>>>
>>>>> Indeed! Now the TDM is stable, I've also found the reason of the EVTERRs, which was related to some stale
>>>>> code I've used to enable and disable both RDMAE and TDMAE bits to try to reset the transfers.
>>>>> Once removed that code everything is looks ok now.
>>>>>
>>>>> Regarding patches, well, from my side there isn't nothing special compared to the original fsl_ssi.c code.
>>>>> I'm basically running against a very skinny fsl_ssi.c version, I've just setup a bit larger DMA buffer, from
>>>>> 16bytes to 2K, and now reduced the DMA period to 8 because I'm mostly comfortable with that size to simplify
>>>>> sampling exchange against DAHDI subsystem within my DMA callbacks.
>>>>>
>>>>> In a few words, my problem was related due to a DMA buffer too small.
>>>>>
>>>>> What eventually might be interesting to have is the INTRMASK and EVTERR DMA setting to trigger DMA
>>>>> related errors, but I guess this need to be discussed elsewhere.
>>>> I have implemented roberto's patch on the 4.2 kernel, and I get a huge
>>>> number of EVTERR interrupts.  Something like 7200/second at 16kHz
>>>> sample rate.  But strangely, the audio seems to be correct.
>>> I've notice that clearing the EVTERR bit seems restarting the given SDMA.
>>>
>>>> My patch is slightly different in that it just enables EVTERR for all
>>>> channels, not just for the SSI.  Might as well see if there are any
>>>> other problems.
>>> Oh yes! This will overload the SDMA isr.
>> It didn't seem to.  There didn't seem to be any other DMA happening in
>> my system, definitely none that made the EVTRR trigger.  However, I
>> changed it back to the way you had it.  No differences, still got a
>> TON of EVTERRs.
>
> This might be related to SDMA request when another is pending.
>
>>
>>> How bigger is your audio buffer?
>>> In your case I guess you will need something like 16KHz * 16 channels *
>>> 2 bytes (16bits) = 512K minimum.
>>> I would try to start from 1MB or maybe more.
>> That's 2 seconds of audio!  We definitely need less buffering than
>> that.    We pretty much need a latency of 100ms, worst case, or 1600
>> frames, or 51,200 bytes.
>
> I haven't checked in detail how the DAI buffering is working, but likely
> the samples are passed not in buffer size chunks but instead with less
> granularity. Having a large buffer gives more chance to the SSI to not
> overlap DMA requests, hence no more EVTERRs.
>
> I would give it a try.
>>
>> I did change the max buffer size to 1MB though, but I'm not sure how
>> much is actually being used.
>
> I guess it's 64K, look for IMX_SSI_DMABUF_SIZE.
>
>
Exactly, I changed that to 1024*1024, but still I don't get zero
EVTERRs, even when I set my periods long and number of periods high.
Roberto Fichera Nov. 5, 2015, 11:01 p.m. UTC | #5
On 11/05/2015 11:49 PM, Caleb Crome wrote:
> On Thu, Nov 5, 2015 at 2:40 PM, Roberto Fichera <kernel@tekno-soft.it> wrote:
>> On 11/05/2015 11:25 PM, Caleb Crome wrote:
>>> On Thu, Nov 5, 2015 at 2:08 PM, Roberto Fichera <kernel@tekno-soft.it> wrote:
>>>> On 11/05/2015 10:34 PM, Caleb Crome wrote:
>>>>> On Thu, Nov 5, 2015 at 3:48 AM, Roberto Fichera <kernel@tekno-soft.it> wrote:
>>>>>> On 11/05/2015 12:30 PM, Fabio Estevam wrote:
>>>>>>> On Thu, Nov 5, 2015 at 8:03 AM, Roberto Fichera <kernel@tekno-soft.it> wrote:
>>>>>>>
>>>>>>>> Following your suggestion, I've increased the buffer size to 2K and set the period to fifo_length - 2 (13),
>>>>>>>> with that I'm now running substantially smooth except 3 EVTERR on RX DMA over 4 million of interrupts.
>>>>>>>>
>>>>>>>> Thanks Nicolin! I'm quite happy now!
>>>>>>> That's good progress, Roberto.
>>>>>>>
>>>>>>> It would be nice if you and Caleb could post the patches to the mailing list.
>>>>>>>
>>>>> Yes, when I get something quite solid, I'd like to submit it all to
>>>>> the list, and hope to get it into the kernel so nobody else has to go
>>>>> through this pain again.
>>>>>
>>>>>> Indeed! Now the TDM is stable, I've also found the reason of the EVTERRs, which was related to some stale
>>>>>> code I've used to enable and disable both RDMAE and TDMAE bits to try to reset the transfers.
>>>>>> Once removed that code everything is looks ok now.
>>>>>>
>>>>>> Regarding patches, well, from my side there isn't nothing special compared to the original fsl_ssi.c code.
>>>>>> I'm basically running against a very skinny fsl_ssi.c version, I've just setup a bit larger DMA buffer, from
>>>>>> 16bytes to 2K, and now reduced the DMA period to 8 because I'm mostly comfortable with that size to simplify
>>>>>> sampling exchange against DAHDI subsystem within my DMA callbacks.
>>>>>>
>>>>>> In a few words, my problem was related due to a DMA buffer too small.
>>>>>>
>>>>>> What eventually might be interesting to have is the INTRMASK and EVTERR DMA setting to trigger DMA
>>>>>> related errors, but I guess this need to be discussed elsewhere.
>>>>> I have implemented roberto's patch on the 4.2 kernel, and I get a huge
>>>>> number of EVTERR interrupts.  Something like 7200/second at 16kHz
>>>>> sample rate.  But strangely, the audio seems to be correct.
>>>> I've notice that clearing the EVTERR bit seems restarting the given SDMA.
>>>>
>>>>> My patch is slightly different in that it just enables EVTERR for all
>>>>> channels, not just for the SSI.  Might as well see if there are any
>>>>> other problems.
>>>> Oh yes! This will overload the SDMA isr.
>>> It didn't seem to.  There didn't seem to be any other DMA happening in
>>> my system, definitely none that made the EVTRR trigger.  However, I
>>> changed it back to the way you had it.  No differences, still got a
>>> TON of EVTERRs.
>> This might be related to SDMA request when another is pending.
>>
>>>> How bigger is your audio buffer?
>>>> In your case I guess you will need something like 16KHz * 16 channels *
>>>> 2 bytes (16bits) = 512K minimum.
>>>> I would try to start from 1MB or maybe more.
>>> That's 2 seconds of audio!  We definitely need less buffering than
>>> that.    We pretty much need a latency of 100ms, worst case, or 1600
>>> frames, or 51,200 bytes.
>> I haven't checked in detail how the DAI buffering is working, but likely
>> the samples are passed not in buffer size chunks but instead with less
>> granularity. Having a large buffer gives more chance to the SSI to not
>> overlap DMA requests, hence no more EVTERRs.
>>
>> I would give it a try.
>>> I did change the max buffer size to 1MB though, but I'm not sure how
>>> much is actually being used.
>> I guess it's 64K, look for IMX_SSI_DMABUF_SIZE.
>>
>>
> Exactly, I changed that to 1024*1024, but still I don't get zero
> EVTERRs, even when I set my periods long and number of periods high.

They decreased?
Caleb Crome Nov. 5, 2015, 11:21 p.m. UTC | #6
On Thu, Nov 5, 2015 at 3:01 PM, Roberto Fichera <kernel@tekno-soft.it> wrote:
>
>
> On 11/05/2015 11:49 PM, Caleb Crome wrote:
>> On Thu, Nov 5, 2015 at 2:40 PM, Roberto Fichera <kernel@tekno-soft.it> wrote:
>>> On 11/05/2015 11:25 PM, Caleb Crome wrote:
>>>> On Thu, Nov 5, 2015 at 2:08 PM, Roberto Fichera <kernel@tekno-soft.it> wrote:
>>>>> On 11/05/2015 10:34 PM, Caleb Crome wrote:
>>>>>> On Thu, Nov 5, 2015 at 3:48 AM, Roberto Fichera <kernel@tekno-soft.it> wrote:
>>>>>>> On 11/05/2015 12:30 PM, Fabio Estevam wrote:
>>>>>>>> On Thu, Nov 5, 2015 at 8:03 AM, Roberto Fichera <kernel@tekno-soft.it> wrote:
>>>>>>>>
>>>>>>>>> Following your suggestion, I've increased the buffer size to 2K and set the period to fifo_length - 2 (13),
>>>>>>>>> with that I'm now running substantially smooth except 3 EVTERR on RX DMA over 4 million of interrupts.
>>>>>>>>>
>>>>>>>>> Thanks Nicolin! I'm quite happy now!
>>>>>>>> That's good progress, Roberto.
>>>>>>>>
>>>>>>>> It would be nice if you and Caleb could post the patches to the mailing list.
>>>>>>>>
>>>>>> Yes, when I get something quite solid, I'd like to submit it all to
>>>>>> the list, and hope to get it into the kernel so nobody else has to go
>>>>>> through this pain again.
>>>>>>
>>>>>>> Indeed! Now the TDM is stable, I've also found the reason of the EVTERRs, which was related to some stale
>>>>>>> code I've used to enable and disable both RDMAE and TDMAE bits to try to reset the transfers.
>>>>>>> Once removed that code everything is looks ok now.
>>>>>>>
>>>>>>> Regarding patches, well, from my side there isn't nothing special compared to the original fsl_ssi.c code.
>>>>>>> I'm basically running against a very skinny fsl_ssi.c version, I've just setup a bit larger DMA buffer, from
>>>>>>> 16bytes to 2K, and now reduced the DMA period to 8 because I'm mostly comfortable with that size to simplify
>>>>>>> sampling exchange against DAHDI subsystem within my DMA callbacks.
>>>>>>>
>>>>>>> In a few words, my problem was related due to a DMA buffer too small.
>>>>>>>
>>>>>>> What eventually might be interesting to have is the INTRMASK and EVTERR DMA setting to trigger DMA
>>>>>>> related errors, but I guess this need to be discussed elsewhere.
>>>>>> I have implemented roberto's patch on the 4.2 kernel, and I get a huge
>>>>>> number of EVTERR interrupts.  Something like 7200/second at 16kHz
>>>>>> sample rate.  But strangely, the audio seems to be correct.
>>>>> I've notice that clearing the EVTERR bit seems restarting the given SDMA.
>>>>>
>>>>>> My patch is slightly different in that it just enables EVTERR for all
>>>>>> channels, not just for the SSI.  Might as well see if there are any
>>>>>> other problems.
>>>>> Oh yes! This will overload the SDMA isr.
>>>> It didn't seem to.  There didn't seem to be any other DMA happening in
>>>> my system, definitely none that made the EVTRR trigger.  However, I
>>>> changed it back to the way you had it.  No differences, still got a
>>>> TON of EVTERRs.
>>> This might be related to SDMA request when another is pending.
>>>
>>>>> How bigger is your audio buffer?
>>>>> In your case I guess you will need something like 16KHz * 16 channels *
>>>>> 2 bytes (16bits) = 512K minimum.
>>>>> I would try to start from 1MB or maybe more.
>>>> That's 2 seconds of audio!  We definitely need less buffering than
>>>> that.    We pretty much need a latency of 100ms, worst case, or 1600
>>>> frames, or 51,200 bytes.
>>> I haven't checked in detail how the DAI buffering is working, but likely
>>> the samples are passed not in buffer size chunks but instead with less
>>> granularity. Having a large buffer gives more chance to the SSI to not
>>> overlap DMA requests, hence no more EVTERRs.
>>>
>>> I would give it a try.
>>>> I did change the max buffer size to 1MB though, but I'm not sure how
>>>> much is actually being used.
>>> I guess it's 64K, look for IMX_SSI_DMABUF_SIZE.
>>>
>>>
>> Exactly, I changed that to 1024*1024, but still I don't get zero
>> EVTERRs, even when I set my periods long and number of periods high.
>
> They decreased?
>

the big win was going to dual fifo, but they're still there at
something like 17/second.

-Caleb
Roberto Fichera Nov. 5, 2015, 11:28 p.m. UTC | #7
On 11/06/2015 12:21 AM, Caleb Crome wrote:
> On Thu, Nov 5, 2015 at 3:01 PM, Roberto Fichera <kernel@tekno-soft.it> wrote:
>>
>> On 11/05/2015 11:49 PM, Caleb Crome wrote:
>>> On Thu, Nov 5, 2015 at 2:40 PM, Roberto Fichera <kernel@tekno-soft.it> wrote:
>>>> On 11/05/2015 11:25 PM, Caleb Crome wrote:
>>>>> On Thu, Nov 5, 2015 at 2:08 PM, Roberto Fichera <kernel@tekno-soft.it> wrote:
>>>>>> On 11/05/2015 10:34 PM, Caleb Crome wrote:
>>>>>>> On Thu, Nov 5, 2015 at 3:48 AM, Roberto Fichera <kernel@tekno-soft.it> wrote:
>>>>>>>> On 11/05/2015 12:30 PM, Fabio Estevam wrote:
>>>>>>>>> On Thu, Nov 5, 2015 at 8:03 AM, Roberto Fichera <kernel@tekno-soft.it> wrote:
>>>>>>>>>
>>>>>>>>>> Following your suggestion, I've increased the buffer size to 2K and set the period to fifo_length - 2 (13),
>>>>>>>>>> with that I'm now running substantially smooth except 3 EVTERR on RX DMA over 4 million of interrupts.
>>>>>>>>>>
>>>>>>>>>> Thanks Nicolin! I'm quite happy now!
>>>>>>>>> That's good progress, Roberto.
>>>>>>>>>
>>>>>>>>> It would be nice if you and Caleb could post the patches to the mailing list.
>>>>>>>>>
>>>>>>> Yes, when I get something quite solid, I'd like to submit it all to
>>>>>>> the list, and hope to get it into the kernel so nobody else has to go
>>>>>>> through this pain again.
>>>>>>>
>>>>>>>> Indeed! Now the TDM is stable, I've also found the reason of the EVTERRs, which was related to some stale
>>>>>>>> code I've used to enable and disable both RDMAE and TDMAE bits to try to reset the transfers.
>>>>>>>> Once removed that code everything is looks ok now.
>>>>>>>>
>>>>>>>> Regarding patches, well, from my side there isn't nothing special compared to the original fsl_ssi.c code.
>>>>>>>> I'm basically running against a very skinny fsl_ssi.c version, I've just setup a bit larger DMA buffer, from
>>>>>>>> 16bytes to 2K, and now reduced the DMA period to 8 because I'm mostly comfortable with that size to simplify
>>>>>>>> sampling exchange against DAHDI subsystem within my DMA callbacks.
>>>>>>>>
>>>>>>>> In a few words, my problem was related due to a DMA buffer too small.
>>>>>>>>
>>>>>>>> What eventually might be interesting to have is the INTRMASK and EVTERR DMA setting to trigger DMA
>>>>>>>> related errors, but I guess this need to be discussed elsewhere.
>>>>>>> I have implemented roberto's patch on the 4.2 kernel, and I get a huge
>>>>>>> number of EVTERR interrupts.  Something like 7200/second at 16kHz
>>>>>>> sample rate.  But strangely, the audio seems to be correct.
>>>>>> I've notice that clearing the EVTERR bit seems restarting the given SDMA.
>>>>>>
>>>>>>> My patch is slightly different in that it just enables EVTERR for all
>>>>>>> channels, not just for the SSI.  Might as well see if there are any
>>>>>>> other problems.
>>>>>> Oh yes! This will overload the SDMA isr.
>>>>> It didn't seem to.  There didn't seem to be any other DMA happening in
>>>>> my system, definitely none that made the EVTRR trigger.  However, I
>>>>> changed it back to the way you had it.  No differences, still got a
>>>>> TON of EVTERRs.
>>>> This might be related to SDMA request when another is pending.
>>>>
>>>>>> How bigger is your audio buffer?
>>>>>> In your case I guess you will need something like 16KHz * 16 channels *
>>>>>> 2 bytes (16bits) = 512K minimum.
>>>>>> I would try to start from 1MB or maybe more.
>>>>> That's 2 seconds of audio!  We definitely need less buffering than
>>>>> that.    We pretty much need a latency of 100ms, worst case, or 1600
>>>>> frames, or 51,200 bytes.
>>>> I haven't checked in detail how the DAI buffering is working, but likely
>>>> the samples are passed not in buffer size chunks but instead with less
>>>> granularity. Having a large buffer gives more chance to the SSI to not
>>>> overlap DMA requests, hence no more EVTERRs.
>>>>
>>>> I would give it a try.
>>>>> I did change the max buffer size to 1MB though, but I'm not sure how
>>>>> much is actually being used.
>>>> I guess it's 64K, look for IMX_SSI_DMABUF_SIZE.
>>>>
>>>>
>>> Exactly, I changed that to 1024*1024, but still I don't get zero
>>> EVTERRs, even when I set my periods long and number of periods high.
>> They decreased?
>>
> the big win was going to dual fifo, but they're still there at
> something like 17/second.

What about your current fifo_depth? Are you using the full length?
Caleb Crome Nov. 5, 2015, 11:30 p.m. UTC | #8
On Thu, Nov 5, 2015 at 3:28 PM, Roberto Fichera <kernel@tekno-soft.it> wrote:
>
>
> On 11/06/2015 12:21 AM, Caleb Crome wrote:
>> On Thu, Nov 5, 2015 at 3:01 PM, Roberto Fichera <kernel@tekno-soft.it> wrote:
>>>
>>> On 11/05/2015 11:49 PM, Caleb Crome wrote:
>>>> On Thu, Nov 5, 2015 at 2:40 PM, Roberto Fichera <kernel@tekno-soft.it> wrote:
>>>>> On 11/05/2015 11:25 PM, Caleb Crome wrote:
>>>>>> On Thu, Nov 5, 2015 at 2:08 PM, Roberto Fichera <kernel@tekno-soft.it> wrote:
>>>>>>> On 11/05/2015 10:34 PM, Caleb Crome wrote:
>>>>>>>> On Thu, Nov 5, 2015 at 3:48 AM, Roberto Fichera <kernel@tekno-soft.it> wrote:
>>>>>>>>> On 11/05/2015 12:30 PM, Fabio Estevam wrote:
>>>>>>>>>> On Thu, Nov 5, 2015 at 8:03 AM, Roberto Fichera <kernel@tekno-soft.it> wrote:
>>>>>>>>>>
>>>>>>>>>>> Following your suggestion, I've increased the buffer size to 2K and set the period to fifo_length - 2 (13),
>>>>>>>>>>> with that I'm now running substantially smooth except 3 EVTERR on RX DMA over 4 million of interrupts.
>>>>>>>>>>>
>>>>>>>>>>> Thanks Nicolin! I'm quite happy now!
>>>>>>>>>> That's good progress, Roberto.
>>>>>>>>>>
>>>>>>>>>> It would be nice if you and Caleb could post the patches to the mailing list.
>>>>>>>>>>
>>>>>>>> Yes, when I get something quite solid, I'd like to submit it all to
>>>>>>>> the list, and hope to get it into the kernel so nobody else has to go
>>>>>>>> through this pain again.
>>>>>>>>
>>>>>>>>> Indeed! Now the TDM is stable, I've also found the reason of the EVTERRs, which was related to some stale
>>>>>>>>> code I've used to enable and disable both RDMAE and TDMAE bits to try to reset the transfers.
>>>>>>>>> Once removed that code everything is looks ok now.
>>>>>>>>>
>>>>>>>>> Regarding patches, well, from my side there isn't nothing special compared to the original fsl_ssi.c code.
>>>>>>>>> I'm basically running against a very skinny fsl_ssi.c version, I've just setup a bit larger DMA buffer, from
>>>>>>>>> 16bytes to 2K, and now reduced the DMA period to 8 because I'm mostly comfortable with that size to simplify
>>>>>>>>> sampling exchange against DAHDI subsystem within my DMA callbacks.
>>>>>>>>>
>>>>>>>>> In a few words, my problem was related due to a DMA buffer too small.
>>>>>>>>>
>>>>>>>>> What eventually might be interesting to have is the INTRMASK and EVTERR DMA setting to trigger DMA
>>>>>>>>> related errors, but I guess this need to be discussed elsewhere.
>>>>>>>> I have implemented roberto's patch on the 4.2 kernel, and I get a huge
>>>>>>>> number of EVTERR interrupts.  Something like 7200/second at 16kHz
>>>>>>>> sample rate.  But strangely, the audio seems to be correct.
>>>>>>> I've notice that clearing the EVTERR bit seems restarting the given SDMA.
>>>>>>>
>>>>>>>> My patch is slightly different in that it just enables EVTERR for all
>>>>>>>> channels, not just for the SSI.  Might as well see if there are any
>>>>>>>> other problems.
>>>>>>> Oh yes! This will overload the SDMA isr.
>>>>>> It didn't seem to.  There didn't seem to be any other DMA happening in
>>>>>> my system, definitely none that made the EVTRR trigger.  However, I
>>>>>> changed it back to the way you had it.  No differences, still got a
>>>>>> TON of EVTERRs.
>>>>> This might be related to SDMA request when another is pending.
>>>>>
>>>>>>> How bigger is your audio buffer?
>>>>>>> In your case I guess you will need something like 16KHz * 16 channels *
>>>>>>> 2 bytes (16bits) = 512K minimum.
>>>>>>> I would try to start from 1MB or maybe more.
>>>>>> That's 2 seconds of audio!  We definitely need less buffering than
>>>>>> that.    We pretty much need a latency of 100ms, worst case, or 1600
>>>>>> frames, or 51,200 bytes.
>>>>> I haven't checked in detail how the DAI buffering is working, but likely
>>>>> the samples are passed not in buffer size chunks but instead with less
>>>>> granularity. Having a large buffer gives more chance to the SSI to not
>>>>> overlap DMA requests, hence no more EVTERRs.
>>>>>
>>>>> I would give it a try.
>>>>>> I did change the max buffer size to 1MB though, but I'm not sure how
>>>>>> much is actually being used.
>>>>> I guess it's 64K, look for IMX_SSI_DMABUF_SIZE.
>>>>>
>>>>>
>>>> Exactly, I changed that to 1024*1024, but still I don't get zero
>>>> EVTERRs, even when I set my periods long and number of periods high.
>>> They decreased?
>>>
>> the big win was going to dual fifo, but they're still there at
>> something like 17/second.
>
> What about your current fifo_depth? Are you using the full length?
>

Do you mean in the SSI watermark, or some other FIFO depth?

I'm currently operating at watermark = 6 & DMA maxburst of 12 (dual fifo mode).

That's the best performing so far.

-Caleb
Roberto Fichera Nov. 5, 2015, 11:46 p.m. UTC | #9
On 11/06/2015 12:30 AM, Caleb Crome wrote:
> On Thu, Nov 5, 2015 at 3:28 PM, Roberto Fichera <kernel@tekno-soft.it> wrote:
>>
>> On 11/06/2015 12:21 AM, Caleb Crome wrote:
>>> On Thu, Nov 5, 2015 at 3:01 PM, Roberto Fichera <kernel@tekno-soft.it> wrote:
>>>> On 11/05/2015 11:49 PM, Caleb Crome wrote:
>>>>> On Thu, Nov 5, 2015 at 2:40 PM, Roberto Fichera <kernel@tekno-soft.it> wrote:
>>>>>> On 11/05/2015 11:25 PM, Caleb Crome wrote:
>>>>>>> On Thu, Nov 5, 2015 at 2:08 PM, Roberto Fichera <kernel@tekno-soft.it> wrote:
>>>>>>>> On 11/05/2015 10:34 PM, Caleb Crome wrote:
>>>>>>>>> On Thu, Nov 5, 2015 at 3:48 AM, Roberto Fichera <kernel@tekno-soft.it> wrote:
>>>>>>>>>> On 11/05/2015 12:30 PM, Fabio Estevam wrote:
>>>>>>>>>>> On Thu, Nov 5, 2015 at 8:03 AM, Roberto Fichera <kernel@tekno-soft.it> wrote:
>>>>>>>>>>>
>>>>>>>>>>>> Following your suggestion, I've increased the buffer size to 2K and set the period to fifo_length - 2 (13),
>>>>>>>>>>>> with that I'm now running substantially smooth except 3 EVTERR on RX DMA over 4 million of interrupts.
>>>>>>>>>>>>
>>>>>>>>>>>> Thanks Nicolin! I'm quite happy now!
>>>>>>>>>>> That's good progress, Roberto.
>>>>>>>>>>>
>>>>>>>>>>> It would be nice if you and Caleb could post the patches to the mailing list.
>>>>>>>>>>>
>>>>>>>>> Yes, when I get something quite solid, I'd like to submit it all to
>>>>>>>>> the list, and hope to get it into the kernel so nobody else has to go
>>>>>>>>> through this pain again.
>>>>>>>>>
>>>>>>>>>> Indeed! Now the TDM is stable, I've also found the reason of the EVTERRs, which was related to some stale
>>>>>>>>>> code I've used to enable and disable both RDMAE and TDMAE bits to try to reset the transfers.
>>>>>>>>>> Once removed that code everything is looks ok now.
>>>>>>>>>>
>>>>>>>>>> Regarding patches, well, from my side there isn't nothing special compared to the original fsl_ssi.c code.
>>>>>>>>>> I'm basically running against a very skinny fsl_ssi.c version, I've just setup a bit larger DMA buffer, from
>>>>>>>>>> 16bytes to 2K, and now reduced the DMA period to 8 because I'm mostly comfortable with that size to simplify
>>>>>>>>>> sampling exchange against DAHDI subsystem within my DMA callbacks.
>>>>>>>>>>
>>>>>>>>>> In a few words, my problem was related due to a DMA buffer too small.
>>>>>>>>>>
>>>>>>>>>> What eventually might be interesting to have is the INTRMASK and EVTERR DMA setting to trigger DMA
>>>>>>>>>> related errors, but I guess this need to be discussed elsewhere.
>>>>>>>>> I have implemented roberto's patch on the 4.2 kernel, and I get a huge
>>>>>>>>> number of EVTERR interrupts.  Something like 7200/second at 16kHz
>>>>>>>>> sample rate.  But strangely, the audio seems to be correct.
>>>>>>>> I've notice that clearing the EVTERR bit seems restarting the given SDMA.
>>>>>>>>
>>>>>>>>> My patch is slightly different in that it just enables EVTERR for all
>>>>>>>>> channels, not just for the SSI.  Might as well see if there are any
>>>>>>>>> other problems.
>>>>>>>> Oh yes! This will overload the SDMA isr.
>>>>>>> It didn't seem to.  There didn't seem to be any other DMA happening in
>>>>>>> my system, definitely none that made the EVTRR trigger.  However, I
>>>>>>> changed it back to the way you had it.  No differences, still got a
>>>>>>> TON of EVTERRs.
>>>>>> This might be related to SDMA request when another is pending.
>>>>>>
>>>>>>>> How bigger is your audio buffer?
>>>>>>>> In your case I guess you will need something like 16KHz * 16 channels *
>>>>>>>> 2 bytes (16bits) = 512K minimum.
>>>>>>>> I would try to start from 1MB or maybe more.
>>>>>>> That's 2 seconds of audio!  We definitely need less buffering than
>>>>>>> that.    We pretty much need a latency of 100ms, worst case, or 1600
>>>>>>> frames, or 51,200 bytes.
>>>>>> I haven't checked in detail how the DAI buffering is working, but likely
>>>>>> the samples are passed not in buffer size chunks but instead with less
>>>>>> granularity. Having a large buffer gives more chance to the SSI to not
>>>>>> overlap DMA requests, hence no more EVTERRs.
>>>>>>
>>>>>> I would give it a try.
>>>>>>> I did change the max buffer size to 1MB though, but I'm not sure how
>>>>>>> much is actually being used.
>>>>>> I guess it's 64K, look for IMX_SSI_DMABUF_SIZE.
>>>>>>
>>>>>>
>>>>> Exactly, I changed that to 1024*1024, but still I don't get zero
>>>>> EVTERRs, even when I set my periods long and number of periods high.
>>>> They decreased?
>>>>
>>> the big win was going to dual fifo, but they're still there at
>>> something like 17/second.
>> What about your current fifo_depth? Are you using the full length?
>>
> Do you mean in the SSI watermark, or some other FIFO depth?

Sorry! SSI watermark.

> I'm currently operating at watermark = 6 & DMA maxburst of 12 (dual fifo mode).
>
> That's the best performing so far.

Have you already played to see if increasing the watermark to 8 and
maxburst to 15 decrease the EVTERRs?
I haven't check how the SDMA script works in dual fifo mode, but I think
that in this operating mode, maxburst
might be also 16.
> -Caleb
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel@alsa-project.org
> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
Caleb Crome Nov. 6, 2015, 12:35 a.m. UTC | #10
On Thu, Nov 5, 2015 at 3:46 PM, Roberto Fichera <kernel@tekno-soft.it> wrote:
> On 11/06/2015 12:30 AM, Caleb Crome wrote:
>> On Thu, Nov 5, 2015 at 3:28 PM, Roberto Fichera <kernel@tekno-soft.it> wrote:
>>>
>>> On 11/06/2015 12:21 AM, Caleb Crome wrote:
>>>> On Thu, Nov 5, 2015 at 3:01 PM, Roberto Fichera <kernel@tekno-soft.it> wrote:
>>>>> On 11/05/2015 11:49 PM, Caleb Crome wrote:
>>>>>> On Thu, Nov 5, 2015 at 2:40 PM, Roberto Fichera <kernel@tekno-soft.it> wrote:
>>>>>>> On 11/05/2015 11:25 PM, Caleb Crome wrote:
>>>>>>>> On Thu, Nov 5, 2015 at 2:08 PM, Roberto Fichera <kernel@tekno-soft.it> wrote:
>>>>>>>>> On 11/05/2015 10:34 PM, Caleb Crome wrote:
>>>>>>>>>> On Thu, Nov 5, 2015 at 3:48 AM, Roberto Fichera <kernel@tekno-soft.it> wrote:
>>>>>>>>>>> On 11/05/2015 12:30 PM, Fabio Estevam wrote:
>>>>>>>>>>>> On Thu, Nov 5, 2015 at 8:03 AM, Roberto Fichera <kernel@tekno-soft.it> wrote:
>>>>>>>>>>>>
>>>>>>>>>>>>> Following your suggestion, I've increased the buffer size to 2K and set the period to fifo_length - 2 (13),
>>>>>>>>>>>>> with that I'm now running substantially smooth except 3 EVTERR on RX DMA over 4 million of interrupts.
>>>>>>>>>>>>>
>>>>>>>>>>>>> Thanks Nicolin! I'm quite happy now!
>>>>>>>>>>>> That's good progress, Roberto.
>>>>>>>>>>>>
>>>>>>>>>>>> It would be nice if you and Caleb could post the patches to the mailing list.
>>>>>>>>>>>>
>>>>>>>>>> Yes, when I get something quite solid, I'd like to submit it all to
>>>>>>>>>> the list, and hope to get it into the kernel so nobody else has to go
>>>>>>>>>> through this pain again.
>>>>>>>>>>
>>>>>>>>>>> Indeed! Now the TDM is stable, I've also found the reason of the EVTERRs, which was related to some stale
>>>>>>>>>>> code I've used to enable and disable both RDMAE and TDMAE bits to try to reset the transfers.
>>>>>>>>>>> Once removed that code everything is looks ok now.
>>>>>>>>>>>
>>>>>>>>>>> Regarding patches, well, from my side there isn't nothing special compared to the original fsl_ssi.c code.
>>>>>>>>>>> I'm basically running against a very skinny fsl_ssi.c version, I've just setup a bit larger DMA buffer, from
>>>>>>>>>>> 16bytes to 2K, and now reduced the DMA period to 8 because I'm mostly comfortable with that size to simplify
>>>>>>>>>>> sampling exchange against DAHDI subsystem within my DMA callbacks.
>>>>>>>>>>>
>>>>>>>>>>> In a few words, my problem was related due to a DMA buffer too small.
>>>>>>>>>>>
>>>>>>>>>>> What eventually might be interesting to have is the INTRMASK and EVTERR DMA setting to trigger DMA
>>>>>>>>>>> related errors, but I guess this need to be discussed elsewhere.
>>>>>>>>>> I have implemented roberto's patch on the 4.2 kernel, and I get a huge
>>>>>>>>>> number of EVTERR interrupts.  Something like 7200/second at 16kHz
>>>>>>>>>> sample rate.  But strangely, the audio seems to be correct.
>>>>>>>>> I've notice that clearing the EVTERR bit seems restarting the given SDMA.
>>>>>>>>>
>>>>>>>>>> My patch is slightly different in that it just enables EVTERR for all
>>>>>>>>>> channels, not just for the SSI.  Might as well see if there are any
>>>>>>>>>> other problems.
>>>>>>>>> Oh yes! This will overload the SDMA isr.
>>>>>>>> It didn't seem to.  There didn't seem to be any other DMA happening in
>>>>>>>> my system, definitely none that made the EVTRR trigger.  However, I
>>>>>>>> changed it back to the way you had it.  No differences, still got a
>>>>>>>> TON of EVTERRs.
>>>>>>> This might be related to SDMA request when another is pending.
>>>>>>>
>>>>>>>>> How bigger is your audio buffer?
>>>>>>>>> In your case I guess you will need something like 16KHz * 16 channels *
>>>>>>>>> 2 bytes (16bits) = 512K minimum.
>>>>>>>>> I would try to start from 1MB or maybe more.
>>>>>>>> That's 2 seconds of audio!  We definitely need less buffering than
>>>>>>>> that.    We pretty much need a latency of 100ms, worst case, or 1600
>>>>>>>> frames, or 51,200 bytes.
>>>>>>> I haven't checked in detail how the DAI buffering is working, but likely
>>>>>>> the samples are passed not in buffer size chunks but instead with less
>>>>>>> granularity. Having a large buffer gives more chance to the SSI to not
>>>>>>> overlap DMA requests, hence no more EVTERRs.
>>>>>>>
>>>>>>> I would give it a try.
>>>>>>>> I did change the max buffer size to 1MB though, but I'm not sure how
>>>>>>>> much is actually being used.
>>>>>>> I guess it's 64K, look for IMX_SSI_DMABUF_SIZE.
>>>>>>>
>>>>>>>
>>>>>> Exactly, I changed that to 1024*1024, but still I don't get zero
>>>>>> EVTERRs, even when I set my periods long and number of periods high.
>>>>> They decreased?
>>>>>
>>>> the big win was going to dual fifo, but they're still there at
>>>> something like 17/second.
>>> What about your current fifo_depth? Are you using the full length?
>>>
>> Do you mean in the SSI watermark, or some other FIFO depth?
>
> Sorry! SSI watermark.
>
>> I'm currently operating at watermark = 6 & DMA maxburst of 12 (dual fifo mode).
>>
>> That's the best performing so far.
>
> Have you already played to see if increasing the watermark to 8 and
> maxburst to 15 decrease the EVTERRs?


16kHz, wm=8, maxburst = 15:  total data integrity failure.
    data coming out the port is not in order.  Also, get
    EVTERRs on ch 1 and ch 2.

48kHz, wm=8, maxburst = 16: 100 EVTERRs/sec, but data is right.

16kHz, wm=8, maxburst = 16:  0 EVTERRs/sec but data on SSI is wrong.

48kHz, wm=7, maxburst = 14:  total system lockup. (might be infinite
printk's or something, but it's dead).


Interestingly, even with I'm getting many EVTERRs, I'm not getting SSI
FIFO under/overruns.  How is that possible?

Will try more tomorrow...

-caleb

> I haven't check how the SDMA script works in dual fifo mode, but I think
> that in this operating mode, maxburst
> might be also 16.
>> -Caleb
>> _______________________________________________
>> Alsa-devel mailing list
>> Alsa-devel@alsa-project.org
>> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
>

Patch
diff mbox

diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index 9d375bc..a3a2317 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -38,6 +38,8 @@ 
 #include <linux/of_address.h>
 #include <linux/of_device.h>
 #include <linux/of_dma.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>

 #include <asm/irq.h>
 #include <linux/platform_data/dma-imx-sdma.h>
@@ -50,6 +52,8 @@ 

 /* SDMA registers */
 #define SDMA_H_C0PTR           0x000
+#define SDMACORE_EVENTS         0x005
+#define SDMACORE_EVENTS2        0x01f
 #define SDMA_H_INTR            0x004
 #define SDMA_H_STATSTOP                0x008
 #define SDMA_H_START           0x00c
@@ -385,6 +389,9 @@  struct sdma_engine {
        const struct sdma_driver_data   *drvdata;
        u32                             spba_start_addr;
        u32                             spba_end_addr;
+        u32                             evterrchannel[MAX_DMA_CHANNELS];
+       struct dentry *dbg_dir;
+       struct dentry *dbg_stats;
 };

 static struct sdma_driver_data sdma_imx31 = {
@@ -562,7 +569,19 @@  static int sdma_config_ownership(struct
sdma_channel *sdmac,

 static void sdma_enable_channel(struct sdma_engine *sdma, int channel)
 {
+       struct sdma_channel *sdmac = &sdma->channel[channel];
+       u32 msk;
+
        writel(BIT(channel), sdma->regs + SDMA_H_START);
+       /*
+        * enable EVTERR interrupts on this channel
+        */
+       if ((sdmac->peripheral_type == IMX_DMATYPE_SSI_SP) ||
+           (sdmac->peripheral_type == IMX_DMATYPE_SSI_DUAL)) {
+               msk = readl(sdma->regs + SDMA_H_INTRMSK);
+               writel(msk | BIT(channel), sdma->regs + SDMA_H_INTRMSK);
+               printk(KERN_INFO "%s: enabling EVTERR for channel
%d\n", __func__, channel);
+       }
 }