IMX6Q: Spdif TX miss 1-2s of the song

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

IMX6Q: Spdif TX miss 1-2s of the song

2,438 Views
dabrain
Contributor I

Dear all,

I'm currently using the codec mxc-spdif as TX and i'm facing a loss of 1-3s at the beginning of each song.

Indeed i'm using aplay or gstreamer.

I know that spdif tx is not fully tested ( seen in different forum) but i would like to know if it could be possible to find a condition to wait in order to launch the playback when the spdif communication is correctly on/sync.

Indeed i put a sleep of 1s ( which is not a solution) at the end of the function mxc_spdif_playback_start and in this case i dont loose the beginning of the song.

SPDIF_SIS register is always equal to 2 ( tx fifo empty) at the end of the function.

I had a look to the reference manual and i dont find any information who can help me.

Please help.

Labels (1)
Tags (3)
0 Kudos
Reply
13 Replies

1,857 Views
nicolinchen
Contributor I

Hi Cerveau,

Just tested with my board, and there is no such loss in my playback case. Right after I entered 'aplay /test.wav', I could hear entire audio playback from my SPDIF receiver side without any obvious loss. (1-2s should be easily discerned)

However, my test environment might be a bit different at the external SPDIF receiver part. So I doubt if it might be because your SPDIF receiver were remaining sleep mode due to no input clock from i.MX6Q.

I think you can, first, try to move SCR_LOW_POWER setting from start() to startup() and accordingly SCR_LOW_POWER clear from end() to shutdown(). And see if there's any effect.

If not, you can try to clear the SCR_LOW_POWER during probe(), and drop the SCR_LOW_POWER configuration in start() and stop(). This, however, might lift some power consumption during non-playback period.

Well, I think at least you can try it out to pinpoint the root cause. If this modification does make sense, we can talk about the further refinement later.

Best regards,

Nicolin Chen

0 Kudos
Reply

1,857 Views
dabrain
Contributor I

Thank you for your answer.

I removed the LOW_POWER completely ( remove the bit in probe and do not set it again) and the result is the same.

I'm comparing the behaviour with a CD player using a spdif coax out and on the cd player the track starts immediatly.

I should maybe use another device to test, i'm currently using a home cinema device branded onkyo( difficult to find a amplifier accepting spdif in).

When I say 1 or 2 sec its an estimation seen that the first it starts with more than 1s delay and if i stop and play immediatly the delay is less important. I guess we should send some silence/zero before reading the spdif fifo.

Could you tell me a bit more about modes from TxFIFO_Ctrl bits in SPDIF_SCR register?

Best regards.

Steph

0 Kudos
Reply

1,857 Views
nicolinchen
Contributor I

Hmm....Thing seems to be a little tougher. It looks like LOW_POWER only could not toss the clock out. Then I think we can try another way, just it might a little steep.

(Note: When I say 'Move', it literally means CUT and PASTE.)

For probe():

1, Move clk_enable() to the end of probe(), and drop clk_disable() in shutdown() or playback_stop().

2, Move softreset() to the tail of clk_enable() in probe().

3, Move SIE register configuration, it just clears all the interrupt bits, after softrest().

4, For SCR reg: Set TxFIFO_Ctrl to 0x0 and TxSel to 0x5 (Normal operation) and Clear LOW_POWER.

5, Set clock rate to 64 * desired samplerate(44100) * (plat_data->spdif_div_44100 + 1) by using function:

     static int spdif_clk_set_rate(struct clk *clk, unsigned long rate)

     {

              unsigned long rate_actual;

              rate_actual = clk_round_rate(clk, rate);

              clk_set_rate(clk, rate_actual);

              return 0;

     }  

6, Set STC reg to STC_TXCLK_SRC_EN | (0x1<< STC_TXCLK_SRC_OFFSET) | (plat_data->spdif_div_44100 - 1)

(You can figure out that we are trying to complete all the setting in probe() and then we should keep the setting won't be altered.)

For playback_stop():

7, Delete TXSEL_OFF bit and LOW_POWER bit setting.

-------------

By doing these, I think your system would be able to playback 44100Hz audio without any loss.

However:

1. The whole system would output digital zero data with active clock, so the power consumption might be a bit higher.

2. The system might only support 44100Hz playback perfectly. There might be a little risk if we change the clock rate to fit 48000Hz or 32000Hz that 1s data would be lost again.

And I'm not so sure which step could be smartly omitted but you can try to simplify it if you really think such modification is kinda a mess :-/

0 Kudos
Reply

1,857 Views
dabrain
Contributor I

Dear Nicolin,

Unfortunately I had a try with your recommandations and the result is the same. I loose less than 1s but its really obvious.

Here is my code in spdif probe:

http://pastebin.com/raw.php?i=vuGjMbBp

I had a try to put the txfifo zero in hw_params

http://pastebin.com/raw.php?i=NWPs8F9Y

But no effect.

I can have a better behaviour with a mdelay(1000) in playback_start function just before regval |= SCR_DMA_TX_EN;

In this case the first play attempt loose some ms ( i can say 10, i'm testing with under_pressure from Queen) and then no loss with the next quick attempt.

If i wait more than 10 sec between aplay attempt i get again a loss ( but really less important than without the mdelay)

I'm testing with aplay on a kernel 3.0.35 with Signed 16 bit Little Endian, Rate 44100 Hz, Stereo sample ( queen under_pressure).

I'm also having a codec wm8740 plugged to audmux4 and i dont have this issue.

0 Kudos
Reply

1,857 Views
nicolinchen
Contributor I

I just found there's something incorrect in your code:

regval = __raw_readl(spdif_base_addr + SPDIF_REG_SCR);

regval &= 0xfc33e3;   <----should be '0xFFFFD3E3'  because you only wanted to set LOW_POWER, TXSEL and TXFIFO. so shouldn't modify other bits.

regval &= ~SCR_LOW_POWER;

regval = SCR_TXFIFO_ZERO | SCR_TXSEL_NORMAL;  <---should use 'regval |='

__raw_writel(regval, SPDIF_REG_SCR + spdif_base_addr);

you should ensure these bits and configurations won't be alert during playback's start() or stop():

SCR_LOW_POWER, SCR_TXSEL_NORMAL,STC_TXCLK_ALL_EN, STC_TXCLK_DIV, STC_TXCLK_SRC, and the output clock rate(clk_set_rate()).

I've been tested this flow by using SPDIF as an HDMI-audio output, and let HDMI owner capture HDMI package for me. His result is just fine that there's always digital zero output after system boot.

So I think you can try again.

Best regards,

Nicolin Chen

0 Kudos
Reply

1,857 Views
dabrain
Contributor I

Hello nicolin,

I made the mods you were asking me to do but it is still the same.

I'm not sure ton understand when you say to not alert bits such as SCR_TXSEL_NORMAL

Do you think you could provide me your mxc_spdif.c file in order to test and compare ?

You can send it to me at scerveau   at gmail.com

Best regards.

0 Kudos
Reply

1,857 Views
nicolinchen
Contributor I

File attached. You can get and test it. I also uploaded the diff about what I've modified.

Hope this would help you out.

Nicolin Chen

0 Kudos
Reply

1,857 Views
wangli
Contributor I

Hi nicolinchen,

why does the patch not integrate the freescale of linux?

Thanks,

LiWang.

0 Kudos
Reply

1,857 Views
olegnos
Contributor I

Dear Nicolin.


Many thanks for the patch.

0 Kudos
Reply

1,857 Views
dabrain
Contributor I

Thank you very much. It seems that the patch you send me allow me to play media from beginning ( just a tiny loss the first time 10ms something like that). I dont need my delay anymore.

Now i gonna check what is different from my previous implementation and how can we do something not outputing signal all the time.

0 Kudos
Reply

1,857 Views
dabrain
Contributor I

Dear Nicolin,

I add a try to make it work with different sample rate and power saving and this solution is the best i got losing only 900ms to start the playback. There is still some loss but this is almost acceptable. I dont see how we can have no loss without the delay.

Can you have a look to it and comment if needed ?

0 Kudos
Reply

1,857 Views
nicolinchen
Contributor I

Hi Cerveau, Doing mdelay in hw_params() would be no different from put in start() like what you did at the beginning.

And there might be another solution by using set_bias_level(). Register a set_biase_level to the soc_codec_dev_spdif.

Do the softreset and the other configurations and msleep when SND_SOC_BIAS_OFF->SND_SOC_BIAS_STANDBY; /* msleep might be better because mdelay would cause the whole system lag during the 900ms. */

Do the LOW_POWER and TXSEL_OFF setting when SND_SOC_BIAS_STANDBY->SND_SOC_BIAS_OFF.


This would at least allow you to avoid some data loss if you playback some files continuously: DAPM would turn BIAS off about 5 seconds later after all audio playback's finished.

You only need to do the delay whenever you start to play the first one of the branch of files.


And I have a question about different sample rate. When I said there might be a problem occur to this situation, actually I was guessing, not so sure.

So your test result with my previous patch got the exact result that data loss would happen if changing 44.1KHz to 32KHz?

0 Kudos
Reply

1,857 Views
dabrain
Contributor I

Thank you very much Nicolin.

I gonna have a try ASAP.

Sorry for the late answer, i was off during this time...

0 Kudos
Reply