Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 53 additions & 64 deletions sound/soc/codecs/lpass-va-macro.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/pm_clock.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <sound/soc.h>
Expand Down Expand Up @@ -1343,18 +1344,22 @@ static int fsgen_gate_enable(struct clk_hw *hw)
struct regmap *regmap = va->regmap;
int ret;

if (va->has_swr_master) {
ret = clk_prepare_enable(va->mclk);
if (ret)
return ret;
ret = pm_runtime_get_sync(va->dev);
if (ret < 0) {
pm_runtime_put_noidle(va->dev);
return ret;
}

ret = va_macro_mclk_enable(va, true);
if (ret) {
pm_runtime_put_noidle(va->dev);
return ret;
}
if (va->has_swr_master)
regmap_update_bits(regmap, CDC_VA_CLK_RST_CTRL_SWR_CONTROL,
CDC_VA_SWR_CLK_EN_MASK, CDC_VA_SWR_CLK_ENABLE);

return ret;
return 0;
}

static void fsgen_gate_disable(struct clk_hw *hw)
Expand All @@ -1367,8 +1372,24 @@ static void fsgen_gate_disable(struct clk_hw *hw)
CDC_VA_SWR_CLK_EN_MASK, 0x0);

va_macro_mclk_enable(va, false);
if (va->has_swr_master)
clk_disable_unprepare(va->mclk);

pm_runtime_mark_last_busy(va->dev);
pm_runtime_put_autosuspend(va->dev);
}

static int va_macro_setup_pm_clocks(struct device *dev, struct va_macro *va)
{
int ret;

ret = devm_pm_clk_create(dev);
if (ret)
return ret;

ret = of_pm_clk_add_clks(dev);
if (ret < 0)
return ret;

return 0;
}

static int fsgen_gate_is_enabled(struct clk_hw *hw)
Expand Down Expand Up @@ -1505,6 +1526,7 @@ static int va_macro_probe(struct platform_device *pdev)
void __iomem *base;
u32 sample_rate = 0;
int ret;
int rpm_ret;

va = devm_kzalloc(dev, sizeof(*va), GFP_KERNEL);
if (!va)
Expand Down Expand Up @@ -1572,22 +1594,18 @@ static int va_macro_probe(struct platform_device *pdev)
clk_set_rate(va->npl, 2 * VA_MACRO_MCLK_FREQ);
}

ret = clk_prepare_enable(va->macro);
if (ret)
goto err;

ret = clk_prepare_enable(va->dcodec);
ret = va_macro_setup_pm_clocks(dev, va);
if (ret)
goto err_dcodec;
goto err_rpm_disable;

ret = clk_prepare_enable(va->mclk);
if (ret)
goto err_mclk;
pm_runtime_set_autosuspend_delay(dev, 3000);
pm_runtime_use_autosuspend(dev);
pm_runtime_enable(dev);

if (va->has_npl_clk) {
ret = clk_prepare_enable(va->npl);
if (ret)
goto err_npl;
rpm_ret = pm_runtime_resume_and_get(dev);
if (rpm_ret < 0) {
ret = rpm_ret;
goto err_rpm_disable;
}

/**
Expand Down Expand Up @@ -1626,35 +1644,27 @@ static int va_macro_probe(struct platform_device *pdev)
va_macro_dais,
ARRAY_SIZE(va_macro_dais));
if (ret)
goto err_clkout;

pm_runtime_set_autosuspend_delay(dev, 3000);
pm_runtime_use_autosuspend(dev);
pm_runtime_mark_last_busy(dev);
pm_runtime_set_active(dev);
pm_runtime_enable(dev);
goto err_rpm_put;

ret = va_macro_register_fsgen_output(va);
if (ret)
goto err_clkout;
goto err_rpm_put;

va->fsgen = devm_clk_hw_get_clk(dev, &va->hw, "fsgen");
if (IS_ERR(va->fsgen)) {
ret = PTR_ERR(va->fsgen);
goto err_clkout;
goto err_rpm_put;
}

pm_runtime_mark_last_busy(dev);
pm_runtime_put_autosuspend(dev);

return 0;

err_clkout:
if (va->has_npl_clk)
clk_disable_unprepare(va->npl);
err_npl:
clk_disable_unprepare(va->mclk);
err_mclk:
clk_disable_unprepare(va->dcodec);
err_dcodec:
clk_disable_unprepare(va->macro);
err_rpm_put:
pm_runtime_put_noidle(dev);
err_rpm_disable:
pm_runtime_disable(dev);
err:
lpass_macro_pds_exit(va->pds);

Expand All @@ -1665,12 +1675,7 @@ static void va_macro_remove(struct platform_device *pdev)
{
struct va_macro *va = dev_get_drvdata(&pdev->dev);

if (va->has_npl_clk)
clk_disable_unprepare(va->npl);

clk_disable_unprepare(va->mclk);
clk_disable_unprepare(va->dcodec);
clk_disable_unprepare(va->macro);
pm_runtime_disable(&pdev->dev);

lpass_macro_pds_exit(va->pds);
}
Expand All @@ -1682,38 +1687,22 @@ static int va_macro_runtime_suspend(struct device *dev)
regcache_cache_only(va->regmap, true);
regcache_mark_dirty(va->regmap);

if (va->has_npl_clk)
clk_disable_unprepare(va->npl);

clk_disable_unprepare(va->mclk);

return 0;
return pm_clk_suspend(dev);
}

static int va_macro_runtime_resume(struct device *dev)
{
struct va_macro *va = dev_get_drvdata(dev);
int ret;

ret = clk_prepare_enable(va->mclk);
if (ret) {
dev_err(va->dev, "unable to prepare mclk\n");
ret = pm_clk_resume(dev);
if (ret)
return ret;
}

if (va->has_npl_clk) {
ret = clk_prepare_enable(va->npl);
if (ret) {
clk_disable_unprepare(va->mclk);
dev_err(va->dev, "unable to prepare npl\n");
return ret;
}
}

regcache_cache_only(va->regmap, false);
regcache_sync(va->regmap);

return 0;
return regcache_sync(va->regmap);
}


Expand Down
121 changes: 39 additions & 82 deletions sound/soc/codecs/lpass-wsa-macro.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <sound/soc-dapm.h>
#include <linux/pm_runtime.h>
#include <linux/of_platform.h>
#include <linux/pm_clock.h>
#include <sound/tlv.h>

#include "lpass-macro-common.h"
Expand Down Expand Up @@ -2638,15 +2639,15 @@ static const struct snd_soc_dapm_route wsa_audio_map[] = {
static int wsa_swrm_clock(struct wsa_macro *wsa, bool enable)
{
struct regmap *regmap = wsa->regmap;
int ret;

if (enable) {
int ret;
ret = pm_runtime_get_sync(wsa->dev);
if (ret < 0) {
pm_runtime_put_noidle(wsa->dev);
return ret;
}

ret = clk_prepare_enable(wsa->mclk);
if (ret) {
dev_err(wsa->dev, "failed to enable mclk\n");
return ret;
}
if (enable) {
wsa_macro_mclk_enable(wsa, true);

regmap_update_bits(regmap, CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
Expand All @@ -2657,9 +2658,10 @@ static int wsa_swrm_clock(struct wsa_macro *wsa, bool enable)
regmap_update_bits(regmap, CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
CDC_WSA_SWR_CLK_EN_MASK, 0);
wsa_macro_mclk_enable(wsa, false);
clk_disable_unprepare(wsa->mclk);
}

pm_runtime_mark_last_busy(wsa->dev);
pm_runtime_put_autosuspend(wsa->dev);
return 0;
}

Expand Down Expand Up @@ -2883,27 +2885,26 @@ static int wsa_macro_probe(struct platform_device *pdev)

/* set MCLK and NPL rates */
clk_set_rate(wsa->mclk, WSA_MACRO_MCLK_FREQ);
clk_set_rate(wsa->npl, WSA_MACRO_MCLK_FREQ);
if (wsa->npl)
clk_set_rate(wsa->npl, WSA_MACRO_MCLK_FREQ);

ret = clk_prepare_enable(wsa->macro);
ret = devm_pm_clk_create(dev);
if (ret)
goto err;
return ret;

ret = clk_prepare_enable(wsa->dcodec);
if (ret)
goto err_dcodec;
ret = of_pm_clk_add_clks(dev);
if (ret < 0)
return ret;

ret = clk_prepare_enable(wsa->mclk);
if (ret)
goto err_mclk;
pm_runtime_set_autosuspend_delay(dev, 3000);
pm_runtime_use_autosuspend(dev);
pm_runtime_enable(dev);

ret = clk_prepare_enable(wsa->npl);
if (ret)
goto err_npl;

ret = clk_prepare_enable(wsa->fsgen);
if (ret)
goto err_fsgen;
ret = pm_runtime_resume_and_get(dev);
if (ret < 0) {
goto err_rpm_disable;
}

/* reset swr ip */
regmap_update_bits(wsa->regmap, CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
Expand All @@ -2920,44 +2921,26 @@ static int wsa_macro_probe(struct platform_device *pdev)
wsa_macro_dai,
ARRAY_SIZE(wsa_macro_dai));
if (ret)
goto err_clkout;

pm_runtime_set_autosuspend_delay(dev, 3000);
pm_runtime_use_autosuspend(dev);
pm_runtime_mark_last_busy(dev);
pm_runtime_set_active(dev);
pm_runtime_enable(dev);
goto err_rpm_put;

ret = wsa_macro_register_mclk_output(wsa);
if (ret)
goto err_clkout;
goto err_rpm_put;

return 0;
pm_runtime_mark_last_busy(dev);
pm_runtime_put_autosuspend(dev);

err_clkout:
clk_disable_unprepare(wsa->fsgen);
err_fsgen:
clk_disable_unprepare(wsa->npl);
err_npl:
clk_disable_unprepare(wsa->mclk);
err_mclk:
clk_disable_unprepare(wsa->dcodec);
err_dcodec:
clk_disable_unprepare(wsa->macro);
err:
return 0;
err_rpm_put:
pm_runtime_put_noidle(dev);
err_rpm_disable:
pm_runtime_disable(dev);
return ret;

}

static void wsa_macro_remove(struct platform_device *pdev)
{
struct wsa_macro *wsa = dev_get_drvdata(&pdev->dev);

clk_disable_unprepare(wsa->macro);
clk_disable_unprepare(wsa->dcodec);
clk_disable_unprepare(wsa->mclk);
clk_disable_unprepare(wsa->npl);
clk_disable_unprepare(wsa->fsgen);
pm_runtime_disable(&pdev->dev);
}

static int wsa_macro_runtime_suspend(struct device *dev)
Expand All @@ -2967,46 +2950,20 @@ static int wsa_macro_runtime_suspend(struct device *dev)
regcache_cache_only(wsa->regmap, true);
regcache_mark_dirty(wsa->regmap);

clk_disable_unprepare(wsa->fsgen);
clk_disable_unprepare(wsa->npl);
clk_disable_unprepare(wsa->mclk);

return 0;
return pm_clk_suspend(dev);
}

static int wsa_macro_runtime_resume(struct device *dev)
{
struct wsa_macro *wsa = dev_get_drvdata(dev);
int ret;

ret = clk_prepare_enable(wsa->mclk);
if (ret) {
dev_err(dev, "unable to prepare mclk\n");
return ret;
}

ret = clk_prepare_enable(wsa->npl);
if (ret) {
dev_err(dev, "unable to prepare mclkx2\n");
goto err_npl;
}

ret = clk_prepare_enable(wsa->fsgen);
if (ret) {
dev_err(dev, "unable to prepare fsgen\n");
goto err_fsgen;
}

regcache_cache_only(wsa->regmap, false);
regcache_sync(wsa->regmap);

return 0;
err_fsgen:
clk_disable_unprepare(wsa->npl);
err_npl:
clk_disable_unprepare(wsa->mclk);
ret = pm_clk_resume(dev);
if (ret)
return ret;

return ret;
return regcache_sync(wsa->regmap);
}

static const struct dev_pm_ops wsa_macro_pm_ops = {
Expand Down