Skip to content

Commit 47f403b

Browse files
authored
ASoC: qcom: lpass: Switch VA/WSA macros to PM clock framework (#463)
ASoC: qcom: lpass: Switch VA/WSA macros to PM clock framework
2 parents 62d00f8 + 480422b commit 47f403b

File tree

2 files changed

+92
-146
lines changed

2 files changed

+92
-146
lines changed

sound/soc/codecs/lpass-va-macro.c

Lines changed: 53 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <linux/of_platform.h>
1111
#include <linux/platform_device.h>
1212
#include <linux/pm_runtime.h>
13+
#include <linux/pm_clock.h>
1314
#include <linux/regmap.h>
1415
#include <linux/regulator/consumer.h>
1516
#include <sound/soc.h>
@@ -1343,18 +1344,22 @@ static int fsgen_gate_enable(struct clk_hw *hw)
13431344
struct regmap *regmap = va->regmap;
13441345
int ret;
13451346

1346-
if (va->has_swr_master) {
1347-
ret = clk_prepare_enable(va->mclk);
1348-
if (ret)
1349-
return ret;
1347+
ret = pm_runtime_get_sync(va->dev);
1348+
if (ret < 0) {
1349+
pm_runtime_put_noidle(va->dev);
1350+
return ret;
13501351
}
13511352

13521353
ret = va_macro_mclk_enable(va, true);
1354+
if (ret) {
1355+
pm_runtime_put_noidle(va->dev);
1356+
return ret;
1357+
}
13531358
if (va->has_swr_master)
13541359
regmap_update_bits(regmap, CDC_VA_CLK_RST_CTRL_SWR_CONTROL,
13551360
CDC_VA_SWR_CLK_EN_MASK, CDC_VA_SWR_CLK_ENABLE);
13561361

1357-
return ret;
1362+
return 0;
13581363
}
13591364

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

13691374
va_macro_mclk_enable(va, false);
1370-
if (va->has_swr_master)
1371-
clk_disable_unprepare(va->mclk);
1375+
1376+
pm_runtime_mark_last_busy(va->dev);
1377+
pm_runtime_put_autosuspend(va->dev);
1378+
}
1379+
1380+
static int va_macro_setup_pm_clocks(struct device *dev, struct va_macro *va)
1381+
{
1382+
int ret;
1383+
1384+
ret = devm_pm_clk_create(dev);
1385+
if (ret)
1386+
return ret;
1387+
1388+
ret = of_pm_clk_add_clks(dev);
1389+
if (ret < 0)
1390+
return ret;
1391+
1392+
return 0;
13721393
}
13731394

13741395
static int fsgen_gate_is_enabled(struct clk_hw *hw)
@@ -1505,6 +1526,7 @@ static int va_macro_probe(struct platform_device *pdev)
15051526
void __iomem *base;
15061527
u32 sample_rate = 0;
15071528
int ret;
1529+
int rpm_ret;
15081530

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

1575-
ret = clk_prepare_enable(va->macro);
1576-
if (ret)
1577-
goto err;
1578-
1579-
ret = clk_prepare_enable(va->dcodec);
1597+
ret = va_macro_setup_pm_clocks(dev, va);
15801598
if (ret)
1581-
goto err_dcodec;
1599+
goto err_rpm_disable;
15821600

1583-
ret = clk_prepare_enable(va->mclk);
1584-
if (ret)
1585-
goto err_mclk;
1601+
pm_runtime_set_autosuspend_delay(dev, 3000);
1602+
pm_runtime_use_autosuspend(dev);
1603+
pm_runtime_enable(dev);
15861604

1587-
if (va->has_npl_clk) {
1588-
ret = clk_prepare_enable(va->npl);
1589-
if (ret)
1590-
goto err_npl;
1605+
rpm_ret = pm_runtime_resume_and_get(dev);
1606+
if (rpm_ret < 0) {
1607+
ret = rpm_ret;
1608+
goto err_rpm_disable;
15911609
}
15921610

15931611
/**
@@ -1626,35 +1644,27 @@ static int va_macro_probe(struct platform_device *pdev)
16261644
va_macro_dais,
16271645
ARRAY_SIZE(va_macro_dais));
16281646
if (ret)
1629-
goto err_clkout;
1630-
1631-
pm_runtime_set_autosuspend_delay(dev, 3000);
1632-
pm_runtime_use_autosuspend(dev);
1633-
pm_runtime_mark_last_busy(dev);
1634-
pm_runtime_set_active(dev);
1635-
pm_runtime_enable(dev);
1647+
goto err_rpm_put;
16361648

16371649
ret = va_macro_register_fsgen_output(va);
16381650
if (ret)
1639-
goto err_clkout;
1651+
goto err_rpm_put;
16401652

16411653
va->fsgen = devm_clk_hw_get_clk(dev, &va->hw, "fsgen");
16421654
if (IS_ERR(va->fsgen)) {
16431655
ret = PTR_ERR(va->fsgen);
1644-
goto err_clkout;
1656+
goto err_rpm_put;
16451657
}
16461658

1659+
pm_runtime_mark_last_busy(dev);
1660+
pm_runtime_put_autosuspend(dev);
1661+
16471662
return 0;
16481663

1649-
err_clkout:
1650-
if (va->has_npl_clk)
1651-
clk_disable_unprepare(va->npl);
1652-
err_npl:
1653-
clk_disable_unprepare(va->mclk);
1654-
err_mclk:
1655-
clk_disable_unprepare(va->dcodec);
1656-
err_dcodec:
1657-
clk_disable_unprepare(va->macro);
1664+
err_rpm_put:
1665+
pm_runtime_put_noidle(dev);
1666+
err_rpm_disable:
1667+
pm_runtime_disable(dev);
16581668
err:
16591669
lpass_macro_pds_exit(va->pds);
16601670

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

1668-
if (va->has_npl_clk)
1669-
clk_disable_unprepare(va->npl);
1670-
1671-
clk_disable_unprepare(va->mclk);
1672-
clk_disable_unprepare(va->dcodec);
1673-
clk_disable_unprepare(va->macro);
1678+
pm_runtime_disable(&pdev->dev);
16741679

16751680
lpass_macro_pds_exit(va->pds);
16761681
}
@@ -1682,38 +1687,22 @@ static int va_macro_runtime_suspend(struct device *dev)
16821687
regcache_cache_only(va->regmap, true);
16831688
regcache_mark_dirty(va->regmap);
16841689

1685-
if (va->has_npl_clk)
1686-
clk_disable_unprepare(va->npl);
1687-
1688-
clk_disable_unprepare(va->mclk);
1689-
1690-
return 0;
1690+
return pm_clk_suspend(dev);
16911691
}
16921692

16931693
static int va_macro_runtime_resume(struct device *dev)
16941694
{
16951695
struct va_macro *va = dev_get_drvdata(dev);
16961696
int ret;
16971697

1698-
ret = clk_prepare_enable(va->mclk);
1699-
if (ret) {
1700-
dev_err(va->dev, "unable to prepare mclk\n");
1698+
ret = pm_clk_resume(dev);
1699+
if (ret)
17011700
return ret;
1702-
}
17031701

1704-
if (va->has_npl_clk) {
1705-
ret = clk_prepare_enable(va->npl);
1706-
if (ret) {
1707-
clk_disable_unprepare(va->mclk);
1708-
dev_err(va->dev, "unable to prepare npl\n");
1709-
return ret;
1710-
}
1711-
}
17121702

17131703
regcache_cache_only(va->regmap, false);
1714-
regcache_sync(va->regmap);
17151704

1716-
return 0;
1705+
return regcache_sync(va->regmap);
17171706
}
17181707

17191708

sound/soc/codecs/lpass-wsa-macro.c

Lines changed: 39 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <sound/soc-dapm.h>
1515
#include <linux/pm_runtime.h>
1616
#include <linux/of_platform.h>
17+
#include <linux/pm_clock.h>
1718
#include <sound/tlv.h>
1819

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

2642-
if (enable) {
2643-
int ret;
2644+
ret = pm_runtime_get_sync(wsa->dev);
2645+
if (ret < 0) {
2646+
pm_runtime_put_noidle(wsa->dev);
2647+
return ret;
2648+
}
26442649

2645-
ret = clk_prepare_enable(wsa->mclk);
2646-
if (ret) {
2647-
dev_err(wsa->dev, "failed to enable mclk\n");
2648-
return ret;
2649-
}
2650+
if (enable) {
26502651
wsa_macro_mclk_enable(wsa, true);
26512652

26522653
regmap_update_bits(regmap, CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
@@ -2657,9 +2658,10 @@ static int wsa_swrm_clock(struct wsa_macro *wsa, bool enable)
26572658
regmap_update_bits(regmap, CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
26582659
CDC_WSA_SWR_CLK_EN_MASK, 0);
26592660
wsa_macro_mclk_enable(wsa, false);
2660-
clk_disable_unprepare(wsa->mclk);
26612661
}
26622662

2663+
pm_runtime_mark_last_busy(wsa->dev);
2664+
pm_runtime_put_autosuspend(wsa->dev);
26632665
return 0;
26642666
}
26652667

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

28842886
/* set MCLK and NPL rates */
28852887
clk_set_rate(wsa->mclk, WSA_MACRO_MCLK_FREQ);
2886-
clk_set_rate(wsa->npl, WSA_MACRO_MCLK_FREQ);
2888+
if (wsa->npl)
2889+
clk_set_rate(wsa->npl, WSA_MACRO_MCLK_FREQ);
28872890

2888-
ret = clk_prepare_enable(wsa->macro);
2891+
ret = devm_pm_clk_create(dev);
28892892
if (ret)
2890-
goto err;
2893+
return ret;
28912894

2892-
ret = clk_prepare_enable(wsa->dcodec);
2893-
if (ret)
2894-
goto err_dcodec;
2895+
ret = of_pm_clk_add_clks(dev);
2896+
if (ret < 0)
2897+
return ret;
28952898

2896-
ret = clk_prepare_enable(wsa->mclk);
2897-
if (ret)
2898-
goto err_mclk;
2899+
pm_runtime_set_autosuspend_delay(dev, 3000);
2900+
pm_runtime_use_autosuspend(dev);
2901+
pm_runtime_enable(dev);
28992902

2900-
ret = clk_prepare_enable(wsa->npl);
2901-
if (ret)
2902-
goto err_npl;
29032903

2904-
ret = clk_prepare_enable(wsa->fsgen);
2905-
if (ret)
2906-
goto err_fsgen;
2904+
ret = pm_runtime_resume_and_get(dev);
2905+
if (ret < 0) {
2906+
goto err_rpm_disable;
2907+
}
29072908

29082909
/* reset swr ip */
29092910
regmap_update_bits(wsa->regmap, CDC_WSA_CLK_RST_CTRL_SWR_CONTROL,
@@ -2920,44 +2921,26 @@ static int wsa_macro_probe(struct platform_device *pdev)
29202921
wsa_macro_dai,
29212922
ARRAY_SIZE(wsa_macro_dai));
29222923
if (ret)
2923-
goto err_clkout;
2924-
2925-
pm_runtime_set_autosuspend_delay(dev, 3000);
2926-
pm_runtime_use_autosuspend(dev);
2927-
pm_runtime_mark_last_busy(dev);
2928-
pm_runtime_set_active(dev);
2929-
pm_runtime_enable(dev);
2924+
goto err_rpm_put;
29302925

29312926
ret = wsa_macro_register_mclk_output(wsa);
29322927
if (ret)
2933-
goto err_clkout;
2928+
goto err_rpm_put;
29342929

2935-
return 0;
2930+
pm_runtime_mark_last_busy(dev);
2931+
pm_runtime_put_autosuspend(dev);
29362932

2937-
err_clkout:
2938-
clk_disable_unprepare(wsa->fsgen);
2939-
err_fsgen:
2940-
clk_disable_unprepare(wsa->npl);
2941-
err_npl:
2942-
clk_disable_unprepare(wsa->mclk);
2943-
err_mclk:
2944-
clk_disable_unprepare(wsa->dcodec);
2945-
err_dcodec:
2946-
clk_disable_unprepare(wsa->macro);
2947-
err:
2933+
return 0;
2934+
err_rpm_put:
2935+
pm_runtime_put_noidle(dev);
2936+
err_rpm_disable:
2937+
pm_runtime_disable(dev);
29482938
return ret;
2949-
29502939
}
29512940

29522941
static void wsa_macro_remove(struct platform_device *pdev)
29532942
{
2954-
struct wsa_macro *wsa = dev_get_drvdata(&pdev->dev);
2955-
2956-
clk_disable_unprepare(wsa->macro);
2957-
clk_disable_unprepare(wsa->dcodec);
2958-
clk_disable_unprepare(wsa->mclk);
2959-
clk_disable_unprepare(wsa->npl);
2960-
clk_disable_unprepare(wsa->fsgen);
2943+
pm_runtime_disable(&pdev->dev);
29612944
}
29622945

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

2970-
clk_disable_unprepare(wsa->fsgen);
2971-
clk_disable_unprepare(wsa->npl);
2972-
clk_disable_unprepare(wsa->mclk);
2973-
2974-
return 0;
2953+
return pm_clk_suspend(dev);
29752954
}
29762955

29772956
static int wsa_macro_runtime_resume(struct device *dev)
29782957
{
29792958
struct wsa_macro *wsa = dev_get_drvdata(dev);
29802959
int ret;
29812960

2982-
ret = clk_prepare_enable(wsa->mclk);
2983-
if (ret) {
2984-
dev_err(dev, "unable to prepare mclk\n");
2985-
return ret;
2986-
}
2987-
2988-
ret = clk_prepare_enable(wsa->npl);
2989-
if (ret) {
2990-
dev_err(dev, "unable to prepare mclkx2\n");
2991-
goto err_npl;
2992-
}
2993-
2994-
ret = clk_prepare_enable(wsa->fsgen);
2995-
if (ret) {
2996-
dev_err(dev, "unable to prepare fsgen\n");
2997-
goto err_fsgen;
2998-
}
2999-
30002961
regcache_cache_only(wsa->regmap, false);
3001-
regcache_sync(wsa->regmap);
3002-
3003-
return 0;
3004-
err_fsgen:
3005-
clk_disable_unprepare(wsa->npl);
3006-
err_npl:
3007-
clk_disable_unprepare(wsa->mclk);
2962+
ret = pm_clk_resume(dev);
2963+
if (ret)
2964+
return ret;
30082965

3009-
return ret;
2966+
return regcache_sync(wsa->regmap);
30102967
}
30112968

30122969
static const struct dev_pm_ops wsa_macro_pm_ops = {

0 commit comments

Comments
 (0)