thesofproject / sof

Sound Open Firmware
Other
541 stars 311 forks source link

[ADL/RPL] [Bug] Invalid MCLK configuration with BT HFP configuration #7803

Open kv2019i opened 1 year ago

kv2019i commented 1 year ago

Describe the bug Follow-up to https://github.com/thesofproject/sof/issues/7548

Description form @ujfalusi in the above bug I think there is another angle to this issue which is brought to light by the TX FIFO drain simplifications. The setup is SSP1 - clock provider, playback only to speaker, want MCLK as 19200000 SSP2 - clock receiver, playback/capture to BT, want MCLK as 38400000

We see this sequence in case of a failure: SSP2 start (sets MCLK to 38400000)

ssp-dai      1.2   /drivers/intel/ssp/ssp.c:1111 INFO ssp_trigger() cmd 7
ssp-dai      1.2   /drivers/intel/ssp/ssp.c:900  INFO ssp_pre_start()
mn                 ./drivers/intel/ssp/mn.c:259  INFO mclk_rate 38400000, mclk_source_clock 1
mn                 ./drivers/intel/ssp/mn.c:220  INFO mclk_id 0 mdivr_val 1
mn                 ./drivers/intel/ssp/mn.c:330  INFO find_mn for freq 38400000 bclk 128000
mn                 ./drivers/intel/ssp/mn.c:628  INFO bclk_rate 128000, *out_scr_div 300, m 1, n 1
ssp-dai      1.2   /drivers/intel/ssp/ssp.c:234  INFO ssp_bclk_prepare_enable(): sscr0 = 0xc0c12b7f
ssp-dai      1.2   /drivers/intel/ssp/ssp.c:993  INFO ssp_early_start(): SSE set for SSP2
ssp-dai      1.2   /drivers/intel/ssp/ssp.c:1111 INFO ssp_trigger() cmd 1
ssp-dai      1.2   /drivers/intel/ssp/ssp.c:1008 INFO ssp_start()

SSP2 start (clocks have been configured for SSP2 already)

ssp-dai      1.2   /drivers/intel/ssp/ssp.c:1111 INFO ssp_trigger() cmd 7
ssp-dai      1.2   /drivers/intel/ssp/ssp.c:900  INFO ssp_pre_start()
ssp-dai      1.2   /drivers/intel/ssp/ssp.c:993  INFO ssp_early_start(): SSE set for SSP2
ssp-dai      1.2   /drivers/intel/ssp/ssp.c:1111 INFO ssp_trigger() cmd 1
ssp-dai      1.2   /drivers/intel/ssp/ssp.c:1008 INFO ssp_start()

SSP2 RX stop SSP2 start

ssp-dai      1.2   /drivers/intel/ssp/ssp.c:1111 INFO ssp_trigger() cmd 7
ssp-dai      1.2   /drivers/intel/ssp/ssp.c:900  INFO ssp_pre_start()
ssp-dai      1.2   /drivers/intel/ssp/ssp.c:993  INFO ssp_early_start(): SSE set for SSP2
ssp-dai      1.2   /drivers/intel/ssp/ssp.c:1111 INFO ssp_trigger() cmd 1
ssp-dai      1.2   /drivers/intel/ssp/ssp.c:1008 INFO ssp_start()

SSP2 TX stop

At this point we have SSP2 RX still running, MCLK is configured for 38400000

SSP1 start (fails to set the MCLK to 19200000)

ssp-dai      1.1   /drivers/intel/ssp/ssp.c:1111 INFO ssp_trigger() cmd 7
ssp-dai      1.1   /drivers/intel/ssp/ssp.c:900  INFO ssp_pre_start()
mn                 ./drivers/intel/ssp/mn.c:180  INFO MCLK 19200000, source = 1
mn                 ./drivers/intel/ssp/mn.c:192  ERROR Can't set MCLK 0 to 19200000, it is already configured to 38400000
ssp-dai      1.1   /drivers/intel/ssp/ssp.c:161  ERROR ssp_mclk_prepare_enable(): invalid mclk_rate = 19200000 for mclk_id = 0
ssp-dai      1.1   /drivers/intel/ssp/ssp.c:993  INFO ssp_early_start(): SSE set for SSP1
demux        1.2        src/audio/mux/mux.c:693  INFO mux_trigger(), command = 1
ssp-dai      1.1   /drivers/intel/ssp/ssp.c:1111 INFO ssp_trigger() cmd 1
ssp-dai      1.1   /drivers/intel/ssp/ssp.c:1008 INFO ssp_start()

Note that the MCLK request fails since the same clock is already used by SSP2 and it is set to 38400000, the MCLK request fail is handled by skipping the BCLK setup for SSP1 but the error from ssp_pre_start() is ignored, so we go on and start the SSP1 anyways. This will lead to:

dw-dma                 src/drivers/dw/dma.c:1093 INFO dw_dma_free_data_size() size is 0!
dw-dma                 src/drivers/dw/dma.c:1128 ERROR dw_dma_get_data_size(): xrun detected
dai          1.6            src/audio/dai.c:881  ERROR dai_report_xrun(): underrun due to no data available
dai          1.6            src/audio/dai.c:775  ERROR comp_underrun(): dev->comp.id = 6, source->avail = 192, copy_bytes = 0
pipe         1.7   ....../pipeline-stream.c:270  INFO pipe trigger cmd 6
pipe         1.7   ....../pipeline-stream.c:143  ERROR pipeline_copy(): ret = -61, start->comp.id = 6, dir = 1
pipe         1.7   ..../pipeline-schedule.c:187  ERROR pipeline_task(): xrun recovery failed! pipeline is stopped.

Which is not a surprise without BCLK setup for a clock provider.

I think this setup is not correct. SSP1 and SSP2 can be used at the same time and they want the very same MCLK to run in different speeds. A clock cannot be 38400000 and 19200000 at the same time. Either both SSPs should be asking for the same MCLK rate or the two SSP should use different mclk_id from topology (if it is possible at all).

kv2019i commented 1 year ago

@Vamshigopal @juimonen can you comment on the bug description?

Vamshigopal commented 1 year ago

Hi @kv2019i

In above mentioned scenario by peter, SSP2 (BT offload) here the master clock source is BT controller (38.4MHz) and for SSP1 (Speaker pipeline) master clock source is DSP (19.2MHz) , Can we have 2 different clock source with different frequencies for SSP ?

ujfalusi commented 1 year ago

@Vamshigopal, I need to find some documentation, but is it possible that the MCLK frequency only matters when the SSP is the clock provider and it can be anything when it is not providing the clocks on the bus? The functional clock is different for the IP, so in theory the SSP can run w/o MCLK since the shift logic is driven by the I2S clocks?

Not sure about this and I don't have a setup where it can be tested, verified.

kv2019i commented 1 year ago

One solution to this issue is at https://github.com/thesofproject/sof/pull/7741