All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: fsl_ssi.c: Roberto's problem: ssi hangs after some number of samples
@ 2015-10-30 18:01 Caleb Crome
  2015-10-31  9:16 ` Roberto Fichera
  0 siblings, 1 reply; 33+ messages in thread
From: Caleb Crome @ 2015-10-30 18:01 UTC (permalink / raw)
  To: Roberto Fichera
  Cc: Fabio Estevam, alsa-devel, Shengjiu Wang, Nicolin Chen,
	arnaud.mouiche, Markus Pargmann, shawn.guo, Fabio Estevam

Hi All, is it okay of we split Roberto's problem from mine?  It's
getting difficult to track which response goes to which problem :-)

I included Roberto's email, and Nicolin's reply below:

So, this thread is for the hanging problem, the prehistory for this
thread is in, "fsl_ssi.c: Getting channel slips with fsl_ssi.c in TDM
(network) mode."

-Caleb

On Fri, Oct 30, 2015 at 4:42 AM, Roberto Fichera <kernel@tekno-soft.it> wrote:
> On 10/30/2015 12:04 AM, Nicolin Chen wrote:
>> On Wed, Oct 28, 2015 at 09:11:39AM +0100, Roberto Fichera wrote:
>>
>>> I'm also having the same issue but employing SSI in TDM master mode against a SLIC Si32178
>>> using its PCM mode. PCLK is at 2048KHz, FSYNC is 8KHz slot length is 32 bits (SSI wants
>>> this since when in master mode) but valid data set to be 8bits in the SSI register.
>>> My Current situation is that I've a custom fsl_ssi.c driver to control the SSI in TDM master mode
>>> both PCLK and FSYNC works perfectly fine, the SLIC has a register that I can check via SPI for
>>> such purpose, I can see the clocking status from its side. The main problem I've is exactly the same
>>> Caleb is having, after a certain amount of SDMA transfers, roughly 1000 or so, everything stops
>>> without any apparent reason.
>> I will start to help you to figure out your problem. But it seems that
>> you are having a different issue here with clock generation. I don't
>> get why you said *same issue*. For double confirm, the the "everything
>> stops" mentioned, does it mean that clock from SSI stops?
>>
>
> Definitively yes! My problem is different than Caleb's one. Just to summarize the things.
> I've the SSI1 connected to a SiLabs SLIC Si32178 via AUDMUX6 padmux is below:
>
>         pinctrl_audmux_1: audmuxgrp-3 {
>             fsl,pins = <
>                 MX6SX_PAD_SD3_DATA1__AUDMUX_AUD6_TXC    0x130b0    /* PCLK */
>                 MX6SX_PAD_SD3_DATA2__AUDMUX_AUD6_TXFS   0x130b0    /* FSYNC */
>                 MX6SX_PAD_SD3_DATA0__AUDMUX_AUD6_RXD    0x130b0    /* DTX */
>                 MX6SX_PAD_SD3_DATA3__AUDMUX_AUD6_TXD    0x120b0    /* DRX */
>             >;
>         };
>
> The Si32178 is slave device so the SSI1 has to generate both BCLK and FSYNC. I've configured
> the AUDMUX as:
>
> int si3217x_audmux_config(unsigned int master, unsigned int slave)
> {
>   unsigned int ptcr, pdcr;
>
>   ptcr = IMX_AUDMUX_V2_PTCR_SYN |
>          IMX_AUDMUX_V2_PTCR_TFSDIR |
>          IMX_AUDMUX_V2_PTCR_TFSEL(master) |
>          IMX_AUDMUX_V2_PTCR_TCLKDIR |
>          IMX_AUDMUX_V2_PTCR_TCSEL(master);
>   pdcr = IMX_AUDMUX_V2_PDCR_RXDSEL(master);
>   si3217x_audmux_v2_configure_port(slave, ptcr, pdcr); /* configure internal port */
>
>   ptcr = IMX_AUDMUX_V2_PTCR_SYN;
>   pdcr = IMX_AUDMUX_V2_PDCR_RXDSEL(slave);
>   si3217x_audmux_v2_configure_port(master, ptcr, pdcr); /* configure external port */
>
>   return 0;
> }
>
> BCLK is 2048KHz, FSYNC@8KHz, frame is 32 slots at 8bits each. Looking at TXC and TXFS
> with a logical analyzer everything looks ok.
>
> The SSI is setup at beginning as:
>
>         unsigned long flags;
>         struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
>         u32 srcr;
>         u8 wm;
>
>         clk_prepare_enable(ssi_private->clk);
>
>         /*
>          * Section 16.5 of the MPC8610 reference manual says that the
>          * SSI needs to be disabled before updating the registers we set
>          * here.
>          */
>         write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_SSIEN, 0);
>
>         /*
>          * Program the SSI into I2S Master Network Synchronous mode.
>          * Also enable the transmit and receive FIFO.
>          */
>         write_ssi_mask(&ssi->scr,
>             CCSR_SSI_SCR_I2S_MODE_MASK | CCSR_SSI_SCR_SYN,
>             CCSR_SSI_SCR_I2S_MODE_NORMAL
>             | CCSR_SSI_SCR_SYN | CCSR_SSI_SCR_NET
>             | CCSR_SSI_SCR_SYS_CLK_EN);
>
>         /*
>          * TX falling edge PCLK is mandatory because the RX SLIC side works in this way
>          */
>         writel( CCSR_SSI_STCR_TXBIT0 /* LSB Aligned */
>               | CCSR_SSI_STCR_TFEN0  /* Enable TX FIFO0 */
>               | CCSR_SSI_STCR_TSCKP  /* Transmit Clock Polarity - Data Clocked out on falling edge */
>               | CCSR_SSI_STCR_TFDIR  /* Transmit Frame Direction Internal - generated internally */
>               | CCSR_SSI_STCR_TXDIR, /* Transmit Clock Direction Internal - generated internally */
>             &ssi->stcr);
>
>     srcr = readl(&ssi->srcr);
>
>         /*
>          * clear out RFDIR and RXDIR because the clock is synchronous
>          */
>     srcr &= ~(CCSR_SSI_SRCR_RFDIR | CCSR_SSI_SRCR_RXDIR);
>
>         srcr |= CCSR_SSI_SRCR_RXBIT0 /* LSB Aligned */
>              |  CCSR_SSI_SRCR_RFEN0  /* Enable RX FIFO0 */
>              |  CCSR_SSI_SRCR_RSCKP  /* Receive Clock Polarity - Data latched on rising edge */
>             ;
>
>     writel(srcr, &ssi->srcr);
>
>         /* do not service the isr yet */
>         writel(0, &ssi->sier);
>
>         /*
>          * Set the watermark for transmit FIFI 0 and receive FIFO 0. We
>          * don't use FIFO 1.  We program the transmit water to signal a
>          * DMA transfer if there are only two (or fewer) elements left
>          * in the FIFO.
>          */
>
>        /*
>         * tdm_real_slots is 2 because mask all except first 2 slots
>         * our buffer is 2 slots * 8 bytes each, so set watermarks to a multiple of it
>         * 8 words in our case
>         */
>
>         wm = ssi_private->tdm_real_slots * 4; //ssi_private->use_dma ? ssi_private->fifo_depth - 2 :
> ssi_private->fifo_depth;
>
>         writel(CCSR_SSI_SFCSR_TFWM0(wm) |
>                CCSR_SSI_SFCSR_RFWM0(wm) |
>                CCSR_SSI_SFCSR_TFWM1(wm) |
>                CCSR_SSI_SFCSR_RFWM1(wm),
>                &ssi->sfcsr);
>
>         /* enable one FIFO */
>         write_ssi_mask(&ssi->srcr, CCSR_SSI_SRCR_RFEN1, 0);
>         write_ssi_mask(&ssi->stcr, CCSR_SSI_STCR_TFEN1, 0);
>
>         /* disable SSI two-channel mode operation */
>         write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_TCH_EN, 0);
>
>         /*
>          * We keep the SSI disabled because if we enable it, then the
>          * DMA controller will start.  It's not supposed to start until
>          * the SCR.TE (or SCR.RE) bit is set, but it does anyway.  The
>          * DMA controller will transfer one "BWC" of data (i.e. the
>          * amount of data that the MR.BWC bits are set to).  The reason
>          * this is bad is because at this point, the PCM driver has not
>          * finished initializing the DMA controller.
>          */
>
>         /* Set default slot number -- 32 in our case */
>         write_ssi_mask(&ssi->stccr, CCSR_SSI_SxCCR_DC_MASK,
>             CCSR_SSI_SxCCR_DC(ssi_private->tdm_slots));
>         write_ssi_mask(&ssi->srccr, CCSR_SSI_SxCCR_DC_MASK,
>             CCSR_SSI_SxCCR_DC(ssi_private->tdm_slots));
>
>         /* Set default word length -- 8 bits */
>         write_ssi_mask(&ssi->stccr, CCSR_SSI_SxCCR_WL_MASK,
>             CCSR_SSI_SxCCR_WL(ssi_private->tdm_word_size));
>         write_ssi_mask(&ssi->srccr, CCSR_SSI_SxCCR_WL_MASK,
>             CCSR_SSI_SxCCR_WL(ssi_private->tdm_word_size));
>
>         /* enable the SSI */
>         write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_SSIEN, CCSR_SSI_SCR_SSIEN);
>
>         /*
>          * we are interested only at first 2 slots
>          */
>         writel(~ssi_private->tdm_slots_enabled, &ssi->stmsk);
>         writel(~ssi_private->tdm_slots_enabled, &ssi->srmsk);
>
>        return 0;
> }
>
> SSI clock calculated and then enabled. Both TX and RX DMA channel are requested in the probe() function as below.
> and the corresponding TX and RX SDMA event in DTS are using the default from imx6sx.dtsi:
>
>             slave_config.direction = DMA_MEM_TO_DEV;
>             slave_config.dst_addr = ssi_private->ssi_phys + offsetof(struct ccsr_ssi, stx0);
>             slave_config.dst_addr_width = width;
>             slave_config.dst_maxburst = ssi_private->tdm_real_slots * 4;
>             ret = dmaengine_slave_config(ssi_private->tx_chan, &slave_config);
>
>             ssi_private->rx_chan = dma_request_slave_channel_reason(&pdev->dev, "rx");
>             slave_config.direction = DMA_DEV_TO_MEM;
>             slave_config.src_addr = ssi_private->ssi_phys + offsetof(struct ccsr_ssi, srx0);
>             slave_config.src_addr_width = width;
>             slave_config.src_maxburst = ssi_private->tdm_real_slots * 4;
>             ret = dmaengine_slave_config(ssi_private->rx_chan, &slave_config);
>
> and setup before RDMAE and TDMAE bits, like this:
>
>         ssi_private->tx_buf = dma_alloc_coherent(NULL, buffer_len,
>                                         &ssi_private->tx_dmaaddr, GFP_KERNEL);
>         desc = dmaengine_prep_dma_cyclic(ssi_private->tx_chan, ssi_private->tx_dmaaddr,
>                 buffer_len, ssi_private->tdm_real_slots*4,
>                 DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT);
>
>         desc->callback = dma_tx_callback;
>         desc->callback_param = ssi_private;
>
>         printk("TX: prepare for the DMA.\n");
>         dmaengine_submit(desc);
>         dma_async_issue_pending(ssi_private->tx_chan);
>
>         ssi_private->rx_buf = dma_alloc_coherent(NULL, buffer_len,
>                                         &ssi_private->rx_dmaaddr, GFP_KERNEL);
>
>         desc = dmaengine_prep_dma_cyclic(ssi_private->rx_chan, ssi_private->rx_dmaaddr,
>                 buffer_len, ssi_private->tdm_real_slots*4,
>                 DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT);
>
>         desc->callback = dma_rx_callback;
>         desc->callback_param = ssi_private;
>
>         printk("RX: prepare for the DMA.\n");
>         dmaengine_submit(desc);
>         dma_async_issue_pending(ssi_private->rx_chan);
>
> Finally, the SSI's TX and RX parts are now enabled
>
>     scr = readl(&ssi->scr);
>
>     scr |= CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE;   /* enable both TX and RX SSI sections */
>
>     writel(scr, &ssi->scr);
>
> Finally the SIER si programmed as:
>
>    struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
>     u32 sier = CCSR_SSI_SIER_RFF0_EN | CCSR_SSI_SIER_TFE0_EN;
>
>     /*
>      * if DMA is enabled than allow SSI request for DMA transfers
>      * otherwise normal interrupt requests
>      */
>
>     if (ssi_private->use_dma>0)
>     {
>       sier |= CCSR_SSI_SIER_RDMAE | CCSR_SSI_SIER_TDMAE;
>     }
>
>     if (ssi_private->use_dma>1 || !ssi_private->use_dma)
>     {
>       sier |= CCSR_SSI_SIER_RIE | CCSR_SSI_SIER_TIE;
>     }
>
>     sier &= ~(CCSR_SSI_SIER_TDE1_EN | CCSR_SSI_SIER_TFE1_EN |
>               CCSR_SSI_SIER_TFE0_EN | CCSR_SSI_SIER_TDE0_EN);
>
>     writel(sier, &ssi->sier);
>
> At this time I should see the DMA callbacks called every burst_size words. This behaviour
> doesn't really happen as I wish because I can see from a proc file that such callbacks
> are called from 1 to 20000 times and then anymore. This is also confirmed by the fact that
> the interrupt 34 (sdma) doesn't increase anymore but matches my internal counters collected
> within my callbacks. Here is what I can inspect from the data I have collected:
>
> root@voneus-domus-imx6sx:~# cat /proc/domus_ssi_stats
> SSI TDM Info:
>         PLL clk=66000000
>         SSI baudclk=49152000
>         ssi_phy=0x02028000
>         irq=78
>         fifo_depth=15 <---- this is what is read from DTS but not as watermark
>         tdm_frame_rate=8000
>         tdm_slots=32 (real 2)
>         tdm_word_size=8
>         tdm_slots_enabled=00000000000000000000000000000011
>         clk_frequency=2048000
>         clock_running=yes
>         DMA=yes
>         Dual FIFO=no
>         RX DMA frame count=17121
>         RX DMA addr=0x9c692000
>         RX DMA buffer len=16
>         TX DMA frame count=17121
>         TX DMA addr=0x9c4aa000
>         TX DMA buffer len=16
>
> SSI Registers:
>         ssi_scr=0x0000009f
>         ssi_sier=0x00500004
>         ssi_stcr=0x000002e8
>         ssi_srcr=0x00000288
>         ssi_stccr=0x00007f0b
>         ssi_srccr=0x00007f0b
>         ssi_sfcsr=0x0088f088
>         ssi_stmsk=0xfffffffc
>         ssi_srmsk=0xfffffffc
>
> Cheers,
> Roberto Fichera.



And here's Nicolin's reply:

On Fri, Oct 30, 2015 at 12:42:53PM +0100, Roberto Fichera wrote:


>         /*
>          * Set the watermark for transmit FIFI 0 and receive FIFO 0. We
>          * don't use FIFO 1.  We program the transmit water to signal a
>          * DMA transfer if there are only two (or fewer) elements left
>          * in the FIFO.
>          */

> SSI clock calculated and then enabled. Both TX and RX DMA channel are requested in the probe() function as below.
> and the corresponding TX and RX SDMA event in DTS are using the default from imx6sx.dtsi:

Since you are using single FIFO configuration, which SDMA script
are you using? This should reflects in the Device Tree. As far as
I learned, FSL 3.14 is using number 22 for SSIs which is the one
for Dual FIFO Mode.

> At this time I should see the DMA callbacks called every burst_size words. This behaviour
> doesn't really happen as I wish because I can see from a proc file that such callbacks
> are called from 1 to 20000 times and then anymore. This is also confirmed by the fact that
> the interrupt 34 (sdma) doesn't increase anymore but matches my internal counters collected
> within my callbacks. Here is what I can inspect from the data I have collected:

Just for clarification, the behaviour doesn't happen as you wish
is just the DMA stopped? I remember you also mentioned bit clock
has stopped as you can check the clock status from the Codec chip.

> SSI Registers:
>         ssi_sfcsr=0x0088f088

At this point you have data in RxFIFO and get empty in TxFIFO, so
the DMA requests from both side should be issued. If the DMA stops
as you described, you must check those two channels from the SDMA
side by dumping SDMAARM_STOP_STAT, SDMAARM_HSTART, SDMAARM_EVTOVR,
SDMAARM_EVTPEND, SDMAARM_EVTERR, SDMAARM_DSPOVR and SDMAARM_HOSTOVR
registers.

Overall, I don't see an obvious defect from you SSI side, but you
may also try to toggle TDMAE and RDMAE at the point that callback
stops -- re-raise the DMA requests by disabling and enabling TDMAE
and RDMAE again and see if it works. I think either something did
intervene register controls of SDMA or SSI, or SDMA have missed the
request signals from SSI.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: fsl_ssi.c: Roberto's problem: ssi hangs after some number of samples
  2015-10-30 18:01 fsl_ssi.c: Roberto's problem: ssi hangs after some number of samples Caleb Crome
@ 2015-10-31  9:16 ` Roberto Fichera
  2015-11-01 20:31   ` Fabio Estevam
                     ` (2 more replies)
  0 siblings, 3 replies; 33+ messages in thread
From: Roberto Fichera @ 2015-10-31  9:16 UTC (permalink / raw)
  To: Caleb Crome
  Cc: Fabio Estevam, alsa-devel, Shengjiu Wang, Nicolin Chen,
	arnaud.mouiche, Markus Pargmann, shawn.guo, Fabio Estevam

On 10/30/2015 07:01 PM, Caleb Crome wrote:
> Hi All, is it okay of we split Roberto's problem from mine?  It's
> getting difficult to track which response goes to which problem :-)
>
> I included Roberto's email, and Nicolin's reply below:
>
> So, this thread is for the hanging problem, the prehistory for this
> thread is in, "fsl_ssi.c: Getting channel slips with fsl_ssi.c in TDM
> (network) mode."

That's fine! Thanks Calab!

>
> -Caleb
>
> On Fri, Oct 30, 2015 at 4:42 AM, Roberto Fichera <kernel@tekno-soft.it> wrote:
>> On 10/30/2015 12:04 AM, Nicolin Chen wrote:
>>> On Wed, Oct 28, 2015 at 09:11:39AM +0100, Roberto Fichera wrote:
>>>
>>>> I'm also having the same issue but employing SSI in TDM master mode against a SLIC Si32178
>>>> using its PCM mode. PCLK is at 2048KHz, FSYNC is 8KHz slot length is 32 bits (SSI wants
>>>> this since when in master mode) but valid data set to be 8bits in the SSI register.
>>>> My Current situation is that I've a custom fsl_ssi.c driver to control the SSI in TDM master mode
>>>> both PCLK and FSYNC works perfectly fine, the SLIC has a register that I can check via SPI for
>>>> such purpose, I can see the clocking status from its side. The main problem I've is exactly the same
>>>> Caleb is having, after a certain amount of SDMA transfers, roughly 1000 or so, everything stops
>>>> without any apparent reason.
>>> I will start to help you to figure out your problem. But it seems that
>>> you are having a different issue here with clock generation. I don't
>>> get why you said *same issue*. For double confirm, the the "everything
>>> stops" mentioned, does it mean that clock from SSI stops?
>>>
>> Definitively yes! My problem is different than Caleb's one. Just to summarize the things.
>> I've the SSI1 connected to a SiLabs SLIC Si32178 via AUDMUX6 padmux is below:
>>
>>         pinctrl_audmux_1: audmuxgrp-3 {
>>             fsl,pins = <
>>                 MX6SX_PAD_SD3_DATA1__AUDMUX_AUD6_TXC    0x130b0    /* PCLK */
>>                 MX6SX_PAD_SD3_DATA2__AUDMUX_AUD6_TXFS   0x130b0    /* FSYNC */
>>                 MX6SX_PAD_SD3_DATA0__AUDMUX_AUD6_RXD    0x130b0    /* DTX */
>>                 MX6SX_PAD_SD3_DATA3__AUDMUX_AUD6_TXD    0x120b0    /* DRX */
>>             >;
>>         };
>>
>> The Si32178 is slave device so the SSI1 has to generate both BCLK and FSYNC. I've configured
>> the AUDMUX as:
>>
>> int si3217x_audmux_config(unsigned int master, unsigned int slave)
>> {
>>   unsigned int ptcr, pdcr;
>>
>>   ptcr = IMX_AUDMUX_V2_PTCR_SYN |
>>          IMX_AUDMUX_V2_PTCR_TFSDIR |
>>          IMX_AUDMUX_V2_PTCR_TFSEL(master) |
>>          IMX_AUDMUX_V2_PTCR_TCLKDIR |
>>          IMX_AUDMUX_V2_PTCR_TCSEL(master);
>>   pdcr = IMX_AUDMUX_V2_PDCR_RXDSEL(master);
>>   si3217x_audmux_v2_configure_port(slave, ptcr, pdcr); /* configure internal port */
>>
>>   ptcr = IMX_AUDMUX_V2_PTCR_SYN;
>>   pdcr = IMX_AUDMUX_V2_PDCR_RXDSEL(slave);
>>   si3217x_audmux_v2_configure_port(master, ptcr, pdcr); /* configure external port */
>>
>>   return 0;
>> }
>>
>> BCLK is 2048KHz, FSYNC@8KHz, frame is 32 slots at 8bits each. Looking at TXC and TXFS
>> with a logical analyzer everything looks ok.
>>
>> The SSI is setup at beginning as:
>>
>>         unsigned long flags;
>>         struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
>>         u32 srcr;
>>         u8 wm;
>>
>>         clk_prepare_enable(ssi_private->clk);
>>
>>         /*
>>          * Section 16.5 of the MPC8610 reference manual says that the
>>          * SSI needs to be disabled before updating the registers we set
>>          * here.
>>          */
>>         write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_SSIEN, 0);
>>
>>         /*
>>          * Program the SSI into I2S Master Network Synchronous mode.
>>          * Also enable the transmit and receive FIFO.
>>          */
>>         write_ssi_mask(&ssi->scr,
>>             CCSR_SSI_SCR_I2S_MODE_MASK | CCSR_SSI_SCR_SYN,
>>             CCSR_SSI_SCR_I2S_MODE_NORMAL
>>             | CCSR_SSI_SCR_SYN | CCSR_SSI_SCR_NET
>>             | CCSR_SSI_SCR_SYS_CLK_EN);
>>
>>         /*
>>          * TX falling edge PCLK is mandatory because the RX SLIC side works in this way
>>          */
>>         writel( CCSR_SSI_STCR_TXBIT0 /* LSB Aligned */
>>               | CCSR_SSI_STCR_TFEN0  /* Enable TX FIFO0 */
>>               | CCSR_SSI_STCR_TSCKP  /* Transmit Clock Polarity - Data Clocked out on falling edge */
>>               | CCSR_SSI_STCR_TFDIR  /* Transmit Frame Direction Internal - generated internally */
>>               | CCSR_SSI_STCR_TXDIR, /* Transmit Clock Direction Internal - generated internally */
>>             &ssi->stcr);
>>
>>     srcr = readl(&ssi->srcr);
>>
>>         /*
>>          * clear out RFDIR and RXDIR because the clock is synchronous
>>          */
>>     srcr &= ~(CCSR_SSI_SRCR_RFDIR | CCSR_SSI_SRCR_RXDIR);
>>
>>         srcr |= CCSR_SSI_SRCR_RXBIT0 /* LSB Aligned */
>>              |  CCSR_SSI_SRCR_RFEN0  /* Enable RX FIFO0 */
>>              |  CCSR_SSI_SRCR_RSCKP  /* Receive Clock Polarity - Data latched on rising edge */
>>             ;
>>
>>     writel(srcr, &ssi->srcr);
>>
>>         /* do not service the isr yet */
>>         writel(0, &ssi->sier);
>>
>>         /*
>>          * Set the watermark for transmit FIFI 0 and receive FIFO 0. We
>>          * don't use FIFO 1.  We program the transmit water to signal a
>>          * DMA transfer if there are only two (or fewer) elements left
>>          * in the FIFO.
>>          */
>>
>>        /*
>>         * tdm_real_slots is 2 because mask all except first 2 slots
>>         * our buffer is 2 slots * 8 bytes each, so set watermarks to a multiple of it
>>         * 8 words in our case
>>         */
>>
>>         wm = ssi_private->tdm_real_slots * 4; //ssi_private->use_dma ? ssi_private->fifo_depth - 2 :
>> ssi_private->fifo_depth;
>>
>>         writel(CCSR_SSI_SFCSR_TFWM0(wm) |
>>                CCSR_SSI_SFCSR_RFWM0(wm) |
>>                CCSR_SSI_SFCSR_TFWM1(wm) |
>>                CCSR_SSI_SFCSR_RFWM1(wm),
>>                &ssi->sfcsr);
>>
>>         /* enable one FIFO */
>>         write_ssi_mask(&ssi->srcr, CCSR_SSI_SRCR_RFEN1, 0);
>>         write_ssi_mask(&ssi->stcr, CCSR_SSI_STCR_TFEN1, 0);
>>
>>         /* disable SSI two-channel mode operation */
>>         write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_TCH_EN, 0);
>>
>>         /*
>>          * We keep the SSI disabled because if we enable it, then the
>>          * DMA controller will start.  It's not supposed to start until
>>          * the SCR.TE (or SCR.RE) bit is set, but it does anyway.  The
>>          * DMA controller will transfer one "BWC" of data (i.e. the
>>          * amount of data that the MR.BWC bits are set to).  The reason
>>          * this is bad is because at this point, the PCM driver has not
>>          * finished initializing the DMA controller.
>>          */
>>
>>         /* Set default slot number -- 32 in our case */
>>         write_ssi_mask(&ssi->stccr, CCSR_SSI_SxCCR_DC_MASK,
>>             CCSR_SSI_SxCCR_DC(ssi_private->tdm_slots));
>>         write_ssi_mask(&ssi->srccr, CCSR_SSI_SxCCR_DC_MASK,
>>             CCSR_SSI_SxCCR_DC(ssi_private->tdm_slots));
>>
>>         /* Set default word length -- 8 bits */
>>         write_ssi_mask(&ssi->stccr, CCSR_SSI_SxCCR_WL_MASK,
>>             CCSR_SSI_SxCCR_WL(ssi_private->tdm_word_size));
>>         write_ssi_mask(&ssi->srccr, CCSR_SSI_SxCCR_WL_MASK,
>>             CCSR_SSI_SxCCR_WL(ssi_private->tdm_word_size));
>>
>>         /* enable the SSI */
>>         write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_SSIEN, CCSR_SSI_SCR_SSIEN);
>>
>>         /*
>>          * we are interested only at first 2 slots
>>          */
>>         writel(~ssi_private->tdm_slots_enabled, &ssi->stmsk);
>>         writel(~ssi_private->tdm_slots_enabled, &ssi->srmsk);
>>
>>        return 0;
>> }
>>
>> SSI clock calculated and then enabled. Both TX and RX DMA channel are requested in the probe() function as below.
>> and the corresponding TX and RX SDMA event in DTS are using the default from imx6sx.dtsi:
>>
>>             slave_config.direction = DMA_MEM_TO_DEV;
>>             slave_config.dst_addr = ssi_private->ssi_phys + offsetof(struct ccsr_ssi, stx0);
>>             slave_config.dst_addr_width = width;
>>             slave_config.dst_maxburst = ssi_private->tdm_real_slots * 4;
>>             ret = dmaengine_slave_config(ssi_private->tx_chan, &slave_config);
>>
>>             ssi_private->rx_chan = dma_request_slave_channel_reason(&pdev->dev, "rx");
>>             slave_config.direction = DMA_DEV_TO_MEM;
>>             slave_config.src_addr = ssi_private->ssi_phys + offsetof(struct ccsr_ssi, srx0);
>>             slave_config.src_addr_width = width;
>>             slave_config.src_maxburst = ssi_private->tdm_real_slots * 4;
>>             ret = dmaengine_slave_config(ssi_private->rx_chan, &slave_config);
>>
>> and setup before RDMAE and TDMAE bits, like this:
>>
>>         ssi_private->tx_buf = dma_alloc_coherent(NULL, buffer_len,
>>                                         &ssi_private->tx_dmaaddr, GFP_KERNEL);
>>         desc = dmaengine_prep_dma_cyclic(ssi_private->tx_chan, ssi_private->tx_dmaaddr,
>>                 buffer_len, ssi_private->tdm_real_slots*4,
>>                 DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT);
>>
>>         desc->callback = dma_tx_callback;
>>         desc->callback_param = ssi_private;
>>
>>         printk("TX: prepare for the DMA.\n");
>>         dmaengine_submit(desc);
>>         dma_async_issue_pending(ssi_private->tx_chan);
>>
>>         ssi_private->rx_buf = dma_alloc_coherent(NULL, buffer_len,
>>                                         &ssi_private->rx_dmaaddr, GFP_KERNEL);
>>
>>         desc = dmaengine_prep_dma_cyclic(ssi_private->rx_chan, ssi_private->rx_dmaaddr,
>>                 buffer_len, ssi_private->tdm_real_slots*4,
>>                 DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT);
>>
>>         desc->callback = dma_rx_callback;
>>         desc->callback_param = ssi_private;
>>
>>         printk("RX: prepare for the DMA.\n");
>>         dmaengine_submit(desc);
>>         dma_async_issue_pending(ssi_private->rx_chan);
>>
>> Finally, the SSI's TX and RX parts are now enabled
>>
>>     scr = readl(&ssi->scr);
>>
>>     scr |= CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE;   /* enable both TX and RX SSI sections */
>>
>>     writel(scr, &ssi->scr);
>>
>> Finally the SIER si programmed as:
>>
>>    struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
>>     u32 sier = CCSR_SSI_SIER_RFF0_EN | CCSR_SSI_SIER_TFE0_EN;
>>
>>     /*
>>      * if DMA is enabled than allow SSI request for DMA transfers
>>      * otherwise normal interrupt requests
>>      */
>>
>>     if (ssi_private->use_dma>0)
>>     {
>>       sier |= CCSR_SSI_SIER_RDMAE | CCSR_SSI_SIER_TDMAE;
>>     }
>>
>>     if (ssi_private->use_dma>1 || !ssi_private->use_dma)
>>     {
>>       sier |= CCSR_SSI_SIER_RIE | CCSR_SSI_SIER_TIE;
>>     }
>>
>>     sier &= ~(CCSR_SSI_SIER_TDE1_EN | CCSR_SSI_SIER_TFE1_EN |
>>               CCSR_SSI_SIER_TFE0_EN | CCSR_SSI_SIER_TDE0_EN);
>>
>>     writel(sier, &ssi->sier);
>>
>> At this time I should see the DMA callbacks called every burst_size words. This behaviour
>> doesn't really happen as I wish because I can see from a proc file that such callbacks
>> are called from 1 to 20000 times and then anymore. This is also confirmed by the fact that
>> the interrupt 34 (sdma) doesn't increase anymore but matches my internal counters collected
>> within my callbacks. Here is what I can inspect from the data I have collected:
>>
>> root@voneus-domus-imx6sx:~# cat /proc/domus_ssi_stats
>> SSI TDM Info:
>>         PLL clk=66000000
>>         SSI baudclk=49152000
>>         ssi_phy=0x02028000
>>         irq=78
>>         fifo_depth=15 <---- this is what is read from DTS but not as watermark
>>         tdm_frame_rate=8000
>>         tdm_slots=32 (real 2)
>>         tdm_word_size=8
>>         tdm_slots_enabled=00000000000000000000000000000011
>>         clk_frequency=2048000
>>         clock_running=yes
>>         DMA=yes
>>         Dual FIFO=no
>>         RX DMA frame count=17121
>>         RX DMA addr=0x9c692000
>>         RX DMA buffer len=16
>>         TX DMA frame count=17121
>>         TX DMA addr=0x9c4aa000
>>         TX DMA buffer len=16
>>
>> SSI Registers:
>>         ssi_scr=0x0000009f
>>         ssi_sier=0x00500004
>>         ssi_stcr=0x000002e8
>>         ssi_srcr=0x00000288
>>         ssi_stccr=0x00007f0b
>>         ssi_srccr=0x00007f0b
>>         ssi_sfcsr=0x0088f088
>>         ssi_stmsk=0xfffffffc
>>         ssi_srmsk=0xfffffffc
>>
>> Cheers,
>> Roberto Fichera.
>
>
> And here's Nicolin's reply:
>
> On Fri, Oct 30, 2015 at 12:42:53PM +0100, Roberto Fichera wrote:
>
>
>>         /*
>>          * Set the watermark for transmit FIFI 0 and receive FIFO 0. We
>>          * don't use FIFO 1.  We program the transmit water to signal a
>>          * DMA transfer if there are only two (or fewer) elements left
>>          * in the FIFO.
>>          */
>> SSI clock calculated and then enabled. Both TX and RX DMA channel are requested in the probe() function as below.
>> and the corresponding TX and RX SDMA event in DTS are using the default from imx6sx.dtsi:
> Since you are using single FIFO configuration, which SDMA script
> are you using? This should reflects in the Device Tree. As far as
> I learned, FSL 3.14 is using number 22 for SSIs which is the one
> for Dual FIFO Mode.

No! Currently is 1. Here the Freescale's v3.14.28 GA imx6sx.dtsi entry

                ssi1: ssi@02028000 {
                    compatible = "fsl,imx6sx-ssi", "fsl,imx21-ssi";
                    reg = <0x02028000 0x4000>;
                    interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
                    clocks = <&clks IMX6SX_CLK_SSI1_IPG>,
                         <&clks IMX6SX_CLK_SSI1>;
                    clock-names = "ipg", "baud";
                    dmas = <&sdma 37 1 0>, <&sdma 38 1 0>;
                    dma-names = "rx", "tx";
                    status = "disabled";
                };

>
>> At this time I should see the DMA callbacks called every burst_size words. This behaviour
>> doesn't really happen as I wish because I can see from a proc file that such callbacks
>> are called from 1 to 20000 times and then anymore. This is also confirmed by the fact that
>> the interrupt 34 (sdma) doesn't increase anymore but matches my internal counters collected
>> within my callbacks. Here is what I can inspect from the data I have collected:
> Just for clarification, the behaviour doesn't happen as you wish
> is just the DMA stopped? I remember you also mentioned bit clock
> has stopped as you can check the clock status from the Codec chip.

Sorry, maybe I've used a wrong sentence.
All clocks to SLIC are currently ok, checked with a logical analyser and
both are working as expected.

>
>> SSI Registers:
>>         ssi_sfcsr=0x0088f088
> At this point you have data in RxFIFO and get empty in TxFIFO, so
> the DMA requests from both side should be issued. If the DMA stops
> as you described, you must check those two channels from the SDMA
> side by dumping SDMAARM_STOP_STAT, SDMAARM_HSTART, SDMAARM_EVTOVR,
> SDMAARM_EVTPEND, SDMAARM_EVTERR, SDMAARM_DSPOVR and SDMAARM_HOSTOVR
> registers.
Ok! I will do! Should I do within the SDMA isr or do you prefer another
place?

> Overall, I don't see an obvious defect from you SSI side, but you
> may also try to toggle TDMAE and RDMAE at the point that callback
> stops -- re-raise the DMA requests by disabling and enabling TDMAE
> and RDMAE again and see if it works. I think either something did
> intervene register controls of SDMA or SSI, 

I will try this one.

> or SDMA have missed the request signals from SSI.

This is my current thought. However since the SSI is not operating at so
high
rate and the Cabel's problem seems going to a solution then I think
there is something
else I'm missing.

> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel@alsa-project.org
> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: fsl_ssi.c: Roberto's problem: ssi hangs after some number of samples
  2015-10-31  9:16 ` Roberto Fichera
@ 2015-11-01 20:31   ` Fabio Estevam
  2015-11-02  9:57     ` Roberto Fichera
  2015-11-02 17:51   ` Roberto Fichera
  2015-11-03 21:26   ` Caleb Crome
  2 siblings, 1 reply; 33+ messages in thread
From: Fabio Estevam @ 2015-11-01 20:31 UTC (permalink / raw)
  To: Roberto Fichera
  Cc: Fabio Estevam, alsa-devel, Shengjiu Wang, Caleb Crome,
	Nicolin Chen, arnaud.mouiche, Markus Pargmann, shawn.guo

Hi Roberto,

On Sat, Oct 31, 2015 at 7:16 AM, Roberto Fichera <kernel@tekno-soft.it> wrote:

>> Since you are using single FIFO configuration, which SDMA script
>> are you using? This should reflects in the Device Tree. As far as
>> I learned, FSL 3.14 is using number 22 for SSIs which is the one
>> for Dual FIFO Mode.
>
> No! Currently is 1. Here the Freescale's v3.14.28 GA imx6sx.dtsi entry
>
>                 ssi1: ssi@02028000 {
>                     compatible = "fsl,imx6sx-ssi", "fsl,imx21-ssi";
>                     reg = <0x02028000 0x4000>;
>                     interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
>                     clocks = <&clks IMX6SX_CLK_SSI1_IPG>,
>                          <&clks IMX6SX_CLK_SSI1>;
>                     clock-names = "ipg", "baud";
>                     dmas = <&sdma 37 1 0>, <&sdma 38 1 0>;
>                     dma-names = "rx", "tx";
>                     status = "disabled";
>                 };

Take a look at imx_3.14.38_6ul_ga branch; It does use 22 in the dmas nodes:
http://git.freescale.com/git/cgit.cgi/imx/linux-2.6-imx.git/tree/arch/arm/boot/dts/imx6sx.dtsi?h=imx_3.14.38_6ul_ga

However, this list is only about mainline kernel, so please run all
your tests with mainline instead of FSL 3.14.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: fsl_ssi.c: Roberto's problem: ssi hangs after some number of samples
  2015-11-01 20:31   ` Fabio Estevam
@ 2015-11-02  9:57     ` Roberto Fichera
  0 siblings, 0 replies; 33+ messages in thread
From: Roberto Fichera @ 2015-11-02  9:57 UTC (permalink / raw)
  To: Fabio Estevam
  Cc: Fabio Estevam, alsa-devel, Shengjiu Wang, Caleb Crome,
	Nicolin Chen, arnaud.mouiche, Markus Pargmann, shawn.guo

On 11/01/2015 09:31 PM, Fabio Estevam wrote:

Hi Fabio,

> Hi Roberto,
>
> On Sat, Oct 31, 2015 at 7:16 AM, Roberto Fichera <kernel@tekno-soft.it> wrote:
>
>>> Since you are using single FIFO configuration, which SDMA script
>>> are you using? This should reflects in the Device Tree. As far as
>>> I learned, FSL 3.14 is using number 22 for SSIs which is the one
>>> for Dual FIFO Mode.
>> No! Currently is 1. Here the Freescale's v3.14.28 GA imx6sx.dtsi entry
>>
>>                 ssi1: ssi@02028000 {
>>                     compatible = "fsl,imx6sx-ssi", "fsl,imx21-ssi";
>>                     reg = <0x02028000 0x4000>;
>>                     interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
>>                     clocks = <&clks IMX6SX_CLK_SSI1_IPG>,
>>                          <&clks IMX6SX_CLK_SSI1>;
>>                     clock-names = "ipg", "baud";
>>                     dmas = <&sdma 37 1 0>, <&sdma 38 1 0>;
>>                     dma-names = "rx", "tx";
>>                     status = "disabled";
>>                 };
> Take a look at imx_3.14.38_6ul_ga branch; It does use 22 in the dmas nodes:
> http://git.freescale.com/git/cgit.cgi/imx/linux-2.6-imx.git/tree/arch/arm/boot/dts/imx6sx.dtsi?h=imx_3.14.38_6ul_ga
>
> However, this list is only about mainline kernel, so please run all
> your tests with mainline instead of FSL 3.14.
>

Ok! I'm doing that right now.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: fsl_ssi.c: Roberto's problem: ssi hangs after some number of samples
  2015-10-31  9:16 ` Roberto Fichera
  2015-11-01 20:31   ` Fabio Estevam
@ 2015-11-02 17:51   ` Roberto Fichera
  2015-11-02 18:03     ` Roberto Fichera
  2015-11-03 21:26   ` Caleb Crome
  2 siblings, 1 reply; 33+ messages in thread
From: Roberto Fichera @ 2015-11-02 17:51 UTC (permalink / raw)
  To: Caleb Crome
  Cc: Fabio Estevam, alsa-devel, Shengjiu Wang, Nicolin Chen,
	arnaud.mouiche, Markus Pargmann, shawn.guo, Fabio Estevam

On 10/31/2015 10:16 AM, Roberto Fichera wrote:
> And here's Nicolin's reply: On Fri, Oct 30, 2015 at 12:42:53PM +0100, Roberto Fichera wrote:
>>>         /*
>>>          * Set the watermark for transmit FIFI 0 and receive FIFO 0. We
>>>          * don't use FIFO 1.  We program the transmit water to signal a
>>>          * DMA transfer if there are only two (or fewer) elements left
>>>          * in the FIFO.
>>>          */
>>> SSI clock calculated and then enabled. Both TX and RX DMA channel are requested in the probe() function as below.
>>> and the corresponding TX and RX SDMA event in DTS are using the default from imx6sx.dtsi:
>> Since you are using single FIFO configuration, which SDMA script
>> are you using? This should reflects in the Device Tree. As far as
>> I learned, FSL 3.14 is using number 22 for SSIs which is the one
>> for Dual FIFO Mode.
> No! Currently is 1. Here the Freescale's v3.14.28 GA imx6sx.dtsi entry
>
>                 ssi1: ssi@02028000 {
>                     compatible = "fsl,imx6sx-ssi", "fsl,imx21-ssi";
>                     reg = <0x02028000 0x4000>;
>                     interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
>                     clocks = <&clks IMX6SX_CLK_SSI1_IPG>,
>                          <&clks IMX6SX_CLK_SSI1>;
>                     clock-names = "ipg", "baud";
>                     dmas = <&sdma 37 1 0>, <&sdma 38 1 0>;
>                     dma-names = "rx", "tx";
>                     status = "disabled";
>                 };
>
>>> At this time I should see the DMA callbacks called every burst_size words. This behaviour
>>> doesn't really happen as I wish because I can see from a proc file that such callbacks
>>> are called from 1 to 20000 times and then anymore. This is also confirmed by the fact that
>>> the interrupt 34 (sdma) doesn't increase anymore but matches my internal counters collected
>>> within my callbacks. Here is what I can inspect from the data I have collected:
>> Just for clarification, the behaviour doesn't happen as you wish
>> is just the DMA stopped? I remember you also mentioned bit clock
>> has stopped as you can check the clock status from the Codec chip.
> Sorry, maybe I've used a wrong sentence.
> All clocks to SLIC are currently ok, checked with a logical analyser and
> both are working as expected.
>
>>> SSI Registers:
>>>         ssi_sfcsr=0x0088f088
>> At this point you have data in RxFIFO and get empty in TxFIFO, so
>> the DMA requests from both side should be issued. If the DMA stops
>> as you described, you must check those two channels from the SDMA
>> side by dumping SDMAARM_STOP_STAT, SDMAARM_HSTART, SDMAARM_EVTOVR,
>> SDMAARM_EVTPEND, SDMAARM_EVTERR, SDMAARM_DSPOVR and SDMAARM_HOSTOVR
>> registers.
> Ok! I will do! Should I do within the SDMA isr or do you prefer another
> place?

Below there is both SSI and SDMA status as soon as SDMA stops operating, I've also moved all
code to kernel v4.3 just published this morning:

root@voneus-domus-imx6sx:~# cat /proc/domus_ssi_stats
SSI TDM Info:
        PLL clk=66000000
        SSI baudclk=49152000
        ssi_phy=0x02028000
        irq=21
        fifo_depth=8
        tdm_frame_rate=8000
        tdm_slots=32 (real 2)
        tdm_word_size=8
        tdm_slots_enabled=00000000000000000000000000000011
        clk_frequency=2048000
        clock_running=yes
        DMA=yes
        Dual FIFO=no
        RX DMA frame count=33758
        RX DMA addr=0x9edad000
        RX DMA buffer len=16
        TX DMA frame count=33758
        TX DMA addr=0x9ed7f000
        TX DMA buffer len=16

SSI Registers:
        ssi_scr=0x0000009f
        ssi_sier=0x00500004
        ssi_stcr=0x000002e8
        ssi_srcr=0x00000288
        ssi_stccr=0x00007f0b
        ssi_srccr=0x00007f0b
        ssi_sfcsr=0x0088f088
        ssi_stmsk=0xfffffffc
        ssi_srmsk=0xfffffffc

SSI SISR Register:
        rfrc=0
        tfrc=0
        cmdau=0
        cmddu=0
        rxt=0
        rdr1=0
        rdr0=0
        tde1=0
        tde0=0
        roe1=0
        roe0=0
        tue1=0
        tue0=0
        tfs=0
        rfs=0
        tls=0
        rls=0
        rff1=0
        rff0=0
        tfe1=0
        tfe0=0

SDMA RX channel:
SDMA channel 4 status
        SDMA_H_STATSTOP=0x00000000
        SDMA_H_START=0x00000000
        SDMA_H_EVTOVR=0x00000001
        SDMA_H_EVTPEND=0x0000001a
        SDMA_H_EVTERR=0x00000018
        SDMA_H_DSPOVR=0xffffffff
        SDMA_H_HOSTOVR=0x00000000

SDMA TX channel:
SDMA channel 3 status
        SDMA_H_STATSTOP=0x00000000
        SDMA_H_START=0x00000000
        SDMA_H_EVTOVR=0x00000001
        SDMA_H_EVTPEND=0x0000001a
        SDMA_H_EVTERR=0x00000000
        SDMA_H_DSPOVR=0xffffffff
        SDMA_H_HOSTOVR=0x00000000


>
>> Overall, I don't see an obvious defect from you SSI side, but you
>> may also try to toggle TDMAE and RDMAE at the point that callback
>> stops -- re-raise the DMA requests by disabling and enabling TDMAE
>> and RDMAE again and see if it works. I think either something did
>> intervene register controls of SDMA or SSI, 
> I will try this one.

I will go over this tomorrow morning.

>
>> or SDMA have missed the request signals from SSI.
> This is my current thought. However since the SSI is not operating at so
> high
> rate and the Cabel's problem seems going to a solution then I think
> there is something
> else I'm missing.
>
>> _______________________________________________
>> Alsa-devel mailing list
>> Alsa-devel@alsa-project.org
>> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel@alsa-project.org
> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
>

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: fsl_ssi.c: Roberto's problem: ssi hangs after some number of samples
  2015-11-02 17:51   ` Roberto Fichera
@ 2015-11-02 18:03     ` Roberto Fichera
  2015-11-03  0:56       ` Caleb Crome
  0 siblings, 1 reply; 33+ messages in thread
From: Roberto Fichera @ 2015-11-02 18:03 UTC (permalink / raw)
  To: Caleb Crome
  Cc: Fabio Estevam, alsa-devel, Shengjiu Wang, Nicolin Chen,
	arnaud.mouiche, Markus Pargmann, shawn.guo, Fabio Estevam

On 11/02/2015 06:51 PM, Roberto Fichera wrote:
>>> >> Overall, I don't see an obvious defect from you SSI side, but you
>>> >> may also try to toggle TDMAE and RDMAE at the point that callback
>>> >> stops -- re-raise the DMA requests by disabling and enabling TDMAE
>>> >> and RDMAE again and see if it works. I think either something did
>>> >> intervene register controls of SDMA or SSI, 
>> > I will try this one.
> I will go over this tomorrow morning.
>

I've tried it just now but doesn't work at all! I'm getting only 2 sdma transfers.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: fsl_ssi.c: Roberto's problem: ssi hangs after some number of samples
  2015-11-02 18:03     ` Roberto Fichera
@ 2015-11-03  0:56       ` Caleb Crome
  2015-11-03  8:21         ` Roberto Fichera
  0 siblings, 1 reply; 33+ messages in thread
From: Caleb Crome @ 2015-11-03  0:56 UTC (permalink / raw)
  To: Roberto Fichera
  Cc: Fabio Estevam, alsa-devel, Shengjiu Wang, Nicolin Chen,
	arnaud.mouiche, Markus Pargmann, shawn.guo, Fabio Estevam

On Mon, Nov 2, 2015 at 10:03 AM, Roberto Fichera <kernel@tekno-soft.it> wrote:
> On 11/02/2015 06:51 PM, Roberto Fichera wrote:
>>>> >> Overall, I don't see an obvious defect from you SSI side, but you
>>>> >> may also try to toggle TDMAE and RDMAE at the point that callback
>>>> >> stops -- re-raise the DMA requests by disabling and enabling TDMAE
>>>> >> and RDMAE again and see if it works. I think either something did
>>>> >> intervene register controls of SDMA or SSI,
>>> > I will try this one.
>> I will go over this tomorrow morning.
>>
>
> I've tried it just now but doesn't work at all! I'm getting only 2 sdma transfers.

Heh, now I'm getting perhaps a similar issue -- transfers just stop
for no good reason.

I can use aplay all day long, and the transfers work great.  Even
arecord + aplay together seem to work fine.

However, when I use my portaudio based ramp checker, it runs from
between 1 frame and several thousand, then the callbacks stop.  I
don't know if this is a portaudio problem or an alsa problem -- i
don't think I've seen the issue outside portaudio.

Jackd seems to run okay too (I'm running an overnight full duplex test now).

roberto, what user space library are you using?  Alsa directly, or
portaudio, or something else? it looks like your data rate is quite
manageable, right?  8kHz, 8 slots, 8 bits?  For me, it's a little
better at 16kHz than 48kHz, but still just quits working after a
while.

What's your experience of play vs. record, vs. full duplex?


-Caleb

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: fsl_ssi.c: Roberto's problem: ssi hangs after some number of samples
  2015-11-03  0:56       ` Caleb Crome
@ 2015-11-03  8:21         ` Roberto Fichera
  0 siblings, 0 replies; 33+ messages in thread
From: Roberto Fichera @ 2015-11-03  8:21 UTC (permalink / raw)
  To: Caleb Crome
  Cc: Fabio Estevam, alsa-devel, Shengjiu Wang, Nicolin Chen,
	arnaud.mouiche, Markus Pargmann, shawn.guo, Fabio Estevam

On 11/03/2015 01:56 AM, Caleb Crome wrote:
> On Mon, Nov 2, 2015 at 10:03 AM, Roberto Fichera <kernel@tekno-soft.it> wrote:
>> On 11/02/2015 06:51 PM, Roberto Fichera wrote:
>>>>>>> Overall, I don't see an obvious defect from you SSI side, but you
>>>>>>> may also try to toggle TDMAE and RDMAE at the point that callback
>>>>>>> stops -- re-raise the DMA requests by disabling and enabling TDMAE
>>>>>>> and RDMAE again and see if it works. I think either something did
>>>>>>> intervene register controls of SDMA or SSI,
>>>>> I will try this one.
>>> I will go over this tomorrow morning.
>>>
>> I've tried it just now but doesn't work at all! I'm getting only 2 sdma transfers.
> Heh, now I'm getting perhaps a similar issue -- transfers just stop
> for no good reason.
>
> I can use aplay all day long, and the transfers work great.  Even
> arecord + aplay together seem to work fine.
>
> However, when I use my portaudio based ramp checker, it runs from
> between 1 frame and several thousand, then the callbacks stop.  I
> don't know if this is a portaudio problem or an alsa problem -- i
> don't think I've seen the issue outside portaudio.
>
> Jackd seems to run okay too (I'm running an overnight full duplex test now).
>
> roberto, what user space library are you using?  Alsa directly, or
> portaudio, or something else? 

All is in kernel space, and as I've already said it's dahdi driver for a voip app.
The starting point I've used is fsl_ssi.c. I've removed most of the code not
related to TDM. Then I've added my dma support to move samples from TDM
to a dahdi audio sample buffer.
So it's supposed to be a very skinny TDM driver for SSI in normal and synch
mode.

> it looks like your data rate is quite
> manageable, right?  8kHz, 8 slots, 8 bits?  For me, it's a little
> better at 16kHz than 48kHz, but still just quits working after a
> while.

BCLK@2048KHz, FSYNC@8KHz, 32 slots at 8 bits but I'm masking all
except the first 2 I need.

> What's your experience of play vs. record, vs. full duplex?

Channels should be full duplex, and the samples has to go in dahdi buffer
finally used by asterisk as audio channel.

I'm currently thinking if would be better to write my driver as plain audio codec.
This means that I'll have to write my dahdi driver on top of either PCM or SND
framework, all within kernel space. But I guess this will over-complicate the things
compared to a straight TDM byte sequence, considering also that I'll have to
learn the sound API.

>
>
> -Caleb
>

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: fsl_ssi.c: Roberto's problem: ssi hangs after some number of samples
  2015-10-31  9:16 ` Roberto Fichera
  2015-11-01 20:31   ` Fabio Estevam
  2015-11-02 17:51   ` Roberto Fichera
@ 2015-11-03 21:26   ` Caleb Crome
  2015-11-04 15:33     ` Roberto Fichera
  2 siblings, 1 reply; 33+ messages in thread
From: Caleb Crome @ 2015-11-03 21:26 UTC (permalink / raw)
  To: Roberto Fichera
  Cc: Fabio Estevam, alsa-devel, Shengjiu Wang, Nicolin Chen,
	arnaud.mouiche, Markus Pargmann, shawn.guo, Fabio Estevam

On Sat, Oct 31, 2015 at 2:16 AM, Roberto Fichera <kernel@tekno-soft.it> wrote:
> On 10/30/2015 07:01 PM, Caleb Crome wrote:
>> Hi All, is it okay of we split Roberto's problem from mine?  It's
>> getting difficult to track which response goes to which problem :-)
>>
>> I included Roberto's email, and Nicolin's reply below:
>>
>> So, this thread is for the hanging problem, the prehistory for this
>> thread is in, "fsl_ssi.c: Getting channel slips with fsl_ssi.c in TDM
>> (network) mode."
>
> That's fine! Thanks Calab!
>
>>
>> -Caleb
>>
>> On Fri, Oct 30, 2015 at 4:42 AM, Roberto Fichera <kernel@tekno-soft.it> wrote:
>>> On 10/30/2015 12:04 AM, Nicolin Chen wrote:
>>>> On Wed, Oct 28, 2015 at 09:11:39AM +0100, Roberto Fichera wrote:
>>>>
>>>>> I'm also having the same issue but employing SSI in TDM master mode against a SLIC Si32178
>>>>> using its PCM mode. PCLK is at 2048KHz, FSYNC is 8KHz slot length is 32 bits (SSI wants
>>>>> this since when in master mode) but valid data set to be 8bits in the SSI register.
>>>>> My Current situation is that I've a custom fsl_ssi.c driver to control the SSI in TDM master mode
>>>>> both PCLK and FSYNC works perfectly fine, the SLIC has a register that I can check via SPI for
>>>>> such purpose, I can see the clocking status from its side. The main problem I've is exactly the same
>>>>> Caleb is having, after a certain amount of SDMA transfers, roughly 1000 or so, everything stops
>>>>> without any apparent reason.
>>>> I will start to help you to figure out your problem. But it seems that
>>>> you are having a different issue here with clock generation. I don't
>>>> get why you said *same issue*. For double confirm, the the "everything
>>>> stops" mentioned, does it mean that clock from SSI stops?
>>>>
>>> Definitively yes! My problem is different than Caleb's one. Just to summarize the things.
>>> I've the SSI1 connected to a SiLabs SLIC Si32178 via AUDMUX6 padmux is below:
>>>
>>>         pinctrl_audmux_1: audmuxgrp-3 {
>>>             fsl,pins = <
>>>                 MX6SX_PAD_SD3_DATA1__AUDMUX_AUD6_TXC    0x130b0    /* PCLK */
>>>                 MX6SX_PAD_SD3_DATA2__AUDMUX_AUD6_TXFS   0x130b0    /* FSYNC */
>>>                 MX6SX_PAD_SD3_DATA0__AUDMUX_AUD6_RXD    0x130b0    /* DTX */
>>>                 MX6SX_PAD_SD3_DATA3__AUDMUX_AUD6_TXD    0x120b0    /* DRX */
>>>             >;
>>>         };
>>>
>>> The Si32178 is slave device so the SSI1 has to generate both BCLK and FSYNC. I've configured
>>> the AUDMUX as:
>>>
>>> int si3217x_audmux_config(unsigned int master, unsigned int slave)
>>> {
>>>   unsigned int ptcr, pdcr;
>>>
>>>   ptcr = IMX_AUDMUX_V2_PTCR_SYN |
>>>          IMX_AUDMUX_V2_PTCR_TFSDIR |
>>>          IMX_AUDMUX_V2_PTCR_TFSEL(master) |
>>>          IMX_AUDMUX_V2_PTCR_TCLKDIR |
>>>          IMX_AUDMUX_V2_PTCR_TCSEL(master);
>>>   pdcr = IMX_AUDMUX_V2_PDCR_RXDSEL(master);
>>>   si3217x_audmux_v2_configure_port(slave, ptcr, pdcr); /* configure internal port */
>>>
>>>   ptcr = IMX_AUDMUX_V2_PTCR_SYN;
>>>   pdcr = IMX_AUDMUX_V2_PDCR_RXDSEL(slave);
>>>   si3217x_audmux_v2_configure_port(master, ptcr, pdcr); /* configure external port */
>>>
>>>   return 0;
>>> }
>>>
>>> BCLK is 2048KHz, FSYNC@8KHz, frame is 32 slots at 8bits each. Looking at TXC and TXFS
>>> with a logical analyzer everything looks ok.
>>>
>>> The SSI is setup at beginning as:
>>>
>>>         unsigned long flags;
>>>         struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
>>>         u32 srcr;
>>>         u8 wm;
>>>
>>>         clk_prepare_enable(ssi_private->clk);
>>>
>>>         /*
>>>          * Section 16.5 of the MPC8610 reference manual says that the
>>>          * SSI needs to be disabled before updating the registers we set
>>>          * here.
>>>          */
>>>         write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_SSIEN, 0);
>>>
>>>         /*
>>>          * Program the SSI into I2S Master Network Synchronous mode.
>>>          * Also enable the transmit and receive FIFO.
>>>          */
>>>         write_ssi_mask(&ssi->scr,
>>>             CCSR_SSI_SCR_I2S_MODE_MASK | CCSR_SSI_SCR_SYN,
>>>             CCSR_SSI_SCR_I2S_MODE_NORMAL
>>>             | CCSR_SSI_SCR_SYN | CCSR_SSI_SCR_NET
>>>             | CCSR_SSI_SCR_SYS_CLK_EN);
>>>
>>>         /*
>>>          * TX falling edge PCLK is mandatory because the RX SLIC side works in this way
>>>          */
>>>         writel( CCSR_SSI_STCR_TXBIT0 /* LSB Aligned */
>>>               | CCSR_SSI_STCR_TFEN0  /* Enable TX FIFO0 */
>>>               | CCSR_SSI_STCR_TSCKP  /* Transmit Clock Polarity - Data Clocked out on falling edge */
>>>               | CCSR_SSI_STCR_TFDIR  /* Transmit Frame Direction Internal - generated internally */
>>>               | CCSR_SSI_STCR_TXDIR, /* Transmit Clock Direction Internal - generated internally */
>>>             &ssi->stcr);
>>>
>>>     srcr = readl(&ssi->srcr);
>>>
>>>         /*
>>>          * clear out RFDIR and RXDIR because the clock is synchronous
>>>          */
>>>     srcr &= ~(CCSR_SSI_SRCR_RFDIR | CCSR_SSI_SRCR_RXDIR);
>>>
>>>         srcr |= CCSR_SSI_SRCR_RXBIT0 /* LSB Aligned */
>>>              |  CCSR_SSI_SRCR_RFEN0  /* Enable RX FIFO0 */
>>>              |  CCSR_SSI_SRCR_RSCKP  /* Receive Clock Polarity - Data latched on rising edge */
>>>             ;
>>>
>>>     writel(srcr, &ssi->srcr);
>>>
>>>         /* do not service the isr yet */
>>>         writel(0, &ssi->sier);
>>>
>>>         /*
>>>          * Set the watermark for transmit FIFI 0 and receive FIFO 0. We
>>>          * don't use FIFO 1.  We program the transmit water to signal a
>>>          * DMA transfer if there are only two (or fewer) elements left
>>>          * in the FIFO.
>>>          */
>>>
>>>        /*
>>>         * tdm_real_slots is 2 because mask all except first 2 slots
>>>         * our buffer is 2 slots * 8 bytes each, so set watermarks to a multiple of it
>>>         * 8 words in our case
>>>         */
>>>
>>>         wm = ssi_private->tdm_real_slots * 4; //ssi_private->use_dma ? ssi_private->fifo_depth - 2 :
>>> ssi_private->fifo_depth;
>>>
>>>         writel(CCSR_SSI_SFCSR_TFWM0(wm) |
>>>                CCSR_SSI_SFCSR_RFWM0(wm) |
>>>                CCSR_SSI_SFCSR_TFWM1(wm) |
>>>                CCSR_SSI_SFCSR_RFWM1(wm),
>>>                &ssi->sfcsr);
>>>
>>>         /* enable one FIFO */
>>>         write_ssi_mask(&ssi->srcr, CCSR_SSI_SRCR_RFEN1, 0);
>>>         write_ssi_mask(&ssi->stcr, CCSR_SSI_STCR_TFEN1, 0);
>>>
>>>         /* disable SSI two-channel mode operation */
>>>         write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_TCH_EN, 0);
>>>
>>>         /*
>>>          * We keep the SSI disabled because if we enable it, then the
>>>          * DMA controller will start.  It's not supposed to start until
>>>          * the SCR.TE (or SCR.RE) bit is set, but it does anyway.  The
>>>          * DMA controller will transfer one "BWC" of data (i.e. the
>>>          * amount of data that the MR.BWC bits are set to).  The reason
>>>          * this is bad is because at this point, the PCM driver has not
>>>          * finished initializing the DMA controller.
>>>          */
>>>
>>>         /* Set default slot number -- 32 in our case */
>>>         write_ssi_mask(&ssi->stccr, CCSR_SSI_SxCCR_DC_MASK,
>>>             CCSR_SSI_SxCCR_DC(ssi_private->tdm_slots));
>>>         write_ssi_mask(&ssi->srccr, CCSR_SSI_SxCCR_DC_MASK,
>>>             CCSR_SSI_SxCCR_DC(ssi_private->tdm_slots));
>>>
>>>         /* Set default word length -- 8 bits */
>>>         write_ssi_mask(&ssi->stccr, CCSR_SSI_SxCCR_WL_MASK,
>>>             CCSR_SSI_SxCCR_WL(ssi_private->tdm_word_size));
>>>         write_ssi_mask(&ssi->srccr, CCSR_SSI_SxCCR_WL_MASK,
>>>             CCSR_SSI_SxCCR_WL(ssi_private->tdm_word_size));
>>>
>>>         /* enable the SSI */
>>>         write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_SSIEN, CCSR_SSI_SCR_SSIEN);
>>>
>>>         /*
>>>          * we are interested only at first 2 slots
>>>          */
>>>         writel(~ssi_private->tdm_slots_enabled, &ssi->stmsk);
>>>         writel(~ssi_private->tdm_slots_enabled, &ssi->srmsk);
>>>
>>>        return 0;
>>> }
>>>
>>> SSI clock calculated and then enabled. Both TX and RX DMA channel are requested in the probe() function as below.
>>> and the corresponding TX and RX SDMA event in DTS are using the default from imx6sx.dtsi:
>>>
>>>             slave_config.direction = DMA_MEM_TO_DEV;
>>>             slave_config.dst_addr = ssi_private->ssi_phys + offsetof(struct ccsr_ssi, stx0);
>>>             slave_config.dst_addr_width = width;
>>>             slave_config.dst_maxburst = ssi_private->tdm_real_slots * 4;
>>>             ret = dmaengine_slave_config(ssi_private->tx_chan, &slave_config);
>>>
>>>             ssi_private->rx_chan = dma_request_slave_channel_reason(&pdev->dev, "rx");
>>>             slave_config.direction = DMA_DEV_TO_MEM;
>>>             slave_config.src_addr = ssi_private->ssi_phys + offsetof(struct ccsr_ssi, srx0);
>>>             slave_config.src_addr_width = width;
>>>             slave_config.src_maxburst = ssi_private->tdm_real_slots * 4;
>>>             ret = dmaengine_slave_config(ssi_private->rx_chan, &slave_config);
>>>
>>> and setup before RDMAE and TDMAE bits, like this:
>>>
>>>         ssi_private->tx_buf = dma_alloc_coherent(NULL, buffer_len,
>>>                                         &ssi_private->tx_dmaaddr, GFP_KERNEL);
>>>         desc = dmaengine_prep_dma_cyclic(ssi_private->tx_chan, ssi_private->tx_dmaaddr,
>>>                 buffer_len, ssi_private->tdm_real_slots*4,
>>>                 DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT);
>>>
>>>         desc->callback = dma_tx_callback;
>>>         desc->callback_param = ssi_private;
>>>
>>>         printk("TX: prepare for the DMA.\n");
>>>         dmaengine_submit(desc);
>>>         dma_async_issue_pending(ssi_private->tx_chan);
>>>
>>>         ssi_private->rx_buf = dma_alloc_coherent(NULL, buffer_len,
>>>                                         &ssi_private->rx_dmaaddr, GFP_KERNEL);
>>>
>>>         desc = dmaengine_prep_dma_cyclic(ssi_private->rx_chan, ssi_private->rx_dmaaddr,
>>>                 buffer_len, ssi_private->tdm_real_slots*4,
>>>                 DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT);
>>>
>>>         desc->callback = dma_rx_callback;
>>>         desc->callback_param = ssi_private;
>>>
>>>         printk("RX: prepare for the DMA.\n");
>>>         dmaengine_submit(desc);
>>>         dma_async_issue_pending(ssi_private->rx_chan);
>>>
>>> Finally, the SSI's TX and RX parts are now enabled
>>>
>>>     scr = readl(&ssi->scr);
>>>
>>>     scr |= CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE;   /* enable both TX and RX SSI sections */
>>>
>>>     writel(scr, &ssi->scr);
>>>
>>> Finally the SIER si programmed as:
>>>
>>>    struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
>>>     u32 sier = CCSR_SSI_SIER_RFF0_EN | CCSR_SSI_SIER_TFE0_EN;
>>>
>>>     /*
>>>      * if DMA is enabled than allow SSI request for DMA transfers
>>>      * otherwise normal interrupt requests
>>>      */
>>>
>>>     if (ssi_private->use_dma>0)
>>>     {
>>>       sier |= CCSR_SSI_SIER_RDMAE | CCSR_SSI_SIER_TDMAE;
>>>     }
>>>
>>>     if (ssi_private->use_dma>1 || !ssi_private->use_dma)
>>>     {
>>>       sier |= CCSR_SSI_SIER_RIE | CCSR_SSI_SIER_TIE;
>>>     }
>>>
>>>     sier &= ~(CCSR_SSI_SIER_TDE1_EN | CCSR_SSI_SIER_TFE1_EN |
>>>               CCSR_SSI_SIER_TFE0_EN | CCSR_SSI_SIER_TDE0_EN);
>>>
>>>     writel(sier, &ssi->sier);
>>>
>>> At this time I should see the DMA callbacks called every burst_size words. This behaviour
>>> doesn't really happen as I wish because I can see from a proc file that such callbacks
>>> are called from 1 to 20000 times and then anymore. This is also confirmed by the fact that
>>> the interrupt 34 (sdma) doesn't increase anymore but matches my internal counters collected
>>> within my callbacks. Here is what I can inspect from the data I have collected:
>>>
>>> root@voneus-domus-imx6sx:~# cat /proc/domus_ssi_stats
>>> SSI TDM Info:
>>>         PLL clk=66000000
>>>         SSI baudclk=49152000
>>>         ssi_phy=0x02028000
>>>         irq=78
>>>         fifo_depth=15 <---- this is what is read from DTS but not as watermark
>>>         tdm_frame_rate=8000
>>>         tdm_slots=32 (real 2)
>>>         tdm_word_size=8
>>>         tdm_slots_enabled=00000000000000000000000000000011
>>>         clk_frequency=2048000
>>>         clock_running=yes
>>>         DMA=yes
>>>         Dual FIFO=no
>>>         RX DMA frame count=17121
>>>         RX DMA addr=0x9c692000
>>>         RX DMA buffer len=16
>>>         TX DMA frame count=17121
>>>         TX DMA addr=0x9c4aa000
>>>         TX DMA buffer len=16
>>>
>>> SSI Registers:
>>>         ssi_scr=0x0000009f
>>>         ssi_sier=0x00500004
>>>         ssi_stcr=0x000002e8
>>>         ssi_srcr=0x00000288
>>>         ssi_stccr=0x00007f0b
>>>         ssi_srccr=0x00007f0b
>>>         ssi_sfcsr=0x0088f088
>>>         ssi_stmsk=0xfffffffc
>>>         ssi_srmsk=0xfffffffc
>>>
>>> Cheers,
>>> Roberto Fichera.
>>
>>
>> And here's Nicolin's reply:
>>
>> On Fri, Oct 30, 2015 at 12:42:53PM +0100, Roberto Fichera wrote:
>>
>>
>>>         /*
>>>          * Set the watermark for transmit FIFI 0 and receive FIFO 0. We
>>>          * don't use FIFO 1.  We program the transmit water to signal a
>>>          * DMA transfer if there are only two (or fewer) elements left
>>>          * in the FIFO.
>>>          */
>>> SSI clock calculated and then enabled. Both TX and RX DMA channel are requested in the probe() function as below.
>>> and the corresponding TX and RX SDMA event in DTS are using the default from imx6sx.dtsi:
>> Since you are using single FIFO configuration, which SDMA script
>> are you using? This should reflects in the Device Tree. As far as
>> I learned, FSL 3.14 is using number 22 for SSIs which is the one
>> for Dual FIFO Mode.
>
> No! Currently is 1. Here the Freescale's v3.14.28 GA imx6sx.dtsi entry
>
>                 ssi1: ssi@02028000 {
>                     compatible = "fsl,imx6sx-ssi", "fsl,imx21-ssi";
>                     reg = <0x02028000 0x4000>;
>                     interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
>                     clocks = <&clks IMX6SX_CLK_SSI1_IPG>,
>                          <&clks IMX6SX_CLK_SSI1>;
>                     clock-names = "ipg", "baud";
>                     dmas = <&sdma 37 1 0>, <&sdma 38 1 0>;
>                     dma-names = "rx", "tx";
>                     status = "disabled";
>                 };
>
>>
>>> At this time I should see the DMA callbacks called every burst_size words. This behaviour
>>> doesn't really happen as I wish because I can see from a proc file that such callbacks
>>> are called from 1 to 20000 times and then anymore. This is also confirmed by the fact that
>>> the interrupt 34 (sdma) doesn't increase anymore but matches my internal counters collected
>>> within my callbacks. Here is what I can inspect from the data I have collected:
>> Just for clarification, the behaviour doesn't happen as you wish
>> is just the DMA stopped? I remember you also mentioned bit clock
>> has stopped as you can check the clock status from the Codec chip.
>
> Sorry, maybe I've used a wrong sentence.
> All clocks to SLIC are currently ok, checked with a logical analyser and
> both are working as expected.
>
>>
>>> SSI Registers:
>>>         ssi_sfcsr=0x0088f088
>> At this point you have data in RxFIFO and get empty in TxFIFO, so
>> the DMA requests from both side should be issued. If the DMA stops
>> as you described, you must check those two channels from the SDMA
>> side by dumping SDMAARM_STOP_STAT, SDMAARM_HSTART, SDMAARM_EVTOVR,
>> SDMAARM_EVTPEND, SDMAARM_EVTERR, SDMAARM_DSPOVR and SDMAARM_HOSTOVR
>> registers.
> Ok! I will do! Should I do within the SDMA isr or do you prefer another
> place?
>
>> Overall, I don't see an obvious defect from you SSI side, but you
>> may also try to toggle TDMAE and RDMAE at the point that callback
>> stops -- re-raise the DMA requests by disabling and enabling TDMAE
>> and RDMAE again and see if it works. I think either something did
>> intervene register controls of SDMA or SSI,
>
> I will try this one.
>
>> or SDMA have missed the request signals from SSI.
>
> This is my current thought. However since the SSI is not operating at so
> high
> rate and the Cabel's problem seems going to a solution then I think
> there is something
> else I'm missing.

Is it possible that the event type below in the reference manual
section 55.10.5 is happening?  It looks like the SDMA script is
supposed to deal with it.  Perhaps there's a bug in the script?

55.10.5 External DMA Requests Mirror (SDMACORE_EVENTS)
NOTE
This register is very useful in the case of DMA requests that are
active when a peripheral FIFO level is above the programmed
watermark. The activation of the DMA request (rising edge) is
detected by the SDMA logic and it can enable one or several
channels. One of the channels accesses the peripheral and reads
or writes a number of data that matches the watermark level
(for example, if the watermark is four words, the channel reads
or writes four words).
If the channel is effectively executed long after the DMA
request was received, reading or writing the watermark number
of data may not be sufficient to reset the DMA request (for
example, if the FIFO watermark is four and at the channel
execution it already contains nine pieces of data). This means
no new rising edge may be detected by the SDMA, although
there still remains transfers to perform. Therefore, if the
channel were terminated at that time, it would not be restarted,
causing potential overrun or underrun of the peripheral.
The proposed mechanism is for the channel to check this
register after it has performed the "watermark" number of
accesses to the peripheral. If the bit for the DMA request that
triggers this channel is set, it means there is still another
watermark number of data to transfer. This goes on until the bit
is cleared. The same script can be used for multiple channels
that require this behavior. The script can determine its channel
number from the CCR register and infer the corresponding
DMA request bit to check. It needs a reference table that is
coherent with the request-channel matrix that the ARM
platform programmed.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: fsl_ssi.c: Roberto's problem: ssi hangs after some number of samples
  2015-11-03 21:26   ` Caleb Crome
@ 2015-11-04 15:33     ` Roberto Fichera
  2015-11-04 16:53       ` Roberto Fichera
  2015-11-04 17:58       ` Nicolin Chen
  0 siblings, 2 replies; 33+ messages in thread
From: Roberto Fichera @ 2015-11-04 15:33 UTC (permalink / raw)
  To: Caleb Crome
  Cc: Fabio Estevam, alsa-devel, Shengjiu Wang, Nicolin Chen,
	arnaud.mouiche, Markus Pargmann, shawn.guo, Fabio Estevam

On 11/03/2015 10:26 PM, Caleb Crome wrote:
>>> or SDMA have missed the request signals from SSI.
>> This is my current thought. However since the SSI is not operating at so
>> high
>> rate and the Cabel's problem seems going to a solution then I think
>> there is something
>> else I'm missing.
> Is it possible that the event type below in the reference manual
> section 55.10.5 is happening?  It looks like the SDMA script is
> supposed to deal with it.  Perhaps there's a bug in the script?
>
> 55.10.5 External DMA Requests Mirror (SDMACORE_EVENTS)
> NOTE
> This register is very useful in the case of DMA requests that are
> active when a peripheral FIFO level is above the programmed
> watermark. The activation of the DMA request (rising edge) is
> detected by the SDMA logic and it can enable one or several
> channels. One of the channels accesses the peripheral and reads
> or writes a number of data that matches the watermark level
> (for example, if the watermark is four words, the channel reads
> or writes four words).
> If the channel is effectively executed long after the DMA
> request was received, reading or writing the watermark number
> of data may not be sufficient to reset the DMA request (for
> example, if the FIFO watermark is four and at the channel
> execution it already contains nine pieces of data). This means
> no new rising edge may be detected by the SDMA, although
> there still remains transfers to perform. Therefore, if the
> channel were terminated at that time, it would not be restarted,
> causing potential overrun or underrun of the peripheral.
> The proposed mechanism is for the channel to check this
> register after it has performed the "watermark" number of
> accesses to the peripheral. If the bit for the DMA request that
> triggers this channel is set, it means there is still another
> watermark number of data to transfer. This goes on until the bit
> is cleared. The same script can be used for multiple channels
> that require this behavior. The script can determine its channel
> number from the CCR register and infer the corresponding
> DMA request bit to check. It needs a reference table that is
> coherent with the request-channel matrix that the ARM
> platform programmed.
>

Maybe this is the cause! I've explored a bit what's going on with my DMA stall and
I've found that both RX and TX channels are getting an error, at least this is what
the EVTERR register is reporting. See the log below:

root@voneus-domus-imx6sx:~# cat /proc/domus_ssi_stats
SSI TDM Info:
        IPG clk=66000000
        SSI baudclk=8192000
        ssi_phy=0x02028000
        irq=21
        fifo_depth=10
        tdm_frame_rate=8000
        tdm_slots=32 (real 2)
        tdm_word_size=8
        tdm_slots_enabled=00000000000000000000000000000011
        clk_frequency=2048000
        clock_running=yes
        DMA=yes
        Dual FIFO=no
        *RX DMA frame count=36795*
        RX DMA addr=0x9ef0e000
        RX DMA buffer len=16
        *TX DMA frame count=36795*
        TX DMA addr=0x9ee49000
        TX DMA buffer len=16

SSI Registers:
        ssi_scr=0x0000109f
        ssi_sier=0x00500504
        ssi_stcr=0x000002e8
        ssi_srcr=0x00000288
        ssi_stccr=0x00007f01
        ssi_srccr=0x00007f01
        ssi_sfcsr=0x00aaf0aa
        ssi_stmsk=0xfffffffc
        ssi_srmsk=0xfffffffc

SDMA RX channel:
SDMA channel 4 status
        SDMA_H_STATSTOP=0x00000000
        SDMA_H_START=0x00000000
        SDMA_H_EVTOVR=0x00000001
        SDMA_H_EVTPEND=0x0000001a
        SDMA_H_EVTERR=0x00000000
        SDMA_H_DSPOVR=0xffffffff
        SDMA_H_HOSTOVR=0x00000000
        SDMA_H_INTR=0x00000000
        SDMA_H_INTRMSK=0x00000018
        SDMACORE_EVENTS=0x00000000
        SDMACORE_EVENTS2=0x00000000

SDMA EVTERR channel counters:
*        003 = 1**
**        004 = 1*

SDMA TX channel:
SDMA channel 3 status
        SDMA_H_STATSTOP=0x00000000
        SDMA_H_START=0x00000000
        SDMA_H_EVTOVR=0x00000001
        SDMA_H_EVTPEND=0x0000001a
        SDMA_H_EVTERR=0x00000000
        SDMA_H_DSPOVR=0xffffffff
        SDMA_H_HOSTOVR=0x00000000
        SDMA_H_INTR=0x00000000
        SDMA_H_INTRMSK=0x00000018
        SDMACORE_EVENTS=0x00000000
        SDMACORE_EVENTS2=0x00000000

SDMA EVTERR channel counters:
*        003 = 1**
**        004 = 1*

root@voneus-domus-imx6sx:~# cat /proc/interrupts
           CPU0
 16:      39485       GPC  55 Edge      i.MX Timer Tick
 20:       2310       GPC  26 Edge      2020000.serial
 21:          0       GPC  46 Edge      ssi-tdm
 39:          0  gpio-mxc  12 Edge      si3217x-irq
123:          0  gpio-mxc  28 Edge      2194000.usdhc cd
266:          0       GPC  49 Edge      imx_thermal
271:          0       GPC  19 Edge      rtc alarm
*277:      36800       GPC   2 Edge      sdma*
278:          0       GPC  43 Edge      2184000.usb
279:       2994       GPC  23 Edge      mmc0
280:        245       GPC  25 Edge      mmc1
283:          9       GPC 109 Edge      21e4000.qspi
284:          0       GPC  27 Edge      21e8000.serial
287:      50274       GPC  18 Edge      228c000.ecspi
IPI0:          0  CPU wakeup interrupts
IPI1:          0  Timer broadcast interrupts
IPI2:          0  Rescheduling interrupts
IPI3:          0  Function call interrupts
IPI4:          0  Single function call interrupts
IPI5:          0  CPU stop interrupts
IPI6:          1  IRQ work interrupts
IPI7:          0  completion interrupts
Err:          0

This is the relevant part of the dmesg

[  993.283774] dahdi: Version:
[  993.317161] dahdi: Telephony Interface Registered on major 196
[  997.013802] si3217x_audmux_probe: AUDMUX base is 0xa0b10000
*[  999.313971] sdma_disable_channel: Disabling EVTERR for channel 3**
**[  999.320620] sdma_disable_channel: Disabling EVTERR for channel 4*
[  999.326866] si3217x_ssi_probe: SSI base is 0xa0b20000 clock rate is 2048000Hz, TDM Frame rate 8000Hz, channels 32
having 8 bits word length
[ 1002.733512] si3217x_probe: SPI setup mode 3, 8 bits/w, 10000000 Hz max
[ 1002.740962] RX: prepare for the DMA.
*[ 1002.744960] sdma_enable_channel: Enabling EVTERR for channel 4*
[ 1002.752305] TX: prepare for the DMA.
*[ 1002.756111] sdma_enable_channel: Enabling EVTERR for channel 3*
[ 1002.762739] si3217x_ssi_set_clock: BIT_CLK=8192000, IPGCLK=66000000, PM=1
[ 1003.278453] Si3217x: isVerifiedProslic : chan(0) REG PCMTXHI VAL = 00
[ 1003.285624] Si3217x: isVerifiedProslic : Not a VDAA chan(0) REG PCMMODE VAL = 05
[ 1003.306492] SLIC verification OK
[ 1003.310461] SPI ret=0, MSTRSTAT=0x1f
[ 1003.314068]  PCLK_VALID       = 1
[ 1003.317115]  FS_VALID         = 1
[ 1003.319850]  FS_DETECT        = 1
[ 1003.322661]  PLL_LOCK         = 1
[ 1003.325385]  SRAM_CLR         = 1
[ 1003.328181]  PCLK_FAULT       = 0
[ 1003.331083]  FS_FAULT         = 0
[ 1003.333807]  PLL_FAULT        = 0
[ 1003.341485] Si3217x: isVerifiedProslic : chan(0) REG PCMTXHI VAL = 00
[ 1003.349140] Si3217x: isVerifiedProslic : Not a VDAA chan(0) REG PCMMODE VAL = 05
[ 1003.356601] Si3217x: Channel 0 : Type = PROSLIC
[ 1003.362536] Si3217x: isVerifiedProslic : chan(1) REG PCMTXHI VAL = 40
[ 1003.369863] Si3217x: Channel 1 : Type = DAA
[ 1003.374358] si3217x: Channel 0 : Type = 26
[ 1003.378515] si3217x: Channel 0 : Rev  = 1
[ 1003.385623] Si3217x: loading patch: 12102012
[ 1007.624105] Si3217x: Channel 0 : VBAT Up = 62.754 v
[ 1008.556990] Si3217x: PCMStart
[ 1008.560526] Channel 0: FXS model Si32178
[ 1008.567449] Channel 1: FXO model Si32919 rev A
[ 1008.591259] Found: Quadplay FXS/FXO Card

Basically for every DMA channel attached to a SSI peripheral I will enable the corresponding EVTERR bit
for the given channel in order to detect if a DMA overflow condition might happen or not.

With the patch below I'm able to see the error happening. And more likely it happen just just afterwards
the EVTERR notify the problem to the ISR. At this point the DMA simply stalls due to some problems, most
likely because the SSI FIFO is in overflow or underflow condition. I will do add the code to dump the SSI
registers once EVTERR is triggered.

I think that at this point we should in theory restart the DMA channel, but however how to fix this and
why this is happening?


diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index 9d375bc..b9faf2d 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -50,6 +50,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 +387,7 @@ struct sdma_engine {
     const struct sdma_driver_data    *drvdata;
     u32                spba_start_addr;
     u32                spba_end_addr;
+        u32                             evterrchannel[MAX_DMA_CHANNELS];
 };
 
 static struct sdma_driver_data sdma_imx31 = {
@@ -562,7 +565,17 @@ 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];
+
     writel(BIT(channel), sdma->regs + SDMA_H_START);
+
+        if ( sdmac->peripheral_type == IMX_DMATYPE_SSI_SP )
+        {
+            u32 msk = readl(sdma->regs + SDMA_H_INTRMSK);
+
+            writel(msk | BIT(channel), sdma->regs + SDMA_H_INTRMSK);
+            printk("%s: Enabling EVTERR for channel %d\n", __func__, channel);
+        }
 }
 
 /*
@@ -725,12 +738,26 @@ static irqreturn_t sdma_int_handler(int irq, void *dev_id)
 {
     struct sdma_engine *sdma = dev_id;
     unsigned long stat;
+        u32 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];
@@ -908,6 +935,14 @@ static int sdma_disable_channel(struct dma_chan *chan)
     writel_relaxed(BIT(channel), sdma->regs + SDMA_H_STATSTOP);
     sdmac->status = DMA_ERROR;
 
+        if ( sdmac->peripheral_type == IMX_DMATYPE_SSI_SP )
+        {
+            u32 msk = readl(sdma->regs + SDMA_H_INTRMSK);
+
+            writel(msk & ~(BIT(channel)), sdma->regs + SDMA_H_INTRMSK);
+            printk("%s: Disabling EVTERR for channel %d\n", __func__, channel);
+        }
+
     return 0;
 }
 
@@ -1650,6 +1685,44 @@ static struct dma_chan *sdma_xlate(struct of_phandle_args *dma_spec,
     return dma_request_channel(mask, sdma_filter_fn, &data);
 }
 
+#include <linux/seq_file.h>
+
+#define SDMA_SHOW_REG(reg) \
+    do { \
+                u32 _val = readl(sdma->regs + reg); \
+        seq_printf(s, "\t" #reg "=0x%08lx\n", _val); \
+    } while (0)
+
+void sdma_show_chan_status(struct seq_file *s, struct dma_chan *chan)
+{
+    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 = %lu\n", i, sdma->evterrchannel[i]);
+            }
+        }
+}
+EXPORT_SYMBOL_GPL(sdma_show_chan_status);
+
 static int sdma_probe(struct platform_device *pdev)
 {
     const struct of_device_id *of_id =

^ permalink raw reply related	[flat|nested] 33+ messages in thread

* Re: fsl_ssi.c: Roberto's problem: ssi hangs after some number of samples
  2015-11-04 15:33     ` Roberto Fichera
@ 2015-11-04 16:53       ` Roberto Fichera
  2015-11-04 17:41         ` Caleb Crome
  2015-11-04 17:58       ` Nicolin Chen
  1 sibling, 1 reply; 33+ messages in thread
From: Roberto Fichera @ 2015-11-04 16:53 UTC (permalink / raw)
  To: Caleb Crome
  Cc: Fabio Estevam, alsa-devel, Shengjiu Wang, Nicolin Chen,
	arnaud.mouiche, Markus Pargmann, shawn.guo, Fabio Estevam

On 11/04/2015 04:33 PM, Roberto Fichera wrote:
> On 11/03/2015 10:26 PM, Caleb Crome wrote:
>>>> or SDMA have missed the request signals from SSI.
>>> This is my current thought. However since the SSI is not operating at so
>>> high
>>> rate and the Cabel's problem seems going to a solution then I think
>>> there is something
>>> else I'm missing.
>> Is it possible that the event type below in the reference manual
>> section 55.10.5 is happening?  It looks like the SDMA script is
>> supposed to deal with it.  Perhaps there's a bug in the script?
>>
>> 55.10.5 External DMA Requests Mirror (SDMACORE_EVENTS)
>> NOTE
>> This register is very useful in the case of DMA requests that are
>> active when a peripheral FIFO level is above the programmed
>> watermark. The activation of the DMA request (rising edge) is
>> detected by the SDMA logic and it can enable one or several
>> channels. One of the channels accesses the peripheral and reads
>> or writes a number of data that matches the watermark level
>> (for example, if the watermark is four words, the channel reads
>> or writes four words).
>> If the channel is effectively executed long after the DMA
>> request was received, reading or writing the watermark number
>> of data may not be sufficient to reset the DMA request (for
>> example, if the FIFO watermark is four and at the channel
>> execution it already contains nine pieces of data). This means
>> no new rising edge may be detected by the SDMA, although
>> there still remains transfers to perform. Therefore, if the
>> channel were terminated at that time, it would not be restarted,
>> causing potential overrun or underrun of the peripheral.
>> The proposed mechanism is for the channel to check this
>> register after it has performed the "watermark" number of
>> accesses to the peripheral. If the bit for the DMA request that
>> triggers this channel is set, it means there is still another
>> watermark number of data to transfer. This goes on until the bit
>> is cleared. The same script can be used for multiple channels
>> that require this behavior. The script can determine its channel
>> number from the CCR register and infer the corresponding
>> DMA request bit to check. It needs a reference table that is
>> coherent with the request-channel matrix that the ARM
>> platform programmed.
>>
> Maybe this is the cause! I've explored a bit what's going on with my DMA stall and
> I've found that both RX and TX channels are getting an error, at least this is what
> the EVTERR register is reporting. See the log below:
>
> root@voneus-domus-imx6sx:~# cat /proc/domus_ssi_stats
> SSI TDM Info:
>         IPG clk=66000000
>         SSI baudclk=8192000
>         ssi_phy=0x02028000
>         irq=21
>         fifo_depth=10
>         tdm_frame_rate=8000
>         tdm_slots=32 (real 2)
>         tdm_word_size=8
>         tdm_slots_enabled=00000000000000000000000000000011
>         clk_frequency=2048000
>         clock_running=yes
>         DMA=yes
>         Dual FIFO=no
>         *RX DMA frame count=36795*
>         RX DMA addr=0x9ef0e000
>         RX DMA buffer len=16
>         *TX DMA frame count=36795*
>         TX DMA addr=0x9ee49000
>         TX DMA buffer len=16
>
> SSI Registers:
>         ssi_scr=0x0000109f
>         ssi_sier=0x00500504
>         ssi_stcr=0x000002e8
>         ssi_srcr=0x00000288
>         ssi_stccr=0x00007f01
>         ssi_srccr=0x00007f01
>         ssi_sfcsr=0x00aaf0aa
>         ssi_stmsk=0xfffffffc
>         ssi_srmsk=0xfffffffc
>
> SDMA RX channel:
> SDMA channel 4 status
>         SDMA_H_STATSTOP=0x00000000
>         SDMA_H_START=0x00000000
>         SDMA_H_EVTOVR=0x00000001
>         SDMA_H_EVTPEND=0x0000001a
>         SDMA_H_EVTERR=0x00000000
>         SDMA_H_DSPOVR=0xffffffff
>         SDMA_H_HOSTOVR=0x00000000
>         SDMA_H_INTR=0x00000000
>         SDMA_H_INTRMSK=0x00000018
>         SDMACORE_EVENTS=0x00000000
>         SDMACORE_EVENTS2=0x00000000
>
> SDMA EVTERR channel counters:
> *        003 = 1**
> **        004 = 1*
>
> SDMA TX channel:
> SDMA channel 3 status
>         SDMA_H_STATSTOP=0x00000000
>         SDMA_H_START=0x00000000
>         SDMA_H_EVTOVR=0x00000001
>         SDMA_H_EVTPEND=0x0000001a
>         SDMA_H_EVTERR=0x00000000
>         SDMA_H_DSPOVR=0xffffffff
>         SDMA_H_HOSTOVR=0x00000000
>         SDMA_H_INTR=0x00000000
>         SDMA_H_INTRMSK=0x00000018
>         SDMACORE_EVENTS=0x00000000
>         SDMACORE_EVENTS2=0x00000000
>
> SDMA EVTERR channel counters:
> *        003 = 1**
> **        004 = 1*
>
> root@voneus-domus-imx6sx:~# cat /proc/interrupts
>            CPU0
>  16:      39485       GPC  55 Edge      i.MX Timer Tick
>  20:       2310       GPC  26 Edge      2020000.serial
>  21:          0       GPC  46 Edge      ssi-tdm
>  39:          0  gpio-mxc  12 Edge      si3217x-irq
> 123:          0  gpio-mxc  28 Edge      2194000.usdhc cd
> 266:          0       GPC  49 Edge      imx_thermal
> 271:          0       GPC  19 Edge      rtc alarm
> *277:      36800       GPC   2 Edge      sdma*
> 278:          0       GPC  43 Edge      2184000.usb
> 279:       2994       GPC  23 Edge      mmc0
> 280:        245       GPC  25 Edge      mmc1
> 283:          9       GPC 109 Edge      21e4000.qspi
> 284:          0       GPC  27 Edge      21e8000.serial
> 287:      50274       GPC  18 Edge      228c000.ecspi
> IPI0:          0  CPU wakeup interrupts
> IPI1:          0  Timer broadcast interrupts
> IPI2:          0  Rescheduling interrupts
> IPI3:          0  Function call interrupts
> IPI4:          0  Single function call interrupts
> IPI5:          0  CPU stop interrupts
> IPI6:          1  IRQ work interrupts
> IPI7:          0  completion interrupts
> Err:          0
>
> This is the relevant part of the dmesg
>
> [  993.283774] dahdi: Version:
> [  993.317161] dahdi: Telephony Interface Registered on major 196
> [  997.013802] si3217x_audmux_probe: AUDMUX base is 0xa0b10000
> *[  999.313971] sdma_disable_channel: Disabling EVTERR for channel 3**
> **[  999.320620] sdma_disable_channel: Disabling EVTERR for channel 4*
> [  999.326866] si3217x_ssi_probe: SSI base is 0xa0b20000 clock rate is 2048000Hz, TDM Frame rate 8000Hz, channels 32
> having 8 bits word length
> [ 1002.733512] si3217x_probe: SPI setup mode 3, 8 bits/w, 10000000 Hz max
> [ 1002.740962] RX: prepare for the DMA.
> *[ 1002.744960] sdma_enable_channel: Enabling EVTERR for channel 4*
> [ 1002.752305] TX: prepare for the DMA.
> *[ 1002.756111] sdma_enable_channel: Enabling EVTERR for channel 3*
> [ 1002.762739] si3217x_ssi_set_clock: BIT_CLK=8192000, IPGCLK=66000000, PM=1
> [ 1003.278453] Si3217x: isVerifiedProslic : chan(0) REG PCMTXHI VAL = 00
> [ 1003.285624] Si3217x: isVerifiedProslic : Not a VDAA chan(0) REG PCMMODE VAL = 05
> [ 1003.306492] SLIC verification OK
> [ 1003.310461] SPI ret=0, MSTRSTAT=0x1f
> [ 1003.314068]  PCLK_VALID       = 1
> [ 1003.317115]  FS_VALID         = 1
> [ 1003.319850]  FS_DETECT        = 1
> [ 1003.322661]  PLL_LOCK         = 1
> [ 1003.325385]  SRAM_CLR         = 1
> [ 1003.328181]  PCLK_FAULT       = 0
> [ 1003.331083]  FS_FAULT         = 0
> [ 1003.333807]  PLL_FAULT        = 0
> [ 1003.341485] Si3217x: isVerifiedProslic : chan(0) REG PCMTXHI VAL = 00
> [ 1003.349140] Si3217x: isVerifiedProslic : Not a VDAA chan(0) REG PCMMODE VAL = 05
> [ 1003.356601] Si3217x: Channel 0 : Type = PROSLIC
> [ 1003.362536] Si3217x: isVerifiedProslic : chan(1) REG PCMTXHI VAL = 40
> [ 1003.369863] Si3217x: Channel 1 : Type = DAA
> [ 1003.374358] si3217x: Channel 0 : Type = 26
> [ 1003.378515] si3217x: Channel 0 : Rev  = 1
> [ 1003.385623] Si3217x: loading patch: 12102012
> [ 1007.624105] Si3217x: Channel 0 : VBAT Up = 62.754 v
> [ 1008.556990] Si3217x: PCMStart
> [ 1008.560526] Channel 0: FXS model Si32178
> [ 1008.567449] Channel 1: FXO model Si32919 rev A
> [ 1008.591259] Found: Quadplay FXS/FXO Card
>
> Basically for every DMA channel attached to a SSI peripheral I will enable the corresponding EVTERR bit
> for the given channel in order to detect if a DMA overflow condition might happen or not.
>
> With the patch below I'm able to see the error happening. And more likely it happen just just afterwards
> the EVTERR notify the problem to the ISR. At this point the DMA simply stalls due to some problems, most
> likely because the SSI FIFO is in overflow or underflow condition. I will do add the code to dump the SSI
> registers once EVTERR is triggered.

After apply the changes to dump the SSI register once the ISR is triggered by EVTERR the situation is
the following:

[   57.426204] SSI Registers:
[   57.428955]  ssi_scr=0x0000109f
[   57.432117]  ssi_sier=0x00500504
[   57.435361]  ssi_stcr=0x000002e8
[   57.438603]  ssi_srcr=0x00000288
[   57.441845]  ssi_stccr=0x00007f01
[   57.445175]  ssi_srccr=0x00007f01
[   57.448504]  ssi_sfcsr=0x00aaf0aa
[   57.451833]  ssi_stmsk=0xfffffffc
[   57.455164]  ssi_srmsk=0xfffffffc

Both TX and RX FIFO watermarks are set to maxburst + 2 = 10 in this run,
the SFCSR register reports TX FIFO empty and RX FIFO full and SIER is asserting
the related flags associated to this condition.

So why this is happening and the DMA transfer is not triggered? Maybe trying to increase
the DMA priority might solve this problem?

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: fsl_ssi.c: Roberto's problem: ssi hangs after some number of samples
  2015-11-04 16:53       ` Roberto Fichera
@ 2015-11-04 17:41         ` Caleb Crome
  2015-11-04 17:52           ` Roberto Fichera
  0 siblings, 1 reply; 33+ messages in thread
From: Caleb Crome @ 2015-11-04 17:41 UTC (permalink / raw)
  To: Roberto Fichera
  Cc: Fabio Estevam, alsa-devel, Shengjiu Wang, Nicolin Chen,
	arnaud.mouiche, Markus Pargmann, shawn.guo, Fabio Estevam

On Wed, Nov 4, 2015 at 8:53 AM, Roberto Fichera <kernel@tekno-soft.it> wrote:
> On 11/04/2015 04:33 PM, Roberto Fichera wrote:
>>         *RX DMA frame count=36795*
>>         RX DMA addr=0x9ef0e000
>>         RX DMA buffer len=16
>>         *TX DMA frame count=36795*
>>         TX DMA addr=0x9ee49000
>>         TX DMA buffer len=16


I notice your DMA buffer length is very short, which would require
very frequency interrupts to service, right?   Can you increase your
DMA buffer length by increasing the period size?  Maybe that would
help reduce the likelyhood of a failure.  Although it would be good to
be able to recover from a failure gracefully.
-Caleb

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: fsl_ssi.c: Roberto's problem: ssi hangs after some number of samples
  2015-11-04 17:41         ` Caleb Crome
@ 2015-11-04 17:52           ` Roberto Fichera
  2015-11-04 18:11             ` Nicolin Chen
  0 siblings, 1 reply; 33+ messages in thread
From: Roberto Fichera @ 2015-11-04 17:52 UTC (permalink / raw)
  To: Caleb Crome
  Cc: Fabio Estevam, alsa-devel, Shengjiu Wang, Nicolin Chen,
	arnaud.mouiche, Markus Pargmann, shawn.guo, Fabio Estevam

On 11/04/2015 06:41 PM, Caleb Crome wrote:
> On Wed, Nov 4, 2015 at 8:53 AM, Roberto Fichera <kernel@tekno-soft.it> wrote:
>> On 11/04/2015 04:33 PM, Roberto Fichera wrote:
>>>         *RX DMA frame count=36795*
>>>         RX DMA addr=0x9ef0e000
>>>         RX DMA buffer len=16
>>>         *TX DMA frame count=36795*
>>>         TX DMA addr=0x9ee49000
>>>         TX DMA buffer len=16
>
> I notice your DMA buffer length is very short, which would require
> very frequency interrupts to service, right?   Can you increase your
> DMA buffer length by increasing the period size?  Maybe that would
> help reduce the likelyhood of a failure.  

Not sure if this can help! SSI TDM is set to 32 slots but only 2 are masked. So every frame only
2 slots are pushed/pulled from the FIFOs. maxburst is set to pull a block of 8 elements from the
FIFOs, DMA cyclic call it period. So the full DMA buffer is filled in buffer size / period DMA iterations.

> Although it would be good to
> be able to recover from a failure gracefully.

Yep! I will try to restart the DMA channels from a failure to see if this might work or not.

> -Caleb
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel@alsa-project.org
> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
>

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: fsl_ssi.c: Roberto's problem: ssi hangs after some number of samples
  2015-11-04 15:33     ` Roberto Fichera
  2015-11-04 16:53       ` Roberto Fichera
@ 2015-11-04 17:58       ` Nicolin Chen
  2015-11-04 18:09         ` Roberto Fichera
  1 sibling, 1 reply; 33+ messages in thread
From: Nicolin Chen @ 2015-11-04 17:58 UTC (permalink / raw)
  To: Roberto Fichera
  Cc: Fabio Estevam, alsa-devel, Shengjiu Wang, Caleb Crome,
	arnaud.mouiche, Markus Pargmann, shawn.guo, Fabio Estevam

On Wed, Nov 04, 2015 at 04:33:16PM +0100, Roberto Fichera wrote:
 
> With the patch below I'm able to see the error happening. And more likely it happen just just afterwards
> the EVTERR notify the problem to the ISR. At this point the DMA simply stalls due to some problems, most
> likely because the SSI FIFO is in overflow or underflow condition. I will do add the code to dump the SSI

No, SSI FIFO under/overflow were caused by the DMA stall as their
channels got error out -- SSI was still consuming the TX FIFO and
filling the RX FIFO while DMA didn't move the data at all so SSI
FIFOs got under/overflowed.

> I think that at this point we should in theory restart the DMA channel, but however how to fix this and
> why this is happening?

According to Reference Manual:
----

1) The CHNERR[i] bit is set when a DMA request that triggers channel
i is received through the corresponding input pins and the EP[i]
bit is already set;

2) Externally triggered channel pending flag EP[i] is set by the
scheduler when the channel was activated by a DMA request. It can
be cleared by the ith channel script.

----

It looks like your system made another DMA request while the SDMA
was still in the middle of the transaction for the same channel.
I guess you should find a way to make less frequent DMA requests,
making higher watermarks and larger burst size for example.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: fsl_ssi.c: Roberto's problem: ssi hangs after some number of samples
  2015-11-04 17:58       ` Nicolin Chen
@ 2015-11-04 18:09         ` Roberto Fichera
  2015-11-04 18:18           ` Nicolin Chen
  0 siblings, 1 reply; 33+ messages in thread
From: Roberto Fichera @ 2015-11-04 18:09 UTC (permalink / raw)
  To: Nicolin Chen
  Cc: Fabio Estevam, alsa-devel, Shengjiu Wang, Caleb Crome,
	arnaud.mouiche, Markus Pargmann, shawn.guo, Fabio Estevam

On 11/04/2015 06:58 PM, Nicolin Chen wrote:
> On Wed, Nov 04, 2015 at 04:33:16PM +0100, Roberto Fichera wrote:
>  
>> With the patch below I'm able to see the error happening. And more likely it happen just just afterwards
>> the EVTERR notify the problem to the ISR. At this point the DMA simply stalls due to some problems, most
>> likely because the SSI FIFO is in overflow or underflow condition. I will do add the code to dump the SSI
> No, SSI FIFO under/overflow were caused by the DMA stall as their
> channels got error out -- SSI was still consuming the TX FIFO and
> filling the RX FIFO while DMA didn't move the data at all so SSI
> FIFOs got under/overflowed.

Yeah! The SSI is correctly reporting this problem because DMA is stalled for some reason.

>
>> I think that at this point we should in theory restart the DMA channel, but however how to fix this and
>> why this is happening?
> According to Reference Manual:
> ----
>
> 1) The CHNERR[i] bit is set when a DMA request that triggers channel
> i is received through the corresponding input pins and the EP[i]
> bit is already set;
>
> 2) Externally triggered channel pending flag EP[i] is set by the
> scheduler when the channel was activated by a DMA request. It can
> be cleared by the ith channel script.
>
> ----
>
> It looks like your system made another DMA request while the SDMA
> was still in the middle of the transaction for the same channel.

I don't know because this is something I cannot control. I'm just setting up 2 cyclic dma
for both TX and RX before to set both RDMAE and TDMAE and nothing else. The rest
is done by the SDMA ISR.

> I guess you should find a way to make less frequent DMA requests,
> making higher watermarks and larger burst size for example.
>
I can try to increase the FIFO watermark up to 15 elements, but after that
I don't have more choices. The problem is that the TDM has to run continuously
because the SLIC need it. I can eventually enable and disable the DMA requests
depending by the active channels for optimization, but the problem still,why the
DMA transfer is not triggered?

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: fsl_ssi.c: Roberto's problem: ssi hangs after some number of samples
  2015-11-04 17:52           ` Roberto Fichera
@ 2015-11-04 18:11             ` Nicolin Chen
  2015-11-04 21:47               ` Roberto Fichera
  2015-11-05 10:03               ` Roberto Fichera
  0 siblings, 2 replies; 33+ messages in thread
From: Nicolin Chen @ 2015-11-04 18:11 UTC (permalink / raw)
  To: Roberto Fichera
  Cc: Fabio Estevam, alsa-devel, Shengjiu Wang, Caleb Crome,
	arnaud.mouiche, Markus Pargmann, shawn.guo, Fabio Estevam

On Wed, Nov 04, 2015 at 06:52:12PM +0100, Roberto Fichera wrote:

> > I notice your DMA buffer length is very short, which would require
> > very frequency interrupts to service, right?   Can you increase your
> > DMA buffer length by increasing the period size?  Maybe that would
> > help reduce the likelyhood of a failure.  
> 
> Not sure if this can help! SSI TDM is set to 32 slots but only 2 are masked. So every frame only
> 2 slots are pushed/pulled from the FIFOs. maxburst is set to pull a block of 8 elements from the
> FIFOs, DMA cyclic call it period. So the full DMA buffer is filled in buffer size / period DMA iterations.

A smaller period size may course DMA buffer over/underrun -- ALSA
over/underrun even though it seems that you didn't report any.

And apparently SDMA would get more interrupt/callbacks. I would
suggest a larger period size and buffer size although I cannot
tie your problem with the size. But you may try.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: fsl_ssi.c: Roberto's problem: ssi hangs after some number of samples
  2015-11-04 18:09         ` Roberto Fichera
@ 2015-11-04 18:18           ` Nicolin Chen
  2015-11-04 21:48             ` Roberto Fichera
  0 siblings, 1 reply; 33+ messages in thread
From: Nicolin Chen @ 2015-11-04 18:18 UTC (permalink / raw)
  To: Roberto Fichera
  Cc: Fabio Estevam, alsa-devel, Shengjiu Wang, Caleb Crome,
	arnaud.mouiche, Markus Pargmann, shawn.guo, Fabio Estevam

On Wed, Nov 04, 2015 at 07:09:14PM +0100, Roberto Fichera wrote:

> I can try to increase the FIFO watermark up to 15 elements, but after that
> I don't have more choices. The problem is that the TDM has to run continuously
> because the SLIC need it. I can eventually enable and disable the DMA requests
> depending by the active channels for optimization, but the problem still,why the
> DMA transfer is not triggered?
 
There's nothing you can do from SSI side. If you don't clear the
Channel Error bit, the channel might be still hanging there until
you clear the bit or reset the channel. You may read SDMA chapter
for details.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: fsl_ssi.c: Roberto's problem: ssi hangs after some number of samples
  2015-11-04 18:11             ` Nicolin Chen
@ 2015-11-04 21:47               ` Roberto Fichera
  2015-11-05 10:03               ` Roberto Fichera
  1 sibling, 0 replies; 33+ messages in thread
From: Roberto Fichera @ 2015-11-04 21:47 UTC (permalink / raw)
  To: Nicolin Chen
  Cc: Fabio Estevam, alsa-devel, Shengjiu Wang, Caleb Crome,
	arnaud.mouiche, Markus Pargmann, shawn.guo, Fabio Estevam

On 11/04/2015 07:11 PM, Nicolin Chen wrote:
> On Wed, Nov 04, 2015 at 06:52:12PM +0100, Roberto Fichera wrote:
>
>>> I notice your DMA buffer length is very short, which would require
>>> very frequency interrupts to service, right?   Can you increase your
>>> DMA buffer length by increasing the period size?  Maybe that would
>>> help reduce the likelyhood of a failure.  
>> Not sure if this can help! SSI TDM is set to 32 slots but only 2 are masked. So every frame only
>> 2 slots are pushed/pulled from the FIFOs. maxburst is set to pull a block of 8 elements from the
>> FIFOs, DMA cyclic call it period. So the full DMA buffer is filled in buffer size / period DMA iterations.
> A smaller period size may course DMA buffer over/underrun -- ALSA
> over/underrun even though it seems that you didn't report any.
>
> And apparently SDMA would get more interrupt/callbacks. I would
> suggest a larger period size and buffer size although I cannot
> tie your problem with the size. But you may try.

Do you mean something like 2KB buffer and a period of 64 or 128 frames?
SDMA is supposed to wait the FIFO capacity
to complete a period, right?

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: fsl_ssi.c: Roberto's problem: ssi hangs after some number of samples
  2015-11-04 18:18           ` Nicolin Chen
@ 2015-11-04 21:48             ` Roberto Fichera
  0 siblings, 0 replies; 33+ messages in thread
From: Roberto Fichera @ 2015-11-04 21:48 UTC (permalink / raw)
  To: Nicolin Chen
  Cc: Fabio Estevam, alsa-devel, Shengjiu Wang, Caleb Crome,
	arnaud.mouiche, Markus Pargmann, shawn.guo, Fabio Estevam

On 11/04/2015 07:18 PM, Nicolin Chen wrote:
> On Wed, Nov 04, 2015 at 07:09:14PM +0100, Roberto Fichera wrote:
>
>> I can try to increase the FIFO watermark up to 15 elements, but after that
>> I don't have more choices. The problem is that the TDM has to run continuously
>> because the SLIC need it. I can eventually enable and disable the DMA requests
>> depending by the active channels for optimization, but the problem still,why the
>> DMA transfer is not triggered?
>  
> There's nothing you can do from SSI side. If you don't clear the
> Channel Error bit, the channel might be still hanging there until
> you clear the bit or reset the channel. You may read SDMA chapter
> for details.

Ok! Will have a look tomorrow morning.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: fsl_ssi.c: Roberto's problem: ssi hangs after some number of samples
  2015-11-04 18:11             ` Nicolin Chen
  2015-11-04 21:47               ` Roberto Fichera
@ 2015-11-05 10:03               ` Roberto Fichera
  2015-11-05 11:30                 ` Fabio Estevam
  1 sibling, 1 reply; 33+ messages in thread
From: Roberto Fichera @ 2015-11-05 10:03 UTC (permalink / raw)
  To: Nicolin Chen
  Cc: Fabio Estevam, alsa-devel, Shengjiu Wang, Caleb Crome,
	arnaud.mouiche, Markus Pargmann, shawn.guo, Fabio Estevam

On 11/04/2015 07:11 PM, Nicolin Chen wrote:
> On Wed, Nov 04, 2015 at 06:52:12PM +0100, Roberto Fichera wrote:
>
>>> I notice your DMA buffer length is very short, which would require
>>> very frequency interrupts to service, right?   Can you increase your
>>> DMA buffer length by increasing the period size?  Maybe that would
>>> help reduce the likelyhood of a failure.  
>> Not sure if this can help! SSI TDM is set to 32 slots but only 2 are masked. So every frame only
>> 2 slots are pushed/pulled from the FIFOs. maxburst is set to pull a block of 8 elements from the
>> FIFOs, DMA cyclic call it period. So the full DMA buffer is filled in buffer size / period DMA iterations.
> A smaller period size may course DMA buffer over/underrun -- ALSA
> over/underrun even though it seems that you didn't report any.
>
> And apparently SDMA would get more interrupt/callbacks. I would
> suggest a larger period size and buffer size although I cannot
> tie your problem with the size. But you may try.
>

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!

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: fsl_ssi.c: Roberto's problem: ssi hangs after some number of samples
  2015-11-05 10:03               ` Roberto Fichera
@ 2015-11-05 11:30                 ` Fabio Estevam
  2015-11-05 11:48                   ` Roberto Fichera
  0 siblings, 1 reply; 33+ messages in thread
From: Fabio Estevam @ 2015-11-05 11:30 UTC (permalink / raw)
  To: Roberto Fichera
  Cc: Fabio Estevam, alsa-devel, Shengjiu Wang, Caleb Crome,
	Nicolin Chen, arnaud.mouiche, Markus Pargmann, shawn.guo

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.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: fsl_ssi.c: Roberto's problem: ssi hangs after some number of samples
  2015-11-05 11:30                 ` Fabio Estevam
@ 2015-11-05 11:48                   ` Roberto Fichera
  0 siblings, 0 replies; 33+ messages in thread
From: Roberto Fichera @ 2015-11-05 11:48 UTC (permalink / raw)
  To: Fabio Estevam
  Cc: Fabio Estevam, alsa-devel, Shengjiu Wang, Caleb Crome,
	Nicolin Chen, arnaud.mouiche, Markus Pargmann, shawn.guo

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.
>

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.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: fsl_ssi.c: Roberto's problem: ssi hangs after some number of samples
  2015-11-05 23:46                 ` Roberto Fichera
@ 2015-11-06  0:35                   ` Caleb Crome
  0 siblings, 0 replies; 33+ messages in thread
From: Caleb Crome @ 2015-11-06  0:35 UTC (permalink / raw)
  To: Roberto Fichera
  Cc: Fabio Estevam, alsa-devel, Shengjiu Wang, Nicolin Chen,
	arnaud.mouiche, Markus Pargmann, shawn.guo

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
>

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: fsl_ssi.c: Roberto's problem: ssi hangs after some number of samples
  2015-11-05 23:30               ` Caleb Crome
@ 2015-11-05 23:46                 ` Roberto Fichera
  2015-11-06  0:35                   ` Caleb Crome
  0 siblings, 1 reply; 33+ messages in thread
From: Roberto Fichera @ 2015-11-05 23:46 UTC (permalink / raw)
  To: Caleb Crome
  Cc: Fabio Estevam, alsa-devel, Shengjiu Wang, Nicolin Chen,
	arnaud.mouiche, Markus Pargmann, shawn.guo

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

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: fsl_ssi.c: Roberto's problem: ssi hangs after some number of samples
  2015-11-05 23:28             ` Roberto Fichera
@ 2015-11-05 23:30               ` Caleb Crome
  2015-11-05 23:46                 ` Roberto Fichera
  0 siblings, 1 reply; 33+ messages in thread
From: Caleb Crome @ 2015-11-05 23:30 UTC (permalink / raw)
  To: Roberto Fichera
  Cc: Fabio Estevam, alsa-devel, Shengjiu Wang, Nicolin Chen,
	arnaud.mouiche, Markus Pargmann, shawn.guo

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

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: fsl_ssi.c: Roberto's problem: ssi hangs after some number of samples
  2015-11-05 23:21           ` Caleb Crome
@ 2015-11-05 23:28             ` Roberto Fichera
  2015-11-05 23:30               ` Caleb Crome
  0 siblings, 1 reply; 33+ messages in thread
From: Roberto Fichera @ 2015-11-05 23:28 UTC (permalink / raw)
  To: Caleb Crome
  Cc: Fabio Estevam, alsa-devel, Shengjiu Wang, Nicolin Chen,
	arnaud.mouiche, Markus Pargmann, shawn.guo



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?

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: fsl_ssi.c: Roberto's problem: ssi hangs after some number of samples
  2015-11-05 23:01         ` Roberto Fichera
@ 2015-11-05 23:21           ` Caleb Crome
  2015-11-05 23:28             ` Roberto Fichera
  0 siblings, 1 reply; 33+ messages in thread
From: Caleb Crome @ 2015-11-05 23:21 UTC (permalink / raw)
  To: Roberto Fichera
  Cc: Fabio Estevam, alsa-devel, Shengjiu Wang, Nicolin Chen,
	arnaud.mouiche, Markus Pargmann, shawn.guo

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

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: fsl_ssi.c: Roberto's problem: ssi hangs after some number of samples
  2015-11-05 22:49       ` Caleb Crome
@ 2015-11-05 23:01         ` Roberto Fichera
  2015-11-05 23:21           ` Caleb Crome
  0 siblings, 1 reply; 33+ messages in thread
From: Roberto Fichera @ 2015-11-05 23:01 UTC (permalink / raw)
  To: Caleb Crome
  Cc: Fabio Estevam, alsa-devel, Shengjiu Wang, Nicolin Chen,
	arnaud.mouiche, Markus Pargmann, shawn.guo



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?

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: fsl_ssi.c: Roberto's problem: ssi hangs after some number of samples
  2015-11-05 22:40     ` Roberto Fichera
@ 2015-11-05 22:49       ` Caleb Crome
  2015-11-05 23:01         ` Roberto Fichera
  0 siblings, 1 reply; 33+ messages in thread
From: Caleb Crome @ 2015-11-05 22:49 UTC (permalink / raw)
  To: Roberto Fichera
  Cc: Fabio Estevam, alsa-devel, Shengjiu Wang, Nicolin Chen,
	arnaud.mouiche, Markus Pargmann, shawn.guo

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.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: fsl_ssi.c: Roberto's problem: ssi hangs after some number of samples
  2015-11-05 22:25   ` Caleb Crome
@ 2015-11-05 22:40     ` Roberto Fichera
  2015-11-05 22:49       ` Caleb Crome
  0 siblings, 1 reply; 33+ messages in thread
From: Roberto Fichera @ 2015-11-05 22:40 UTC (permalink / raw)
  To: Caleb Crome
  Cc: Fabio Estevam, alsa-devel, Shengjiu Wang, Nicolin Chen,
	arnaud.mouiche, Markus Pargmann, shawn.guo

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.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: fsl_ssi.c: Roberto's problem: ssi hangs after some number of samples
  2015-11-05 22:08 ` Roberto Fichera
@ 2015-11-05 22:25   ` Caleb Crome
  2015-11-05 22:40     ` Roberto Fichera
  0 siblings, 1 reply; 33+ messages in thread
From: Caleb Crome @ 2015-11-05 22:25 UTC (permalink / raw)
  To: Roberto Fichera
  Cc: Fabio Estevam, alsa-devel, Shengjiu Wang, Nicolin Chen,
	arnaud.mouiche, Markus Pargmann, shawn.guo

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.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: fsl_ssi.c: Roberto's problem: ssi hangs after some number of samples
  2015-11-05 21:34 Caleb Crome
@ 2015-11-05 22:08 ` Roberto Fichera
  2015-11-05 22:25   ` Caleb Crome
  0 siblings, 1 reply; 33+ messages in thread
From: Roberto Fichera @ 2015-11-05 22:08 UTC (permalink / raw)
  To: Caleb Crome
  Cc: Fabio Estevam, alsa-devel, Shengjiu Wang, Nicolin Chen,
	arnaud.mouiche, Markus Pargmann, shawn.guo

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.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: fsl_ssi.c: Roberto's problem: ssi hangs after some number of samples
@ 2015-11-05 21:34 Caleb Crome
  2015-11-05 22:08 ` Roberto Fichera
  0 siblings, 1 reply; 33+ messages in thread
From: Caleb Crome @ 2015-11-05 21:34 UTC (permalink / raw)
  To: Roberto Fichera
  Cc: Fabio Estevam, alsa-devel, Shengjiu Wang, Caleb Crome,
	Nicolin Chen, arnaud.mouiche, Markus Pargmann, shawn.guo

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(+)

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);
+       }
 }

 /*
@@ -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

^ permalink raw reply related	[flat|nested] 33+ messages in thread

end of thread, other threads:[~2015-11-06  0:35 UTC | newest]

Thread overview: 33+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-10-30 18:01 fsl_ssi.c: Roberto's problem: ssi hangs after some number of samples Caleb Crome
2015-10-31  9:16 ` Roberto Fichera
2015-11-01 20:31   ` Fabio Estevam
2015-11-02  9:57     ` Roberto Fichera
2015-11-02 17:51   ` Roberto Fichera
2015-11-02 18:03     ` Roberto Fichera
2015-11-03  0:56       ` Caleb Crome
2015-11-03  8:21         ` Roberto Fichera
2015-11-03 21:26   ` Caleb Crome
2015-11-04 15:33     ` Roberto Fichera
2015-11-04 16:53       ` Roberto Fichera
2015-11-04 17:41         ` Caleb Crome
2015-11-04 17:52           ` Roberto Fichera
2015-11-04 18:11             ` Nicolin Chen
2015-11-04 21:47               ` Roberto Fichera
2015-11-05 10:03               ` Roberto Fichera
2015-11-05 11:30                 ` Fabio Estevam
2015-11-05 11:48                   ` Roberto Fichera
2015-11-04 17:58       ` Nicolin Chen
2015-11-04 18:09         ` Roberto Fichera
2015-11-04 18:18           ` Nicolin Chen
2015-11-04 21:48             ` Roberto Fichera
2015-11-05 21:34 Caleb Crome
2015-11-05 22:08 ` Roberto Fichera
2015-11-05 22:25   ` Caleb Crome
2015-11-05 22:40     ` Roberto Fichera
2015-11-05 22:49       ` Caleb Crome
2015-11-05 23:01         ` Roberto Fichera
2015-11-05 23:21           ` Caleb Crome
2015-11-05 23:28             ` Roberto Fichera
2015-11-05 23:30               ` Caleb Crome
2015-11-05 23:46                 ` Roberto Fichera
2015-11-06  0:35                   ` Caleb Crome

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.