[PATCH v2] ASoC: codecs: Add power domains support in digital macro codecs
Srinivas Kandagatla
srinivas.kandagatla at linaro.org
Thu Feb 24 02:01:49 CET 2022
On 23/02/2022 15:46, Srinivasa Rao Mandadapu wrote:
> Add support for enabling required power domains in digital macro codecs.
> macro and dcodec power domains are being requested as clocks by HLOS
> in ADSP based architectures and ADSP internally handling as powerdomains.
> In ADSP bypass case need to handle them as power domains explicitly.
>
> Signed-off-by: Srinivasa Rao Mandadapu <quic_srivasam at quicinc.com>
> Co-developed-by: Venkata Prasad Potturu <quic_potturu at quicinc.com>
> Signed-off-by: Venkata Prasad Potturu <quic_potturu at quicinc.com>
> Reported-by: kernel test robot <lkp at intel.com>
> ---
> Changes since v1:
> -- Add missing macros in Kconfig.
>
> sound/soc/codecs/Kconfig | 7 ++++
> sound/soc/codecs/Makefile | 2 +
> sound/soc/codecs/lpass-macro-common.c | 72 +++++++++++++++++++++++++++++++++++
> sound/soc/codecs/lpass-macro-common.h | 18 +++++++++
> sound/soc/codecs/lpass-rx-macro.c | 13 ++++++-
> sound/soc/codecs/lpass-tx-macro.c | 10 +++++
> sound/soc/codecs/lpass-va-macro.c | 11 +++++-
> sound/soc/qcom/Kconfig | 1 +
> 8 files changed, 132 insertions(+), 2 deletions(-)
> create mode 100644 sound/soc/codecs/lpass-macro-common.c
> create mode 100644 sound/soc/codecs/lpass-macro-common.h
>
> diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
> index c2627f7..4de029a 100644
> --- a/sound/soc/codecs/Kconfig
> +++ b/sound/soc/codecs/Kconfig
> @@ -244,6 +244,7 @@ config SND_SOC_ALL_CODECS
> imply SND_SOC_WCD9335
> imply SND_SOC_WCD934X
> imply SND_SOC_WCD938X_SDW
> + imply SND_SOC_LPASS_MACRO_COMMON
> imply SND_SOC_LPASS_RX_MACRO
> imply SND_SOC_LPASS_TX_MACRO
> imply SND_SOC_WL1273
> @@ -2008,6 +2009,9 @@ config SND_SOC_TPA6130A2
> tristate "Texas Instruments TPA6130A2 headphone amplifier"
> depends on I2C
>
> +config SND_SOC_LPASS_MACRO_COMMON
> + tristate
> +
> config SND_SOC_LPASS_WSA_MACRO
> depends on COMMON_CLK
> select REGMAP_MMIO
> @@ -2016,16 +2020,19 @@ config SND_SOC_LPASS_WSA_MACRO
> config SND_SOC_LPASS_VA_MACRO
> depends on COMMON_CLK
> select REGMAP_MMIO
> + select SND_SOC_LPASS_MACRO_COMMON
> tristate "Qualcomm VA Macro in LPASS(Low Power Audio SubSystem)"
>
> config SND_SOC_LPASS_RX_MACRO
> depends on COMMON_CLK
> select REGMAP_MMIO
> + select SND_SOC_LPASS_MACRO_COMMON
> tristate "Qualcomm RX Macro in LPASS(Low Power Audio SubSystem)"
>
> config SND_SOC_LPASS_TX_MACRO
> depends on COMMON_CLK
> select REGMAP_MMIO
> + select SND_SOC_LPASS_MACRO_COMMON
> tristate "Qualcomm TX Macro in LPASS(Low Power Audio SubSystem)"
>
> endmenu
> diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
> index b4e11c3..c3c6059 100644
> --- a/sound/soc/codecs/Makefile
> +++ b/sound/soc/codecs/Makefile
> @@ -112,6 +112,7 @@ snd-soc-l3-objs := l3.o
> snd-soc-lm4857-objs := lm4857.o
> snd-soc-lm49453-objs := lm49453.o
> snd-soc-lochnagar-sc-objs := lochnagar-sc.o
> +snd-soc-lpass-macro-common-objs := lpass-macro-common.o
> snd-soc-lpass-rx-macro-objs := lpass-rx-macro.o
> snd-soc-lpass-tx-macro-objs := lpass-tx-macro.o
> snd-soc-lpass-wsa-macro-objs := lpass-wsa-macro.o
> @@ -676,6 +677,7 @@ obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o
> obj-$(CONFIG_SND_SOC_MAX98504) += snd-soc-max98504.o
> obj-$(CONFIG_SND_SOC_SIMPLE_AMPLIFIER) += snd-soc-simple-amplifier.o
> obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o
> +obj-$(CONFIG_SND_SOC_LPASS_MACRO_COMMON) += snd-soc-lpass-macro-common.o
> obj-$(CONFIG_SND_SOC_LPASS_WSA_MACRO) += snd-soc-lpass-wsa-macro.o
> obj-$(CONFIG_SND_SOC_LPASS_VA_MACRO) += snd-soc-lpass-va-macro.o
> obj-$(CONFIG_SND_SOC_LPASS_RX_MACRO) += snd-soc-lpass-rx-macro.o
> diff --git a/sound/soc/codecs/lpass-macro-common.c b/sound/soc/codecs/lpass-macro-common.c
> new file mode 100644
> index 0000000..b8e50e6
> --- /dev/null
> +++ b/sound/soc/codecs/lpass-macro-common.c
> @@ -0,0 +1,72 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +// Copyright (c) 2022, The Linux Foundation. All rights reserved.
> +
> +#include <linux/export.h>
> +#include <linux/module.h>
> +#include <linux/init.h>
> +#include <linux/of_platform.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm_domain.h>
> +#include <linux/pm_runtime.h>
> +
> +#include "lpass-macro-common.h"
> +
> +int lpass_macro_pds_init(struct platform_device *pdev, struct lpass_macro **pds)
> +{
> + struct device *dev = &pdev->dev;
> + struct lpass_macro *l_pds;
> + int ret;
> +
> + const struct property *prop = of_find_property(dev->of_node, "power-domains", NULL);
> +
> + if (!prop)
> + return 0;
how about
if (!of_property_read_bool(dev->of_node, "power-domains"))
return 0;
> +
> + l_pds = devm_kzalloc(dev, sizeof(*l_pds), GFP_KERNEL);
> + if (!l_pds)
> + return -ENOMEM;
> +
> + l_pds->macro_pd = dev_pm_domain_attach_by_name(dev, "macro");
> + if (IS_ERR_OR_NULL(l_pds->macro_pd)) {
> + ret = PTR_ERR(l_pds->macro_pd) ? : -ENODATA;
> + return ret;
> + }
> + ret = pm_runtime_get_sync(l_pds->macro_pd);
> + if (ret < 0) {
> + dev_err(dev, "%s failed for macro_pd, ret %d\n", __func__, ret);
> + dev_pm_domain_detach(l_pds->macro_pd, false);
> + pm_runtime_put_noidle(l_pds->macro_pd);
> + return ret;
> + }
> +
> + l_pds->dcodec_pd = dev_pm_domain_attach_by_name(dev, "dcodec");
> + if (IS_ERR_OR_NULL(l_pds->dcodec_pd)) {
> + ret = PTR_ERR(l_pds->dcodec_pd) ? : -ENODATA;
> + dev_pm_domain_detach(l_pds->macro_pd, false);
> + return ret;
> + }
> +
> + ret = pm_runtime_get_sync(l_pds->dcodec_pd);
> + if (ret < 0) {
> + dev_err(dev, "%s failed for dcodec_pd, ret %d\n", __func__, ret);
> +
> + dev_pm_domain_detach(l_pds->dcodec_pd, false);
should you not detach and do pm_put on macro_pd here?
> + pm_runtime_put_noidle(l_pds->dcodec_pd);
> + return ret;
> + }
> + *pds = l_pds;
> + return ret;
> +}
> +EXPORT_SYMBOL_GPL(lpass_macro_pds_init);
> +
> +void lpass_macro_pds_exit(struct platform_device *pdev, struct lpass_macro *pds)
> +{
> + pm_runtime_put(pds->macro_pd);
> + pm_runtime_put(pds->dcodec_pd);
> + dev_pm_domain_detach(pds->macro_pd, false);
> + dev_pm_domain_detach(pds->dcodec_pd, false);
> +}
> +EXPORT_SYMBOL_GPL(lpass_macro_pds_exit);
> +
> +MODULE_DESCRIPTION("QTI SC7280 LPI GPIO pin control driver");
Seems incorrect description for the module.
> +MODULE_LICENSE("GPL");
> diff --git a/sound/soc/codecs/lpass-macro-common.h b/sound/soc/codecs/lpass-macro-common.h
> new file mode 100644
> index 0000000..c343f0e
> --- /dev/null
> +++ b/sound/soc/codecs/lpass-macro-common.h
> @@ -0,0 +1,18 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Copyright (c) 2022, The Linux Foundation. All rights reserved.
> + */
> +
> +#ifndef __LPASS_MACRO_COMMON_H__
> +#define __LPASS_MACRO_COMMON_H__
> +
> +
> +struct lpass_macro {
> + struct device *macro_pd;
> + struct device *dcodec_pd;
> +};
> +
> +int lpass_macro_pds_init(struct platform_device *pdev, struct lpass_macro **pds);
> +void lpass_macro_pds_exit(struct platform_device *pdev, struct lpass_macro *pds);
> +
> +#endif /* __LPASS_MACRO_COMMON_H__ */
> diff --git a/sound/soc/codecs/lpass-rx-macro.c b/sound/soc/codecs/lpass-rx-macro.c
> index 29d214f..db32090 100644
> --- a/sound/soc/codecs/lpass-rx-macro.c
> +++ b/sound/soc/codecs/lpass-rx-macro.c
> @@ -14,6 +14,8 @@
> #include <linux/of_clk.h>
> #include <linux/clk-provider.h>
>
> +#include "lpass-macro-common.h"
> +
> #define CDC_RX_TOP_TOP_CFG0 (0x0000)
> #define CDC_RX_TOP_SWR_CTRL (0x0008)
> #define CDC_RX_TOP_DEBUG (0x000C)
> @@ -606,7 +608,7 @@ struct rx_macro {
> int is_softclip_on;
> int is_aux_hpf_on;
> int softclip_clk_users;
> -
> + struct lpass_macro *pds;
> struct regmap *regmap;
> struct clk_bulk_data clks[RX_NUM_CLKS_MAX];
> struct clk_hw hw;
> @@ -3537,6 +3539,12 @@ static int rx_macro_probe(struct platform_device *pdev)
> return ret;
> }
>
> + ret = lpass_macro_pds_init(pdev, &rx->pds);
> + if (ret < 0) {
> + dev_err(dev, "Enabling power domains failed in %s\n", __func__);
> + return ret;
> + }
> +
> base = devm_platform_ioremap_resource(pdev, 0);
> if (IS_ERR(base))
> return PTR_ERR(base);
> @@ -3575,6 +3583,9 @@ static int rx_macro_remove(struct platform_device *pdev)
>
> of_clk_del_provider(pdev->dev.of_node);
> clk_bulk_disable_unprepare(RX_NUM_CLKS_MAX, rx->clks);
> +
> + lpass_macro_pds_exit(pdev, rx->pds);
> +
> return 0;
> }
>
> diff --git a/sound/soc/codecs/lpass-tx-macro.c b/sound/soc/codecs/lpass-tx-macro.c
> index 9c96ab1..4d1e5ab 100644
> --- a/sound/soc/codecs/lpass-tx-macro.c
> +++ b/sound/soc/codecs/lpass-tx-macro.c
> @@ -13,6 +13,8 @@
> #include <linux/of_clk.h>
> #include <linux/clk-provider.h>
>
> +#include "lpass-macro-common.h"
> +
> #define CDC_TX_CLK_RST_CTRL_MCLK_CONTROL (0x0000)
> #define CDC_TX_MCLK_EN_MASK BIT(0)
> #define CDC_TX_MCLK_ENABLE BIT(0)
> @@ -266,6 +268,7 @@ struct tx_macro {
> u16 dmic_clk_div;
> bool bcs_enable;
> int dec_mode[NUM_DECIMATORS];
> + struct lpass_macro *pds;
> bool bcs_clk_en;
> };
> #define to_tx_macro(_hw) container_of(_hw, struct tx_macro, hw)
> @@ -1802,6 +1805,11 @@ static int tx_macro_probe(struct platform_device *pdev)
> return ret;
> }
>
> + ret = lpass_macro_pds_init(pdev, &tx->pds);
> + if (ret < 0) {
> + dev_err(dev, "Enabling power domains failed in %s\n", __func__);
> + return ret;
> + }
> base = devm_platform_ioremap_resource(pdev, 0);
> if (IS_ERR(base))
> return PTR_ERR(base);
> @@ -1859,6 +1867,8 @@ static int tx_macro_remove(struct platform_device *pdev)
>
> clk_bulk_disable_unprepare(TX_NUM_CLKS_MAX, tx->clks);
>
> + lpass_macro_pds_exit(pdev, tx->pds);
> +
> return 0;
> }
>
> diff --git a/sound/soc/codecs/lpass-va-macro.c b/sound/soc/codecs/lpass-va-macro.c
> index 11147e3..b29b9a1 100644
> --- a/sound/soc/codecs/lpass-va-macro.c
> +++ b/sound/soc/codecs/lpass-va-macro.c
> @@ -15,6 +15,8 @@
> #include <sound/soc-dapm.h>
> #include <sound/tlv.h>
>
> +#include "lpass-macro-common.h"
> +
> /* VA macro registers */
> #define CDC_VA_CLK_RST_CTRL_MCLK_CONTROL (0x0000)
> #define CDC_VA_MCLK_CONTROL_EN BIT(0)
> @@ -195,6 +197,7 @@ struct va_macro {
> struct regmap *regmap;
> struct clk_bulk_data clks[VA_NUM_CLKS_MAX];
> struct clk_hw hw;
> + struct lpass_macro *pds;
>
> s32 dmic_0_1_clk_cnt;
> s32 dmic_2_3_clk_cnt;
> @@ -1413,7 +1416,11 @@ static int va_macro_probe(struct platform_device *pdev)
> dev_err(dev, "Error getting VA Clocks (%d)\n", ret);
> return ret;
> }
> -
> + ret = lpass_macro_pds_init(pdev, &va->pds);
> + if (ret < 0) {
> + dev_err(dev, "Enabling power domains failed %s\n", __func__);
> + return ret;
> + }
> ret = of_property_read_u32(dev->of_node, "qcom,dmic-sample-rate",
> &sample_rate);
> if (ret) {
> @@ -1468,6 +1475,8 @@ static int va_macro_remove(struct platform_device *pdev)
>
> clk_bulk_disable_unprepare(VA_NUM_CLKS_MAX, va->clks);
>
> + lpass_macro_pds_exit(pdev, va->pds);
> +
> return 0;
> }
>
> diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig
> index 52db003..6ffd51a 100644
> --- a/sound/soc/qcom/Kconfig
> +++ b/sound/soc/qcom/Kconfig
> @@ -194,6 +194,7 @@ config SND_SOC_SC7280
> select SND_SOC_LPASS_SC7280
> select SND_SOC_MAX98357A
> select SND_SOC_WCD938X
> + select SND_SOC_LPASS_MACRO_COMMON
> select SND_SOC_LPASS_RX_MACRO
> select SND_SOC_LPASS_TX_MACRO
> help
More information about the Alsa-devel
mailing list