-
Notifications
You must be signed in to change notification settings - Fork 314
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[FEATURE] Explicit clock control #4156
Comments
same request in linux |
This was a feature we've put on the back burner since November 2018. #629 If you just want the blk and MCLK, it's rather easy to enable since it's just a change in the clock settings. But if you want the FSYNC to be enabled on demand, then it requires firmware to enable pretend DMA transfers with zero-based values, a lot more work. |
If I am not mistaken this also causes a 400ms delay on GLK, if the clock is not enabled the codec will play audio with a delay. |
is this one @plbossart ? |
Yes @sathya-nujella that was issue #2124 I was looking for, but it does make a reference to the WCLK aka FrameSync, so it's not trivial to fix. |
@plbossart At least we need to support BCLK for cs42l42. It would be better if MCLK could be supported as well since some codecs like rt5514 needs MCLK. |
Got lazy didn't read whole bug, yes, i think your mean #2124 |
depends what you want for cs42l42. If it's bclk and mclk, it's easier, but that isn't enough for DA7219 which needs FSYNC to be active |
@plbossart This is Karl Sun from Cirrus . For cs42l42 ,the the PLL lock will be dependent from bclk input. Then we have all the correct setting ready for Dout and DIn. |
Can anyone give some feedback on the expected clock preamble duration prior to audio data being sent ? This would help with the design. |
yes, I don't get what is needed. @brentlu added a 10ms delay initially in the topology but it doesn't seem to fix the issue. |
10ms delay is for another TX noise issue. The delay is between bclk on and dma enable to avoid noise. my understanding of PLL issue is that: this codec requires bclk ready in prepare stage @hhyshw would you confirm if my understanding is correct and describe the clock requirement of the codec with more detail? thanks. |
|
@hhyshw the reference from 2019 is for a different driver, we do not support the clock enable from the machine driver on GLK. To help us figure out alternate solutions, can you please clarify how much time is required before the bclk being activated and the PLL lock. I would imagine we can only enable the actual transfers after the PLL lock. Also, if the issue is only on trigger start, have you tried starting in mute and use a workqueue to unmute some time after the trigger? That would be a way of working around the atomic nature of the trigger proper. |
@plbossart Here is the detail status about polling the PLL lock status a few times to wait for the clock status. Because the CS42L42 I2C command read/write must have a working clock(either internal clk or external sclk ), the driver must know the status clearly to switch.Once the blck signal is ready , then the PLL will take about in 250us--12500us to lock for system clock . |
IIRC the SSP ports could support a clock control if the DMA/CPU FIFO IRQs were masked until trigger start. i.e we could enable port at prepare() as this would allow clocking BCLK/FRAME for 10s of ms /* start the SSP for either playback or capture */
static void ssp_start(struct dai *dai, int direction)
{
struct ssp_pdata *ssp = dai_get_drvdata(dai);
spin_lock(&dai->lock);
/* request mclk/bclk */
ssp_pre_start(dai);
/* enable port */
ssp_update_bits(dai, SSCR0, SSCR0_SSE, SSCR0_SSE);
ssp->state[direction] = COMP_STATE_ACTIVE;
dai_info(dai, "ssp_start()");
if (ssp->params.bclk_delay) {
/* drive BCLK early for guaranteed time,
* before first FSYNC, it is required by some codecs
*/
wait_delay(clock_ms_to_ticks(PLATFORM_DEFAULT_CLOCK,
ssp->params.bclk_delay)); <<<<<<<<<<< small delay here is posssible
}
/* enable DMA */ <<<<<<<<<<<<<<<<<<<<<<<<<< DMA is enabled last so port could be enabled in prepare and DMA in trigger()
if (direction == DAI_DIR_PLAYBACK) {
ssp_update_bits(dai, SSCR1, SSCR1_TSRE, SSCR1_TSRE);
ssp_update_bits(dai, SSTSA, SSTSA_TXEN, SSTSA_TXEN);
} else {
ssp_update_bits(dai, SSCR1, SSCR1_RSRE, SSCR1_RSRE);
ssp_update_bits(dai, SSRSA, SSRSA_RXEN, SSRSA_RXEN);
}
/* wait to get valid fifo status */
wait_delay(PLATFORM_SSP_DELAY);
spin_unlock(&dai->lock);
} |
Hi @hhyshw |
PLL startup time for cs42l42 is 1ms max. |
Actually, what is more, important for us is to have SCLK when we switch back from PLL to internal clocks. So, after reset cs42l42 is running on internal clocks, and these clocks also used for I2C bus, then when we have SCLK ( we assume SCLK started before trigger start is called) we will switch the source from internal clocks to SCLK, during this switch I2C bus cannot be used for ~150us, and then I2C bus can be used again. However, the problem is to switch back. If you remove SCLK before we switch the source from PLL to internal clocks, then the I2C bus is locked, and we cannot access codec registers anymore until hard #reset. So, if you keep SCLK running hw_free() then we can switch back safely in mute(). |
@snake0x65 I don't fully understand the request. At what point do you switch from PLL to internal clock? My worry is that if we keep the SCLK active until the hw_free, the SOF hw_free will be executed before the codec hw_free, and we still have a deadlock. |
@plbossart , sorry, my explanation might be a bit confusing. CS42l42 HW required clocks to be present at the moment of switch from internal clocks to external SCLK and back. The transition takes ~150us. Currently, we are using mute_stream() callback to switch to/from PLL. UNMUTE event -> we switch to PLL, MUTE -> we switch to internal clocks. The problem is that (observed in 4.14 kernel) when mute_stream() is called to unmute SCLK still not available, and when mute_stream() callback is called to mute, SCLK has already stopped. So, we need 2 points where SCLK is stable to make a safe switch to/from PLL. When we use SCLK as a reference for PLL and suddenly SCLK is removed then the I2C bus will be dead and all transitions will fail. We cannot recover from this condition until HW reset. |
@snake0x65 I am not familiar with this mute_stream thing, we only deal with trigger_stop, hw_free and release. Where would you want us to stop the clock? |
@plbossart hw_free() would be ideal for stop |
Thanks @snake0x65, we will assume the direction is to turn on the BCLK and FSYNC during .prepare() (or maybe .hw_params(), tbd) and turn them off during .hw_free(). I don't think we have a limitation at the hardware level, but there are currently missing steps in the firmware if you see #4189 |
Hi, I implement a virtual clock driver for mclk/bclk on Linux side and add a new IPC command on FW side to support explicit clock control. Tested on my TGL chromebook. Kernel: Chrome v5.4 kernel thesofproject/linux#2932 Regards, |
This feature is a duplicate of #629. Close it. @plbossart @bardliao @brentlu Let's track #629. Thanks |
Some codecs need external clock (mclk or bclk) to be ready in prepare stage or some function may broken.
To support those codec, we need to implement explicit clock control so machine driver could enable/disable the clock via DAPM supply widget or set_bias_level callback.
This feature has been implemented on SST FW running on Chrome KBL platforms. Following are the mailthread:
https://mailman.alsa-project.org/pipermail/alsa-devel/2017-November/127833.html
https://mailman.alsa-project.org/pipermail/alsa-devel/2019-October/156161.html
The text was updated successfully, but these errors were encountered: