-
Notifications
You must be signed in to change notification settings - Fork 349
Start ssp clock earlier and stop later #4219
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
Conversation
|
code looks good, maybe we can squash the 2nd and the 3rd commits together. |
|
This PR is alternative version of #4189 |
Thanks @keyonjie I think separate the 2nd and the 3rd commits is easier to review, but I am fine to squash them, too. Lets keep it as it is for now and wait for comments from other reviewers. |
src/drivers/intel/ssp/ssp.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we state what we are doing in comments at the start of each function. i.e. this function enabled clock x, y , z to support codec that need x, y z. This is called before triiger (x) and after trigger(y) etc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bardliao we can use
/* SSP Configuration Request - SOF_IPC_DAI_SSP_CONFIG */
struct sof_ipc_dai_ssp_params {
uint32_t reserved0;
uint16_t reserved1;
uint16_t mclk_id;
uint32_t mclk_rate; /* mclk frequency in Hz */
uint32_t fsync_rate; /* fsync frequency in Hz */
uint32_t bclk_rate; /* bclk frequency in Hz */
/* TDM */
uint32_t tdm_slots;
uint32_t rx_slots;
uint32_t tx_slots;
/* data */
uint32_t sample_valid_bits;
uint16_t tdm_slot_width;
uint16_t reserved2; /* alignment */ <<<< add a flag here, 1 means start BCKL early, 0 menas no change.
/* MCLK */
uint32_t mclk_direction;
uint16_t frame_pulse_width;
uint16_t tdm_per_slot_padding_flag;
uint32_t clks_control;
uint32_t quirks;
uint32_t bclk_delay; /* guaranteed time (ms) for which BCLK
* will be driven, before sending data
*/
} __attribute__((packed, aligned(4)));There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how about using quirks? it's just a flag to the ssp driver.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how about using quirks? it's just a flag to the ssp driver.
I don't know if it is a quirk. @lgirdwood what do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, it's not a quirk but rather an operating mode. - We can use any of the reserved fields above as they are all 0 today and we could set a bit(s) for enabling the clock(s).
src/audio/dai.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hw_free instead?
|
Updated, and the corresponding kernel PR is thesofproject/linux#2936 |
src/drivers/intel/ssp/ssp.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could bclk continue to hw_free since SSE is clear here?
src/drivers/intel/ssp/ssp.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since bclk_delay is added here, it seems to me that TSRE/RSRE bit is irrelevant to the clock itself.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since bclk_delay is added here, it seems to me that TSRE/RSRE bit is irrelevant to the clock itself.
I will check the spec, thanks.
Edit: This is for DMA transmit. I think it should be enabled after BCLK is enabled.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bardliao have you checked if TSRE/RSRE set is mandatory/necessary for BCLK launching? or the setting of SSCR0_SSE? which is the crucial one?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bardliao have you checked if TSRE/RSRE set is mandatory/necessary for BCLK launching? or the setting of SSCR0_SSE? which is the crucial one?
SSCR0_SSE is the crucial one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When I set SSE bit, I see both bclk and fsync on my scope. @bardliao is it the same on your side?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are told to enable TSRE and RSRE long before SSE, so that the fifos are filled.
That said, this is not really working because we don't seem to have a pipeline pre-roll so we still have a risk of FIFOs not being full before enabling the SSE bit. That will have to be another PR...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When I set SSE bit, I see both bclk and fsync on my scope. @bardliao is it the same on your side?
No, only bclk on my side. I tested on Up Xtreme (TGL) board. It looks like fsync starts when DMA starts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are told to enable TSRE and RSRE long before SSE, so that the fifos are filled.
That said, this is not really working because we don't seem to have a pipeline pre-roll so we still have a risk of FIFOs not being full before enabling the SSE bit. That will have to be another PR...
But look at the existing ssp_start we enable TSRE and RSRE after SSE.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know @bardliao and hardware folks tell us it's wrong.
The trigger sequence needs to be revisited in a separate PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry I am wrong, the SSE bit itself only enables bclk, not sure why they appear at the same time on the same device days before...
src/include/kernel/tokens.h
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fail to cherry-pick but the ABI is already updated in 'ipc: dai-intel: add clk_early_start flag'...
No codespell typos will be found - file '/usr/share/codespell/dictionary.txt': No such file or directory
WARNING: Please update ABI in accordance with http://semver.org
#9: FILE: src/include/uapi/user/tokens.h:99:
#define SOF_TKN_INTEL_SSP_TDM_PADDING_PER_SLOT 505
+#define SOF_TKN_INTEL_SSP_CLK_EARLY_START 507
total: 0 errors, 1 warnings, 33 lines checked
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fail to cherry-pick but the ABI is already updated in 'ipc: dai-intel: add clk_early_start flag'...
No codespell typos will be found - file '/usr/share/codespell/dictionary.txt': No such file or directory
WARNING: Please update ABI in accordance with http://semver.org
#9: FILE: src/include/uapi/user/tokens.h:99:
#define SOF_TKN_INTEL_SSP_TDM_PADDING_PER_SLOT 505
+#define SOF_TKN_INTEL_SSP_CLK_EARLY_START 507total: 0 errors, 1 warnings, 33 lines checked
Please cherry-pick from 2ce9552 to 806e766, thanks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this token mean enabling all clocks i.e. MCLK, BCK and FRAME or just BCLK and FRAME ?
Also where do we set the duration of the "EARLY_START" ? or are we are meaning to enable the BCLK and FRAME as soon as we configure the DAI ? or at any other stage during PCM ops ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this token mean enabling all clocks i.e. MCLK, BCK and FRAME or just BCLK and FRAME ?
Also where do we set the duration of the "EARLY_START" ? or are we are meaning to enable the BCLK and FRAME as soon as we configure the DAI ? or at any other stage during PCM ops ?
It means MCLK and BCLK. i.e. Doesn't affect FRAME. With this token enabled, MCLK/BCLK will start during hw_parames and stop during hw_free.
plbossart
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks @bardliao for starting this. I added a set of comments below, the most important is that on stop we have to check for both directions, ie. we start the clock once and stop it when both directions are stopped.
src/include/sof/lib/dai.h
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest listing the callback by groups and in the order in which they are used. I found out by reverse-engineering the code that set_config is actually called during the prepare stage after the hw_params, and it's clearly not evident from the list.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest listing the callback by groups and in the order in which they are used. I found out by reverse-engineering the code that set_config is actually called during the prepare stage after the hw_params, and it's clearly not evident from the list.
I have to admit that I don't know the order the callback are used. Maybe someone can create another PR to do it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
well at the minimum you need to make sure the .hw_params is called after set_config, otherwise the clocks will be set with values that haven't been initialized yet. Unfortunately in my experiments this was the other way around, set_config was called in the prepare stage after hw_params.
@keyonjie and @lgirdwood we really need your help to clarify what the dai_driver state machine looks like and what callbacks are used in what order.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@plbossart set_config is called before hw_params for sure both in the case of static pipelines (during tplg parsing and during BE hw_params) and dynamic pipelines (only during BE hw_params)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ranj063 my traces show otherwise. I think there is a difference between the IPC DAI_CONFIG and the set_config callback in the dai_driver. See the code, the .set_config callback is used in the .prepare stage.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@plbossart From my trace log, set_config is called before hw_params. Look into the code, dai_set_config is called when we send a IPC with SOF_IPC_DAI_CONFIG cmd, which is in sof_link_load. In short, set_config is called during topology loading stage and hw_params is called during pcm open stage. So set_config should be called before hw_params.
src/include/sof/lib/dai.h
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we need to return an integer if we don't test for errors in the caller?
src/drivers/intel/ssp/ssp.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should enable MCLK and BCLK separately. They are not logically connected.
src/drivers/intel/ssp/ssp.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We probably need a change to the code in https://github.com/thesofproject/sof/blob/c7b75f536e9fcbaba6d647bfe02413a572be82c0/src/drivers/intel/ssp/ssp.c#L632, the component does not become active here so if we call ssp_pre_start a second time the protection does not work
src/drivers/intel/ssp/ssp.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo: trigger
src/drivers/intel/ssp/ssp.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
don't we need to check for the direction to mirror what happens line 876? if the playback and capture are started separately we need to stop the SSP when both are stopped.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do we need this here again? we're doing this already in hw_params() too
|
@bardliao I think this is a good feature. I've worked on codecs in the past that would need the BCLK & FRAME clock enabled to do any I2C IO. Would this change also support such codecs ? |
Thanks @plbossart All comments are addressed. |
Yes, but this PR doesn't change FRAME clock enabled time. I wasn't aware any codec need FRAME clock to do I2C IO. We may need to add a new clks_control bit to handle such case. |
Add two clks_control bits. MCLK and/or BCLK will start during hw_params and stop during hw_free if the corresponding bit is set. Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
So that we can stop ssp clock in dai_reset. Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
plbossart
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the state management needs a bit more work I think, it's not clear why we use ACTIVE and PREPARE in similar steps.
src/drivers/intel/ssp/ssp.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think that test is valid for the early start. the ACTVE state is set in the trigger case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think that test is valid for the early start. the ACTVE state is set in the trigger case.
ssp_pre_start() is only called by ssp_start() now, so it is not used for the early start.
src/drivers/intel/ssp/ssp.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should have some sort of symmetry in the function names between bclk_set and release_bclk? get/put, acquire/release, etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should have some sort of symmetry in the function names between bclk_set and release_bclk? get/put, acquire/release, etc.
added ssp_release_bclk and ssp_release_mclk
src/drivers/intel/ssp/ssp.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why use == PREPARE and != ACTIVE is the two different bclk and mclk cases? the state management isn't clear to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why use == PREPARE and != ACTIVE is the two different bclk and mclk cases? the state management isn't clear to me.
That was copied from ssp_post_stop(). I will change it to == COMP_STATE_PREPARE. I also thing using == COMP_STATE_ACTIVE to test if clock is already active is not right. The clock will keep active when ssp->state = COMP_STATE_PAUSED. @keyonjie what do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why use == PREPARE and != ACTIVE is the two different bclk and mclk cases? the state management isn't clear to me.
That was copied from
ssp_post_stop(). I will change it to== COMP_STATE_PREPARE. I also thing using== COMP_STATE_ACTIVEto test if clock is already active is not right. The clock will keep active when ssp->state = COMP_STATE_PAUSED. @keyonjie what do you think?
yes, we can't use the logic of pre_start/post_stop directly here, but we do need check here to avoid set/release clocks when not needed, imagine that when the playback has already enabled mclk/bclk, we should not try to enable them again when a arecord on the same SSP port arrives.
src/drivers/intel/ssp/ssp.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
have you checked that the hw_params is called after set_config? if not, the values will be uninitialized.
src/drivers/intel/ssp/ssp.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no need to init?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no need to init?
We need to init because ret = mn_set_bclk() is only called if CONFIG_INTEL_MN
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there's something weird there: in the #else case below if the condition isn't satisfied we print an error message and jump to out, but we don't set ret... Is that correct?
src/drivers/intel/ssp/ssp.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return ssp_set_bclk(dai)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe just remove if (ret < 0) return ret; below
src/drivers/intel/ssp/ssp.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do we need this here again? we're doing this already in hw_params() too
src/drivers/intel/ssp/ssp.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Im getting super confused here. We do the same things in ssp_hw_params() and ssp_pre_start(). Why do we need to do these twice?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Im getting super confused here. We do the same things in ssp_hw_params() and ssp_pre_start(). Why do we need to do these twice?
They are not called twice. We do them in ssp_hw_params() if SOF_DAI_INTEL_SSP_CLKCTRL_BCLK_ES is set, and do them in ssp_pre_start() if SOF_DAI_INTEL_SSP_CLKCTRL_BCLK_ES is not set. And same thing as MCLK.
When I checked with our hardware folks on the SSP capabilities, the answer was that the BLCK and FSYNC start at the same time when you set the SSE bit. We clearly do not have the ability to start e.g. FSYNC without BCLK also being enabled. That said, I've see weird things and delays in my experiments so I am not completely sure of the dependencies between the two types of clocks. |
We will enable/disable ssp clock in the ops. Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Some codecs need ssp clock to start before codec is initialized and stop after codec is down. Use SOF_DAI_INTEL_SSP_CLKCTRL_MCLK_ES and SOF_DAI_INTEL_SSP_CLKCTRL_BCLK_ES bits to start MCLK/BCLK during hw_parames and stop during hw_free. Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
@plbossart I upload some topologies change, but I don't know if the change of nocodec should go into upstream or not. |
@plbossart I tested it with below change on kernel side. So that I can check the clock easier. I do see the PR take effect on both start and stop. But MCLK always stop when DSP is off with or without this PR. diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c
index c9ea05c643c3..6471b8a27bcc 100644
--- a/sound/soc/sof/pcm.c
+++ b/sound/soc/sof/pcm.c
@@ -268,6 +268,9 @@ static int sof_pcm_hw_params(struct snd_soc_component *component,
return ret;
}
+ pr_err("bard: %s sleep start\n", __func__);
+ msleep(2000);
+ pr_err("bard: %s sleep end\n", __func__);
ret = sof_pcm_dsp_params(spcm, substream, &ipc_params_reply);
if (ret < 0)
return ret;
@@ -467,6 +470,9 @@ static int sof_pcm_trigger(struct snd_soc_component *component,
/* free PCM if reset_hw_params is set and the STOP IPC is successful */
if (!ret && reset_hw_params) {
+ pr_err("bard: %s sleep start\n", __func__);
+ msleep(5000);
+ pr_err("bard: %s sleep end\n", __func__);
ret = sof_pcm_dsp_pcm_free(substream, sdev, spcm);
if (ret < 0)
return ret; |
Define the SSP_CC_MCLK/BCLK_ES bit to be used in SSP_CONFIG_DATA macro to enable mclk/bclk on hw_params and disable malk/bclk on hw_free. Signed-off-by: Brent Lu <brent.lu@intel.com> Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Set clks_control to (SOF_DAI_INTEL_SSP_CLKCTRL_MCLK_ES | SOF_DAI_INTEL_SSP_CLKCTRL_BCLK_ES) to enable MCLK/BCLK early start feature. Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Set clks_control to (SOF_DAI_INTEL_SSP_CLKCTRL_MCLK_ES | SOF_DAI_INTEL_SSP_CLKCTRL_BCLK_ES) to enable MCLK/BCLK early start feature. Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Enable the bclk clock contrl for SSP2. The 10ms bclk delay is no longer needed since bclk is enabled eariler on hw_params. Signed-off-by: Brent Lu <brent.lu@intel.com> Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
|
@bardliao I don't know what I could be doing wrong, but I tried this PR multiple times and I don't see a difference on UP2-nocodec. the bclk and fsync start 4.2ms before the data and stop 18ms later. I suspect a configuration issue since the kernel patch above does not apply on any of my branches. Can you please state which SHA1s you are using for firmware/topology and kernel? |
|
Answering to my own question, it seems the clock control is not properly setup on Up2-nocodec: clks_control 0x40 means only the MCLK is set (BIT6). BCLK is not set, wondering if this is an m4 issue |
|
@bardliao I can confirm that the nocodec M4 stuff does not work with the MCLK | BCLK case. Using BCLK_ES only gives me the right config with BIT(7) set. That said, when I add you kernel patch to add a 1s delay on startup, I see it but on bclk only. Somehow the FSYNC starts with the data, that's not aligned with what the documentation says. Can you confirm if you've seen the FSYNC also toggle earlier than the data and start at the same time as BCLK? |
|
@bardliao see below the patch I used to see something in nocodec mode. Maybe this is missing an 'eval' for M4 to do the bitwise OR. @ranj063 can you help? diff --git a/tools/topology/sof-apl-nocodec.m4 b/tools/topology/sof-apl-nocodec.m4
index e32bc753b..e8de3731f 100644
--- a/tools/topology/sof-apl-nocodec.m4
+++ b/tools/topology/sof-apl-nocodec.m4
@@ -273,7 +273,7 @@ DAI_CONFIG(SSP, 0, 0, NoCodec-0,
SSP_TDM(2, 16, 3, 3),
dnl SSP_CONFIG_DATA(type, dai_index, valid bits, mclk_id, quirks)
SSP_CONFIG_DATA(SSP, 0, 16, 0, SSP_QUIRK_LBM, 0,
- SSP_CC_MCLK_ES | SSP_CC_BCLK_ES)))
+ SSP_CC_BCLK_ES)))
DAI_CONFIG(SSP, 1, 1, NoCodec-1,
SSP_CONFIG(I2S, SSP_CLOCK(mclk, 24576000, codec_mclk_in),
@@ -281,7 +281,7 @@ DAI_CONFIG(SSP, 1, 1, NoCodec-1,
SSP_CLOCK(fsync, 48000, codec_slave),
SSP_TDM(2, 16, 3, 3),
SSP_CONFIG_DATA(SSP, 1, 16, 0, SSP_QUIRK_LBM, 0,
- SSP_CC_MCLK_ES | SSP_CC_BCLK_ES)))
+ SSP_CC_BCLK_ES)))
#DAI_CONFIG(SSP, 2, 2, NoCodec-2,
# SSP_CONFIG(I2S, SSP_CLOCK(mclk, 24576000, codec_mclk_in),
@@ -289,7 +289,7 @@ DAI_CONFIG(SSP, 1, 1, NoCodec-1,
# SSP_CLOCK(fsync, 48000, codec_slave),
# SSP_TDM(2, 16, 3, 3),
# SSP_CONFIG_DATA(SSP, 2, 16, 0, SSP_QUIRK_LBM, 0,
-# SSP_CC_MCLK_ES | SSP_CC_BCLK_ES)))
+# SSP_CC_BCLK_ES)))
DAI_CONFIG(SSP, 3, 3, NoCodec-3,
SSP_CONFIG(I2S, SSP_CLOCK(mclk, 24576000, codec_mclk_in),
@@ -297,7 +297,7 @@ DAI_CONFIG(SSP, 3, 3, NoCodec-3,
SSP_CLOCK(fsync, 48000, codec_slave),
SSP_TDM(2, 16, 3, 3),
SSP_CONFIG_DATA(SSP, 3, 16, 0, SSP_QUIRK_LBM, 0,
- SSP_CC_MCLK_ES | SSP_CC_BCLK_ES)))
+ SSP_CC_BCLK_ES)))
#DAI_CONFIG(SSP, 4, 4, NoCodec-4,
# SSP_CONFIG(I2S, SSP_CLOCK(mclk, 24576000, codec_mclk_in),
@@ -305,7 +305,7 @@ DAI_CONFIG(SSP, 3, 3, NoCodec-3,
# SSP_CLOCK(fsync, 48000, codec_slave),
# SSP_TDM(2, 16, 3, 3),
# SSP_CONFIG_DATA(SSP, 4, 16, 0, SSP_QUIRK_LBM, 0,
-# SSP_CC_MCLK_ES | SSP_CC_BCLK_ES)))
+# SSP_CC_BCLK_ES)))
DAI_CONFIG(SSP, 5, 5, NoCodec-5,
SSP_CONFIG(I2S, SSP_CLOCK(mclk, 24576000, codec_mclk_in),
@@ -313,7 +313,7 @@ DAI_CONFIG(SSP, 5, 5, NoCodec-5,
SSP_CLOCK(fsync, 48000, codec_slave),
SSP_TDM(2, 16, 3, 3),
SSP_CONFIG_DATA(SSP, 5, 16, 0, SSP_QUIRK_LBM, 0,
- SSP_CC_MCLK_ES | SSP_CC_BCLK_ES)))
+ SSP_CC_BCLK_ES)))
DAI_CONFIG(DMIC, 0, 6, NoCodec-6,
dnl DMIC_CONFIG(driver_version, clk_min, clk_mac, duty_min, duty_max, |
@plbossart can you please try this: |
Doesn't M4 support bitwise OR? https://www.gnu.org/software/m4/manual/m4-1.4.15/html_node/Eval.html#Eval |
yeah it does but the end result is the same in this case right? |
|
There is a problem found. On Chrome-v4.14, our hw_free is called from the CPU DAI of FE DAI Link which is earlier than codec driver's call-back which is on CODEC DAI of BE DAI Link. [ 69.321714] sound pcmC0D1p: snd_pcm_common_ioctl: DRAIN [ 69.663541] cs42l42 i2c-10134242:00: cs42l42_mute_stream: On SOF Linux, I found the PCM_FREE command is sent even earlier... [ 256.423305] sound pcmC0D0p: snd_pcm_common_ioctl: DROP I add a DAI_HW_FREE ipc command in BE DAI's hw_free(). It still comes before codec dai's hw_free() but after codec dai's mute_stream(). So the codec driver could do something there before we disable clocks. |
|
@plbossart @bardliao sorry I was wrong about fsync, it does not come with bclk Yellow line is the bclk, you can see it start toggling long before the fsync because the SSE bit is set in hw_params Blue one is the fsync and the purple is the data. Not sure why there is a zero sample before the pcm data we want to send. Regards, |
Sorry, I only tested it with 0xc0, but not MCLK | BCLK. I thought they are the same.
No, FSYNC always starts with DATA on my side CH1: DATA |
|
Thanks for the comments @bardliao @brentlu. I think we have to double-check the results with our hardware friends. For the hw_free problem, I am not sure if there is a solution. Even the firmware only deals with the hw_free during the BE dailink hw_free, the clock will always be stopped before the codec hw_free. The codec would need to switch clocks in an earlier step. |
|
@plbossart yes, i finally understand why cs42l42 switches PLL in mute_stream() callback because their hw_free() is always too late regardless platform. |
|
|
||
| dnl SSP_CONFIG_DATA(type, idx, valid bits, mclk_id, quirks, bclk_delay, | ||
| dnl clks_control, pulse_width, padding) | ||
| dnl mclk_id, quirks, bclk_delay clks_control, pulse_width and padding are optional |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's incomplete...we need to modify the SSP_CONFIG_DATA macro here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@plbossart I think the issue is that 636cbef is already on the main branch, but @brentlu was testing with glk-012-stable-branch branch where 636cbef is not there.
src/drivers/intel/ssp/ssp.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there's something weird there: in the #else case below if the condition isn't satisfied we print an error message and jump to out, but we don't set ret... Is that correct?
src/drivers/intel/ssp/ssp.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if my above suspicion is correct and ret should be negative when jumping to out, then you can just move this assignment above out: and remove the if
| static int ssp_pre_start(struct dai *dai) | ||
| { | ||
| struct ssp_pdata *ssp = dai_get_drvdata(dai); | ||
| int ret = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here the initialisation is indeed redundant
| * ssp_mclk/bclk_prepare_enable/disable functions | ||
| */ | ||
| if (!(ssp->params.clks_control & | ||
| SOF_DAI_INTEL_SSP_CLKCTRL_MCLK_ES)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wrong indentation here and below
|
@bardliao @plbossart should this be closed in favour of #4288 ? |
yes I think so. #4288 is based on @bardliao 's work so it's not like we have a disagreement. |





Some codecs need ssp clock start earlier and stop later.
I didn't measure the clock yet, will do it soon.
@brentlu Can you test it on your side, too?