Re: [PATCH v1 4/4] clk: qcom: lpass: Add support for LPASS clock controller for SC7280

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Quoting Taniya Das (2021-11-02 02:56:53)
> The Low Power Audio subsystem core and audio clocks are required for
> Audio client to be able to request for the clocks and power domains.
> 
> Signed-off-by: Taniya Das <tdas@xxxxxxxxxxxxxx>
> ---
>  drivers/clk/qcom/Kconfig               |   9 +
>  drivers/clk/qcom/Makefile              |   1 +
>  drivers/clk/qcom/lpassaudiocc-sc7280.c | 831 +++++++++++++++++++++++++++++++++
>  drivers/clk/qcom/lpasscorecc-sc7280.c  | 491 +++++++++++++++++++
>  4 files changed, 1332 insertions(+)
>  create mode 100644 drivers/clk/qcom/lpassaudiocc-sc7280.c
>  create mode 100644 drivers/clk/qcom/lpasscorecc-sc7280.c
> 
> diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
> index 74efc82..4dcabc6 100644
> --- a/drivers/clk/qcom/Kconfig
> +++ b/drivers/clk/qcom/Kconfig
> @@ -435,6 +435,15 @@ config SC_LPASS_CORECC_7180
>           Say Y if you want to use LPASS clocks and power domains of the LPASS
>           core clock controller.
> 
> +config SC_LPASS_CORECC_7280
> +       tristate "SC7280 LPASS Core & Audio Clock Controller"
> +       select SC_GCC_7280

select GDSC too

> +       help
> +         Support for the LPASS(Low Power Audio Subsystem) core and audio clock
> +         controller on SC7280 devices.
> +         Say Y if you want to use LPASS clocks and power domains of the LPASS
> +         core clock controller.
> +
>  config SC_MSS_7180
>         tristate "SC7180 Modem Clock Controller"
>         select SC_GCC_7180
> diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
> index 1718c34..9e4b8e1 100644
> --- a/drivers/clk/qcom/Makefile
> +++ b/drivers/clk/qcom/Makefile
> @@ -69,6 +69,7 @@ obj-$(CONFIG_SC_GPUCC_7180) += gpucc-sc7180.o
>  obj-$(CONFIG_SC_GPUCC_7280) += gpucc-sc7280.o
>  obj-$(CONFIG_SC_LPASSCC_7280) += lpasscc-sc7280.o
>  obj-$(CONFIG_SC_LPASS_CORECC_7180) += lpasscorecc-sc7180.o
> +obj-$(CONFIG_SC_LPASS_CORECC_7280) += lpasscorecc-sc7280.o lpassaudiocc-sc7280.o
>  obj-$(CONFIG_SC_MSS_7180) += mss-sc7180.o
>  obj-$(CONFIG_SC_VIDEOCC_7180) += videocc-sc7180.o
>  obj-$(CONFIG_SC_VIDEOCC_7280) += videocc-sc7280.o
> diff --git a/drivers/clk/qcom/lpassaudiocc-sc7280.c b/drivers/clk/qcom/lpassaudiocc-sc7280.c
> new file mode 100644
> index 0000000..52e7f8e
> --- /dev/null
> +++ b/drivers/clk/qcom/lpassaudiocc-sc7280.c
> @@ -0,0 +1,831 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (c) 2021, The Linux Foundation. All rights reserved.
> + */
> +
> +#include <linux/clk-provider.h>
> +#include <linux/err.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of_device.h>
> +#include <linux/of.h>
> +#include <linux/pm_clock.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/regmap.h>
> +
> +#include <dt-bindings/clock/qcom,lpassaudiocc-sc7280.h>
> +
> +#include "clk-alpha-pll.h"
> +#include "clk-branch.h"
> +#include "clk-rcg.h"
> +#include "clk-regmap.h"
> +#include "clk-regmap-divider.h"
> +#include "clk-regmap-mux.h"
> +#include "common.h"
> +#include "gdsc.h"
> +
> +enum {
> +       P_BI_TCXO,
> +       P_LPASS_AON_CC_PLL_OUT_EVEN,
> +       P_LPASS_AON_CC_PLL_OUT_MAIN,
> +       P_LPASS_AON_CC_PLL_OUT_MAIN_CDIV_DIV_CLK_SRC,
> +       P_LPASS_AON_CC_PLL_OUT_ODD,
> +       P_LPASS_AUDIO_CC_PLL_OUT_AUX,
> +       P_LPASS_AUDIO_CC_PLL_OUT_AUX2_DIV_CLK_SRC,
> +       P_LPASS_AUDIO_CC_PLL_MAIN_DIV_CLK,
> +};
> +
> +static struct pll_vco zonda_vco[] = {

const

> +       { 595200000, 3600000000, 0 },
> +};
> +
> +/* 1128.96MHz configuration */
> +static const struct alpha_pll_config lpass_audio_cc_pll_config = {
> +       .l = 0x3a,
> +       .alpha = 0xcccc,
> +       .config_ctl_val = 0x08200920,
> +       .config_ctl_hi_val = 0x05002001,
> +       .config_ctl_hi1_val = 0x00000000,
> +       .user_ctl_val = 0x03000101,
> +};
> +
> +static struct clk_alpha_pll lpass_audio_cc_pll = {
> +       .offset = 0x0,
> +       .vco_table = zonda_vco,
> +       .num_vco = ARRAY_SIZE(zonda_vco),
> +       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_ZONDA],
> +       .clkr = {
> +               .hw.init = &(struct clk_init_data){

const struct clk_init_data

BTW, we should do that for all the qcom clk drivers.

> +                       .name = "lpass_audio_cc_pll",
> +                       .parent_data = &(const struct clk_parent_data){
> +                               .fw_name = "bi_tcxo",

To make the kernel smaller we should consider using integers in the
.index field instead of .fw_name so that we don't have to store around
strings.

> +                       },
> +                       .num_parents = 1,
> +                       .ops = &clk_alpha_pll_zonda_ops,
> +               },
> +       },
> +};
> +
> +static const struct clk_div_table post_div_table_lpass_audio_cc_pll_out_aux2[] = {
> +       { 0x1, 2 },
> +       { }
> +};
> +
> +static struct clk_alpha_pll_postdiv lpass_audio_cc_pll_out_aux2 = {
> +       .offset = 0x0,
> +       .post_div_shift = 8,
> +       .post_div_table = post_div_table_lpass_audio_cc_pll_out_aux2,
> +       .num_post_div = ARRAY_SIZE(post_div_table_lpass_audio_cc_pll_out_aux2),
> +       .width = 2,
> +       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_ZONDA],
> +       .clkr.hw.init = &(struct clk_init_data){
> +               .name = "lpass_audio_cc_pll_out_aux2",
> +               .parent_hws = (const struct clk_hw*[]){
> +                       &lpass_audio_cc_pll.clkr.hw,
> +               },
> +               .num_parents = 1,
> +               .ops = &clk_alpha_pll_postdiv_zonda_ops,
> +       },
> +};
> +
> +static struct pll_vco lucid_vco[] = {

const

> +       { 249600000, 2000000000, 0 },
> +};
> +
> diff --git a/drivers/clk/qcom/lpasscorecc-sc7280.c b/drivers/clk/qcom/lpasscorecc-sc7280.c
> new file mode 100644
> index 0000000..812d9bd
> --- /dev/null
> +++ b/drivers/clk/qcom/lpasscorecc-sc7280.c
> @@ -0,0 +1,491 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (c) 2021, The Linux Foundation. All rights reserved.
> + */
> +
> +#include <linux/clk-provider.h>
> +#include <linux/err.h>
> +#include <linux/module.h>
> +#include <linux/of_device.h>
> +#include <linux/of.h>
> +#include <linux/pm_clock.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/regmap.h>
> +
> +#include <dt-bindings/clock/qcom,lpasscorecc-sc7280.h>
> +
> +#include "clk-alpha-pll.h"
> +#include "clk-branch.h"
> +#include "clk-rcg.h"
> +#include "clk-regmap.h"
[...]
> +               .hw.init = &(struct clk_init_data){
> +                       .name = "lpass_core_cc_sysnoc_mport_core_clk",
> +                       .parent_hws = (const struct clk_hw*[]){
> +                               &lpass_core_cc_core_clk_src.clkr.hw,
> +                       },
> +                       .num_parents = 1,
> +                       .flags = CLK_SET_RATE_PARENT,
> +                       .ops = &clk_branch2_ops,
> +               },
> +       },
> +};
> +
> +static struct gdsc  lpass_core_cc_lpass_core_hm_gdsc = {

Only one space after gdsc please

> +       .gdscr = 0x0,
> +       .pd = {
> +               .name = "lpass_core_cc_lpass_core_hm_gdsc",
> +       },
> +       .pwrsts = PWRSTS_OFF_ON,
> +       .flags = RETAIN_FF_ENABLE,
> +       .clk_name = "iface",
> +};
> +
> +static struct clk_regmap *lpass_core_cc_sc7280_clocks[] = {
> +       [LPASS_CORE_CC_CORE_CLK] = &lpass_core_cc_core_clk.clkr,
> +       [LPASS_CORE_CC_CORE_CLK_SRC] = &lpass_core_cc_core_clk_src.clkr,
> +       [LPASS_CORE_CC_DIG_PLL] = &lpass_core_cc_dig_pll.clkr,
> +       [LPASS_CORE_CC_DIG_PLL_OUT_MAIN_DIV_CLK_SRC] =
> +               &lpass_core_cc_dig_pll_out_main_div_clk_src.clkr,
> +       [LPASS_CORE_CC_DIG_PLL_OUT_ODD] = &lpass_core_cc_dig_pll_out_odd.clkr,
> +       [LPASS_CORE_CC_EXT_IF0_CLK_SRC] = &lpass_core_cc_ext_if0_clk_src.clkr,
> +       [LPASS_CORE_CC_EXT_IF0_IBIT_CLK] = &lpass_core_cc_ext_if0_ibit_clk.clkr,
> +       [LPASS_CORE_CC_EXT_IF1_CLK_SRC] = &lpass_core_cc_ext_if1_clk_src.clkr,
> +       [LPASS_CORE_CC_EXT_IF1_IBIT_CLK] = &lpass_core_cc_ext_if1_ibit_clk.clkr,
> +       [LPASS_CORE_CC_LPM_CORE_CLK] = &lpass_core_cc_lpm_core_clk.clkr,
> +       [LPASS_CORE_CC_LPM_MEM0_CORE_CLK] = &lpass_core_cc_lpm_mem0_core_clk.clkr,
> +       [LPASS_CORE_CC_SYSNOC_MPORT_CORE_CLK] = &lpass_core_cc_sysnoc_mport_core_clk.clkr,
> +};
> +
> +static struct regmap_config lpass_core_cc_sc7280_regmap_config = {
> +       .reg_bits = 32,
> +       .reg_stride = 4,
> +       .val_bits = 32,
> +       .fast_io = true,
> +};
> +
> +static const struct qcom_cc_desc lpass_core_cc_sc7280_desc = {
> +       .config = &lpass_core_cc_sc7280_regmap_config,
> +       .clks = lpass_core_cc_sc7280_clocks,
> +       .num_clks = ARRAY_SIZE(lpass_core_cc_sc7280_clocks),
> +};
> +
> +static const struct of_device_id lpass_core_cc_sc7280_match_table[] = {
> +       { .compatible = "qcom,sc7280-lpasscorecc" },
> +       { }
> +};
> +MODULE_DEVICE_TABLE(of, lpass_core_cc_sc7280_match_table);
> +
> +static struct gdsc *lpass_core_hm_sc7280_gdscs[] = {
> +       [LPASS_CORE_CC_LPASS_CORE_HM_GDSC] = &lpass_core_cc_lpass_core_hm_gdsc,
> +};
> +
> +static const struct qcom_cc_desc lpass_core_hm_sc7280_desc = {
> +       .config = &lpass_core_cc_sc7280_regmap_config,
> +       .gdscs = lpass_core_hm_sc7280_gdscs,
> +       .num_gdscs = ARRAY_SIZE(lpass_core_hm_sc7280_gdscs),
> +};
> +
> +static void lpass_pm_runtime_disable(void *data)
> +{
> +       pm_runtime_disable(data);
> +}
> +
> +static void lpass_pm_clk_destroy(void *data)

Please make the symbols unique. This is the same function name twice.

> +{
> +       pm_clk_destroy(data);
> +}
> +
> +static int lpass_create_pm_clks(struct platform_device *pdev)
> +{
> +       int ret;
> +
> +       pm_runtime_use_autosuspend(&pdev->dev);
> +       pm_runtime_set_autosuspend_delay(&pdev->dev, 100);
> +       pm_runtime_enable(&pdev->dev);
> +
> +       ret = devm_add_action_or_reset(&pdev->dev, lpass_pm_runtime_disable, &pdev->dev);
> +       if (ret)
> +               return ret;
> +
> +       ret = pm_clk_create(&pdev->dev);
> +       if (ret)
> +               return ret;
> +       ret = devm_add_action_or_reset(&pdev->dev, lpass_pm_clk_destroy, &pdev->dev);
> +       if (ret)
> +               return ret;
> +
> +       ret = pm_clk_add(&pdev->dev, "iface");
> +       if (ret < 0)
> +               dev_err(&pdev->dev, "failed to acquire iface clock\n");
> +
> +       return ret;
> +}
> +
> +static int lpass_core_cc_sc7280_probe(struct platform_device *pdev)
> +{
> +       struct regmap *regmap;
> +       int ret;
> +
> +       ret = lpass_create_pm_clks(pdev);
> +       if (ret)
> +               return ret;
> +
> +       regmap = qcom_cc_map(pdev, &lpass_core_cc_sc7280_desc);
> +       if (IS_ERR(regmap))
> +               return PTR_ERR(regmap);
> +
> +       clk_lucid_pll_configure(&lpass_core_cc_dig_pll, regmap, &lpass_core_cc_dig_pll_config);
> +
> +       ret = qcom_cc_really_probe(pdev, &lpass_core_cc_sc7280_desc, regmap);
> +       if (ret) {
> +               dev_err(&pdev->dev, "Failed to register LPASS CORE CC clocks\n");
> +               return ret;
> +       }
> +
> +       pm_runtime_mark_last_busy(&pdev->dev);
> +       pm_runtime_put_autosuspend(&pdev->dev);
> +
> +       return ret;
> +}
> +
> +static const struct dev_pm_ops lpass_core_cc_pm_ops = {
> +       SET_RUNTIME_PM_OPS(pm_clk_suspend, pm_clk_resume, NULL)
> +};
> +
> +static struct platform_driver lpass_core_cc_sc7280_driver = {
> +       .probe = lpass_core_cc_sc7280_probe,
> +       .driver = {
> +               .name = "lpass_core_cc-sc7280",
> +               .of_match_table = lpass_core_cc_sc7280_match_table,
> +               .pm = &lpass_core_cc_pm_ops,
> +       },
> +};
> +
> +static int lpass_hm_core_probe(struct platform_device *pdev)
> +{
> +       const struct qcom_cc_desc *desc;
> +       int ret;
> +
> +       lpass_core_cc_sc7280_regmap_config.name = "lpass_hm_core";
> +       desc = &lpass_core_hm_sc7280_desc;
> +
> +       ret = qcom_cc_probe_by_index(pdev, 0, desc);
> +       if (ret)
> +               goto destroy_clk;
> +
> +       return 0;
> +
> +destroy_clk:
> +       return ret;

	return qcom_cc_probe_by_index(...);

is equivalent.

> +}
> +
> +static const struct of_device_id lpass_hm_sc7280_match_table[] = {
> +       {
> +               .compatible = "qcom,sc7280-lpasshm",
> +       },

Please reduce to one line instead of three.

> +       { }
> +};
> +MODULE_DEVICE_TABLE(of, lpass_hm_sc7280_match_table);
> +




[Index of Archives]     [Device Tree Compilter]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux PCI Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Yosemite Backpacking]


  Powered by Linux