From f6a1e4ecd41b7e1bbf8157709d3016b2e667ff6a Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 3 Jun 2021 10:32:49 -0500 Subject: [PATCH 1/5] ASoC: SOF: dai: mirror group_id definition added in firmware This was added in ABI 3.17 but never added to the kernel tree. The group_id is not currently used but this patch is required before additional changes. Signed-off-by: Pierre-Louis Bossart --- include/sound/sof/dai.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/sound/sof/dai.h b/include/sound/sof/dai.h index 6bb403e8c5ee79..ea6dc970c18fbe 100644 --- a/include/sound/sof/dai.h +++ b/include/sound/sof/dai.h @@ -69,7 +69,8 @@ struct sof_ipc_dai_config { /* physical protocol and clocking */ uint16_t format; /**< SOF_DAI_FMT_ */ - uint16_t reserved16; /**< alignment */ + uint8_t group_id; /**< group ID, 0 means no group (ABI 3.17) */ + uint8_t reserved8; /**< alignment */ /* reserved for future use */ uint32_t reserved[8]; From af70ccd281188d65f06b6be2f11344d74c95946e Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Wed, 2 Jun 2021 11:33:15 -0500 Subject: [PATCH 2/5] ASoC: SOF: Intel: hda-dai: configure SSP in prepare stage If a system suspend happens (e.g. with rtcwake in tests) while playback/capture is on-going, the hw_params step is not invoked on resume. Other dais such as HDA and ALH/SoundWire use both the .hw_params and the .prepare stage, but in the latter case use a state variable to detect the difference between underflows and resume operations due to restrictions on programming sequences. For the SSP it's fine to only do the configuration in the .prepare step. Signed-off-by: Pierre-Louis Bossart --- sound/soc/sof/intel/hda-dai.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/sound/soc/sof/intel/hda-dai.c b/sound/soc/sof/intel/hda-dai.c index fb1b429cc451bc..371dedb542ed14 100644 --- a/sound/soc/sof/intel/hda-dai.c +++ b/sound/soc/sof/intel/hda-dai.c @@ -479,9 +479,8 @@ static int ssp_dai_setup_or_free(struct snd_pcm_substream *substream, struct snd return hda_ctrl_dai_widget_free(w); } -static int ssp_dai_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai) +static int ssp_dai_prepare(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) { return ssp_dai_setup_or_free(substream, dai, true); } @@ -493,7 +492,7 @@ static int ssp_dai_hw_free(struct snd_pcm_substream *substream, } static const struct snd_soc_dai_ops ssp_dai_ops = { - .hw_params = ssp_dai_hw_params, + .prepare = ssp_dai_prepare, .hw_free = ssp_dai_hw_free, }; From e7fdfb2a1cf5e093890f405573a07b3ede0d9a15 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Tue, 1 Jun 2021 17:01:33 -0500 Subject: [PATCH 3/5] ASoC: SOF: dai: include new flags for DAI_CONFIG Mirror changes done in SOF tree. The changes do not rely on BIT/GENMASK on purpose to keep the structure and flags common with the firmware tree. The DAI_CONFIG IPC is currently used in multiple ways. It is sent to the DSP firmware when enabling static or dynamic pipelines, in hw_params or prepare callbacks for Intel SSP, HDaudio and ALH, on trigger_stop and hw_free. This IPC has been abused a bit in the past, i.e. the values used for some of the DAI-specific fields are used to either allocate or free resources. Two typical examples are Intel HDaudio and SoundWire/ALH DAIs, where using a zero DMA channel number or stream tag signals to the firmware the DMA channels or tags allocated earlier can be freed. Rather than add a new IPC for 'hw_params' and 'hw_free', this patch suggests supporting a 2-bit value conveying the 'stage' information in an existing IPC structure. Only 3 possible values are used. The mapping between HW_PARAMS and HW_FREE flags and ALSA definitions is not strictly 1:1, e.g. in some cases the HW_PARAM flag might be set during the .prepare callback, while the HW_FREE might be sent during the ALSA .trigger for stop/suspend. The semantics of the flags is to reserve and start/stop all needed resources, typically hardware related such as DMAs or clocks, when the HW_PARAMS is set, while the HW_FREE flag allows the firmware to release the resources allocated. The data transfers are still controlled within the firmware through the propagation of the trigger command. The driver can then pass information that the DAI_CONFIG was invoked in e.g. a pipeline/DAI setup, hw_params or hw_free stage without having to use a special DAI-specific encoding. Unfortunately we can't remove old encodings due to backwards-compatibility requirements but for new cases, such as the SSP in follow-up patches, we can make the IPC less cryptic. This change is tagged as ABI 3.19 and is completely backwards compatible. Signed-off-by: Pierre-Louis Bossart --- include/sound/sof/dai.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/include/sound/sof/dai.h b/include/sound/sof/dai.h index ea6dc970c18fbe..9625f47557b8ef 100644 --- a/include/sound/sof/dai.h +++ b/include/sound/sof/dai.h @@ -50,6 +50,13 @@ #define SOF_DAI_FMT_INV_MASK 0x0f00 #define SOF_DAI_FMT_CLOCK_PROVIDER_MASK 0xf000 +/* DAI_CONFIG flags */ +#define SOF_DAI_CONFIG_FLAGS_MASK 0x3 +#define SOF_DAI_CONFIG_FLAGS_NONE (0 << 0) /**< DAI_CONFIG sent without stage information */ +#define SOF_DAI_CONFIG_FLAGS_HW_PARAMS (1 << 0) /**< DAI_CONFIG sent during hw_params stage */ +#define SOF_DAI_CONFIG_FLAGS_HW_FREE (2 << 0) /**< DAI_CONFIG sent during hw_free stage */ +#define SOF_DAI_CONFIG_FLAGS_RFU (3 << 0) /**< not used, reserved for future use */ + /** \brief Types of DAI */ enum sof_ipc_dai_type { SOF_DAI_INTEL_NONE = 0, /**< None */ @@ -70,7 +77,7 @@ struct sof_ipc_dai_config { /* physical protocol and clocking */ uint16_t format; /**< SOF_DAI_FMT_ */ uint8_t group_id; /**< group ID, 0 means no group (ABI 3.17) */ - uint8_t reserved8; /**< alignment */ + uint8_t flags; /**< SOF_DAI_CONFIG_FLAGS_ (ABI 3.19) */ /* reserved for future use */ uint32_t reserved[8]; From b7587ac315349bf531ff4d7fc6e362050fdbf8a8 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Tue, 1 Jun 2021 17:04:32 -0500 Subject: [PATCH 4/5] ASoC: SOF: Intel: hda: add new flags for DAI_CONFIG The DAI_CONFIG is used for both hw_params and hw_free. Use flags to specify what stage the configuration applies to. the DAI_CONFIG IPC may be sent also during the widget setup so each flag is cleared after the IPC to restore the state. Signed-off-by: Pierre-Louis Bossart --- sound/soc/sof/intel/hda.c | 10 ++++++++++ sound/soc/sof/sof-audio.c | 5 +++++ 2 files changed, 15 insertions(+) diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index 447c82b227db91..f2ebf1dace349a 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -71,6 +71,11 @@ int hda_ctrl_dai_widget_setup(struct snd_soc_dapm_widget *w) return ret; } + /* set HW_PARAMS flag */ + set_mask_bits(&config->flags, + SOF_DAI_CONFIG_FLAGS_MASK, + SOF_DAI_CONFIG_FLAGS_HW_PARAMS); + /* send DAI_CONFIG IPC */ ret = sof_ipc_tx_message(sdev->ipc, config->hdr.cmd, config, config->hdr.size, &reply, sizeof(reply)); @@ -107,6 +112,11 @@ int hda_ctrl_dai_widget_free(struct snd_soc_dapm_widget *w) config = &sof_dai->dai_config[sof_dai->current_config]; + /* set HW_FREE flag */ + set_mask_bits(&config->flags, + SOF_DAI_CONFIG_FLAGS_MASK, + SOF_DAI_CONFIG_FLAGS_HW_FREE); + ret = sof_ipc_tx_message(sdev->ipc, config->hdr.cmd, config, config->hdr.size, &reply, sizeof(reply)); if (ret < 0) { diff --git a/sound/soc/sof/sof-audio.c b/sound/soc/sof/sof-audio.c index 5f5c034769327a..f06d6b32882307 100644 --- a/sound/soc/sof/sof-audio.c +++ b/sound/soc/sof/sof-audio.c @@ -55,6 +55,11 @@ static int sof_dai_config_setup(struct snd_sof_dev *sdev, struct snd_sof_dai *da return -EINVAL; } + /* set NONE flag to clear all previous settings */ + set_mask_bits(&config->flags, + SOF_DAI_CONFIG_FLAGS_MASK, + SOF_DAI_CONFIG_FLAGS_NONE); + ret = sof_ipc_tx_message(sdev->ipc, config->hdr.cmd, config, config->hdr.size, &reply, sizeof(reply)); From a518c19b95dd745a16872528a292e862acfe97f1 Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Tue, 25 May 2021 19:25:32 +0800 Subject: [PATCH 5/5] ASoC: SOF: dai-intel: add SOF_DAI_INTEL_SSP_CLKCTRL_MCLK/BCLK_ES bits 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. While the kernel does not do anything with these bitfields, this is also tagged as part of the ABI 3.19 changes. Signed-off-by: Bard Liao --- include/sound/sof/dai-intel.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/sound/sof/dai-intel.h b/include/sound/sof/dai-intel.h index 136adf6686e267..7a266f41983cb4 100644 --- a/include/sound/sof/dai-intel.h +++ b/include/sound/sof/dai-intel.h @@ -48,6 +48,10 @@ #define SOF_DAI_INTEL_SSP_CLKCTRL_FS_KA BIT(4) /* bclk idle */ #define SOF_DAI_INTEL_SSP_CLKCTRL_BCLK_IDLE_HIGH BIT(5) +/* mclk early start */ +#define SOF_DAI_INTEL_SSP_CLKCTRL_MCLK_ES BIT(6) +/* bclk early start */ +#define SOF_DAI_INTEL_SSP_CLKCTRL_BCLK_ES BIT(7) /* DMIC max. four controllers for eight microphone channels */ #define SOF_DAI_INTEL_DMIC_NUM_CTRL 4