From 5de0472da9d3a7a635f995204cded4d1d9171e3e Mon Sep 17 00:00:00 2001 From: Meng Wang Date: Tue, 1 Sep 2020 15:41:37 +0800 Subject: [PATCH] asoc: bolero: switch clk to VA_CLK for LPI SVA When switching TX_CLK to VA_CLK, there could be some IRQ missing with current design. Switch the clk in bolero to avoid the corner case. Change-Id: Iec5cac16e026e4e46646894c546f1acb3fce4fa8 Signed-off-by: Meng Wang --- asoc/codecs/bolero/bolero-cdc.c | 2 +- asoc/codecs/bolero/tx-macro.c | 48 ++++++++++++++--- asoc/codecs/bolero/va-macro.c | 95 +++++++++++++++++++-------------- 3 files changed, 99 insertions(+), 46 deletions(-) diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index 4ab01eb06ee6..201537190397 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -1068,7 +1068,7 @@ EXPORT_SYMBOL(bolero_register_wake_irq); * * @component: pointer to codec component instance. * - * @clk_src: 0 for TX_RCG and 1 for VA_RCG + * @clk_src: clk source * * Returns 0 on success or -EINVAL on error. */ diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index 5af73081da23..4ea66165efe0 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -179,6 +179,7 @@ struct tx_macro_priv { int amic_sample_rate; bool lpi_enable; bool register_event_listener; + u16 current_clk_id; }; static bool tx_macro_get_data(struct snd_soc_component *component, @@ -1817,11 +1818,11 @@ static const struct snd_soc_dapm_widget tx_macro_dapm_widgets_v3[] = { SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_SUPPLY_S("TX_SWR_CLK", 0, SND_SOC_NOPM, 0, 0, + SND_SOC_DAPM_SUPPLY_S("TX_SWR_CLK", -1, SND_SOC_NOPM, 0, 0, tx_macro_tx_swr_clk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_SUPPLY_S("VA_SWR_CLK", 0, SND_SOC_NOPM, 0, 0, + SND_SOC_DAPM_SUPPLY_S("VA_SWR_CLK", -1, SND_SOC_NOPM, 0, 0, tx_macro_va_swr_clk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), }; @@ -2869,12 +2870,46 @@ static int tx_macro_clk_switch(struct snd_soc_component *component, int clk_src) "%s: priv is null for macro!\n", __func__); return -EINVAL; } - if (tx_priv->swr_ctrl_data) { - ret = swrm_wcd_notify( - tx_priv->swr_ctrl_data[0].tx_swr_pdev, - SWR_REQ_CLK_SWITCH, &clk_src); + dev_dbg(component->dev, + "%s: va_swr_clk_cnt %d, tx_swr_clk_cnt %d, tx_clk_status %d\n", + __func__, tx_priv->va_swr_clk_cnt, + tx_priv->tx_swr_clk_cnt, tx_priv->tx_clk_status); + if (tx_priv->current_clk_id == clk_src) { + dev_dbg(component->dev, + "%s: requested clk %d is same as current\n", + __func__, clk_src); + return 0; + } else if (tx_priv->va_swr_clk_cnt != 0 && tx_priv->tx_clk_status) { + ret = bolero_clk_rsc_request_clock(tx_priv->dev, + TX_CORE_CLK, + clk_src, + true); + if (ret) { + dev_dbg(component->dev, + "%s: request clock %d enable failed\n", + __func__, clk_src); + goto ret; + } + ret = bolero_clk_rsc_request_clock(tx_priv->dev, + TX_CORE_CLK, + tx_priv->current_clk_id, + false); + if (ret) { + dev_dbg(component->dev, + "%s: request clock disable failed\n", + __func__); + bolero_clk_rsc_request_clock(tx_priv->dev, + TX_CORE_CLK, + clk_src, + false); + goto ret; + } + tx_priv->current_clk_id = clk_src; + } else { + ret = -EBUSY; } +ret: return ret; } @@ -3460,6 +3495,7 @@ static int tx_macro_probe(struct platform_device *pdev) tx_macro_init_ops(&ops, tx_io_base); ops.clk_id_req = TX_CORE_CLK; ops.default_clk_id = TX_CORE_CLK; + tx_priv->current_clk_id = TX_CORE_CLK; ret = bolero_register_macro(&pdev->dev, TX_MACRO, &ops); if (ret) { dev_err(&pdev->dev, diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index 13c90fe63244..8e32a46cab78 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -381,7 +381,6 @@ static int va_macro_swr_pwr_event_v2(struct snd_soc_dapm_widget *w, int ret = 0; struct device *va_dev = NULL; struct va_macro_priv *va_priv = NULL; - int clk_src = 0; if (!va_macro_get_data(component, &va_dev, &va_priv, __func__)) return -EINVAL; @@ -394,14 +393,31 @@ static int va_macro_swr_pwr_event_v2(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: - if (va_priv->swr_ctrl_data) { - clk_src = CLK_SRC_VA_RCG; - ret = swrm_wcd_notify( - va_priv->swr_ctrl_data[0].va_swr_pdev, - SWR_REQ_CLK_SWITCH, &clk_src); - if (ret) - dev_dbg(va_dev, "%s: clock switch failed\n", + if (va_priv->default_clk_id != VA_CORE_CLK) { + ret = bolero_clk_rsc_request_clock(va_priv->dev, + va_priv->default_clk_id, + VA_CORE_CLK, + true); + if (ret) { + dev_dbg(component->dev, + "%s: request clock VA_CLK enable failed\n", __func__); + break; + } + ret = bolero_clk_rsc_request_clock(va_priv->dev, + va_priv->default_clk_id, + TX_CORE_CLK, + false); + if (ret) { + dev_dbg(component->dev, + "%s: request clock TX_CLK enable failed\n", + __func__); + bolero_clk_rsc_request_clock(va_priv->dev, + va_priv->default_clk_id, + VA_CORE_CLK, + false); + break; + } } msm_cdc_pinctrl_set_wakeup_capable( va_priv->va_swr_gpio_p, false); @@ -409,14 +425,31 @@ static int va_macro_swr_pwr_event_v2(struct snd_soc_dapm_widget *w, case SND_SOC_DAPM_POST_PMD: msm_cdc_pinctrl_set_wakeup_capable( va_priv->va_swr_gpio_p, true); - if (va_priv->swr_ctrl_data) { - clk_src = CLK_SRC_TX_RCG; - ret = swrm_wcd_notify( - va_priv->swr_ctrl_data[0].va_swr_pdev, - SWR_REQ_CLK_SWITCH, &clk_src); - if (ret) - dev_dbg(va_dev, "%s: clock switch failed\n", + if (va_priv->default_clk_id == TX_CORE_CLK) { + ret = bolero_clk_rsc_request_clock(va_priv->dev, + va_priv->default_clk_id, + TX_CORE_CLK, + true); + if (ret) { + dev_dbg(component->dev, + "%s: request clock TX_CLK disable failed\n", __func__); + break; + } + ret = bolero_clk_rsc_request_clock(va_priv->dev, + va_priv->default_clk_id, + VA_CORE_CLK, + false); + if (ret) { + dev_dbg(component->dev, + "%s: request clock VA_CLK disable failed\n", + __func__); + bolero_clk_rsc_request_clock(va_priv->dev, + TX_CORE_CLK, + TX_CORE_CLK, + false); + break; + } } break; default: @@ -455,10 +488,11 @@ static int va_macro_swr_pwr_event(struct snd_soc_dapm_widget *w, "%s: lpass audio hw enable failed\n", __func__); } - if (!ret) - if (bolero_tx_clk_switch(component, CLK_SRC_VA_RCG)) + if (!ret) { + if (bolero_tx_clk_switch(component, VA_CORE_CLK)) dev_dbg(va_dev, "%s: clock switch failed\n", __func__); + } if (va_priv->lpi_enable && !va_priv->disable_afe_wakeup_event_listener) { bolero_register_event_listener(component, true); @@ -470,7 +504,7 @@ static int va_macro_swr_pwr_event(struct snd_soc_dapm_widget *w, va_priv->register_event_listener = false; bolero_register_event_listener(component, false); } - if (bolero_tx_clk_switch(component, CLK_SRC_TX_RCG)) + if (bolero_tx_clk_switch(component, TX_CORE_CLK)) dev_dbg(va_dev, "%s: clock switch failed\n",__func__); if (va_priv->lpass_audio_hw_vote) digital_cdc_rsc_mgr_hw_vote_disable( @@ -511,7 +545,6 @@ static int va_macro_mclk_event(struct snd_soc_dapm_widget *w, int ret = 0; struct device *va_dev = NULL; struct va_macro_priv *va_priv = NULL; - int clk_src = 0; if (!va_macro_get_data(component, &va_dev, &va_priv, __func__)) return -EINVAL; @@ -533,22 +566,6 @@ static int va_macro_mclk_event(struct snd_soc_dapm_widget *w, break; case SND_SOC_DAPM_POST_PMD: if (va_priv->lpi_enable) { - if (va_priv->version == BOLERO_VERSION_2_1) { - if (va_priv->swr_ctrl_data) { - clk_src = CLK_SRC_TX_RCG; - ret = swrm_wcd_notify( - va_priv->swr_ctrl_data[0].va_swr_pdev, - SWR_REQ_CLK_SWITCH, &clk_src); - if (ret) - dev_dbg(va_dev, - "%s: clock switch failed\n", - __func__); - } - } else if (bolero_tx_clk_switch(component, - CLK_SRC_TX_RCG)) { - dev_dbg(va_dev, "%s: clock switch failed\n", - __func__); - } va_macro_mclk_enable(va_priv, 0, true); } else { bolero_tx_mclk_enable(component, 0); @@ -1946,15 +1963,15 @@ static const struct snd_soc_dapm_widget va_macro_dapm_widgets_v2[] = { VA_MACRO_AIF3_CAP, 0, va_aif3_cap_mixer_v2, ARRAY_SIZE(va_aif3_cap_mixer_v2)), - SND_SOC_DAPM_SUPPLY_S("VA_SWR_PWR", -1, SND_SOC_NOPM, 0, 0, + SND_SOC_DAPM_SUPPLY_S("VA_SWR_PWR", 0, SND_SOC_NOPM, 0, 0, va_macro_swr_pwr_event_v2, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_SUPPLY_S("VA_TX_SWR_CLK", 0, SND_SOC_NOPM, 0, 0, + SND_SOC_DAPM_SUPPLY_S("VA_TX_SWR_CLK", -1, SND_SOC_NOPM, 0, 0, va_macro_tx_swr_clk_event_v2, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_SUPPLY_S("VA_SWR_CLK", 0, SND_SOC_NOPM, 0, 0, + SND_SOC_DAPM_SUPPLY_S("VA_SWR_CLK", -1, SND_SOC_NOPM, 0, 0, va_macro_swr_clk_event_v2, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), }; @@ -1988,7 +2005,7 @@ static const struct snd_soc_dapm_widget va_macro_dapm_widgets_v3[] = { SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_SUPPLY_S("VA_SWR_PWR", -1, SND_SOC_NOPM, 0, 0, + SND_SOC_DAPM_SUPPLY_S("VA_SWR_PWR", 0, SND_SOC_NOPM, 0, 0, va_macro_swr_pwr_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), };