Hello,
This series adds APCS mailbox and clock support for SDX55. The APCS IP
in SDX55 provides IPC and clock functionalities. Hence, mailbox support
is added to the "qcom-apcs-ipc-mailbox" driver and a dedicated clock
driver "apcs-sdx55" is added.
Also, the clock to the APCS block is coming from 3 different sources:
1. Board XO
2. Fixed rate GPLL0
3. A7 PLL
First source is from crystal osc, second is from GCC and third one is a
separate clock source. Hence, a dedicated clk driver is added for the A7
PLL as well.
Apart from the mailbox support, another intention of this series is to add
the CPUFreq support to SDX55 platform. Since there is no dedicated hardware
IP in SDX55 to do CPUFreq duties, this platform makes use of the clock and
regulators directly via cpufreq-dt driver.
The trick here is attaching the power domain to cpudev. Usually the power
domains for the target device is attached in the bus driver or in the
dedicated device drivers. But in this case, there is no dedicated CPUFreq
driver nor a bus driver. After discussing with Viresh, I concluded that
A7 PLL driver might be the best place to do this!
But this decision is subject to discussion, hence added Ulf and Viresh to
this series.
Thanks,
Mani
Changes in v3:
* Incorporated review comments from Stephen for APCS clk driver and Rob for
APCS DT binding
Changes in v2:
* Modified the max_register value as per the SDX55 IPC offset in mailbox
driver.
Manivannan Sadhasivam (5):
dt-bindings: mailbox: Add binding for SDX55 APCS
mailbox: qcom: Add support for SDX55 APCS IPC
dt-bindings: clock: Add Qualcomm A7 PLL binding
clk: qcom: Add A7 PLL support
clk: qcom: Add SDX55 APCS clock controller support
.../devicetree/bindings/clock/qcom,a7pll.yaml | 51 ++++++
.../mailbox/qcom,apcs-kpss-global.yaml | 33 ++++
drivers/clk/qcom/Kconfig | 17 ++
drivers/clk/qcom/Makefile | 2 +
drivers/clk/qcom/a7-pll.c | 100 ++++++++++++
drivers/clk/qcom/apcs-sdx55.c | 149 ++++++++++++++++++
drivers/mailbox/qcom-apcs-ipc-mailbox.c | 7 +-
7 files changed, 358 insertions(+), 1 deletion(-)
create mode 100644 Documentation/devicetree/bindings/clock/qcom,a7pll.yaml
create mode 100644 drivers/clk/qcom/a7-pll.c
create mode 100644 drivers/clk/qcom/apcs-sdx55.c
--
2.25.1
@@ -33,9 +33,11 @@ properties:clocks:description:phandles to the parent clocks of the clock driver+minItems:2items:-description:primary pll parent of the clock driver-description:auxiliary parent+-description:reference clock'#mbox-cells':const:1
@@ -55,6 +59,35 @@ required:additionalProperties:false+allOf:+-if:+properties:+compatible:+enum:+-qcom,ipq6018-apcs-apps-global+-qcom,ipq8074-apcs-apps-global+-qcom,msm8916-apcs-kpss-global+-qcom,msm8994-apcs-kpss-global+-qcom,msm8996-apcs-hmss-global+-qcom,msm8998-apcs-hmss-global+-qcom,qcs404-apcs-apps-global+-qcom,sc7180-apss-shared+-qcom,sdm660-apcs-hmss-global+-qcom,sdm845-apss-shared+-qcom,sm8150-apss-shared+then:+properties:+clocks:+maxItems:2+-if:+properties:+compatible:+enum:+-qcom,sdx55-apcs-gcc+then:+properties:+clocks:+maxItems:3examples:# Example apcs with msm8996
In SDX55, the IPC bits are located in the APCS GCC block. Also, this block
can provide clock functionality. Hence, add support for IPC with correct
offset and name of the clock provider.
Signed-off-by: Manivannan Sadhasivam <redacted>
---
drivers/mailbox/qcom-apcs-ipc-mailbox.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
@@ -0,0 +1,51 @@+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)+%YAML1.2+---+$id:http://devicetree.org/schemas/clock/qcom,a7pll.yaml#+$schema:http://devicetree.org/meta-schemas/core.yaml#++title:Qualcomm A7 PLL Binding++maintainers:+-Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>++description:+The A7 PLL on the Qualcomm platforms like SDX55 is used to provide high+frequency clock to the CPU.++properties:+compatible:+enum:+-qcom,sdx55-a7pll++reg:+maxItems:1++'#clock-cells':+const:0++clocks:+items:+-description:board XO clock++clock-names:+items:+-const:bi_tcxo++required:+-compatible+-reg+-'#clock-cells'++additionalProperties:false++examples:+-|+#include <dt-bindings/clock/qcom,rpmh.h>+a7pll:clock@17808000 {+compatible = "qcom,sdx55-a7pll";+reg = <0x17808000 0x1000>;+clocks = <&rpmhcc RPMH_CXO_CLK>;+clock-names = "bi_tcxo";+#clock-cells = <0>;+};
Please add Acked-by/Reviewed-by tags when posting new versions. However,
there's no need to repost patches *only* to add the tags. The upstream
maintainer will do that for acks received on the version they apply.
If a tag was not added on purpose, please state why and what changed.
Please add Acked-by/Reviewed-by tags when posting new versions. However,
there's no need to repost patches *only* to add the tags. The upstream
maintainer will do that for acks received on the version they apply.
If a tag was not added on purpose, please state why and what changed.
Oops! Sorry, I missed your review for this patch:
Reviewed-by: Rob Herring <robh@kernel.org>
Thanks,
Mani
Add support for PLL found in Qualcomm SDX55 platforms which is used to
provide clock to the Cortex A7 CPU via a mux. This PLL can provide high
frequency clock to the CPU above 1GHz as compared to the other sources
like GPLL0.
In this driver, the power domain is attached to the cpudev. This is
required for CPUFreq functionality and there seems to be no better place
to do other than this driver (no dedicated CPUFreq driver).
Signed-off-by: Manivannan Sadhasivam <redacted>
---
drivers/clk/qcom/Kconfig | 8 +++
drivers/clk/qcom/Makefile | 1 +
drivers/clk/qcom/a7-pll.c | 100 ++++++++++++++++++++++++++++++++++++++
3 files changed, 109 insertions(+)
create mode 100644 drivers/clk/qcom/a7-pll.c
@@ -0,0 +1,100 @@+// SPDX-License-Identifier: GPL-2.0+/*+*QualcommA7PLLdriver+*+*Copyright(c)2020,LinaroLimited+*Author:ManivannanSadhasivam<manivannan.sadhasivam@linaro.org>+*/++#include<linux/clk-provider.h>+#include<linux/module.h>+#include<linux/platform_device.h>+#include<linux/regmap.h>++#include"clk-alpha-pll.h"++#define LUCID_PLL_OFF_L_VAL 0x04++staticconststructpll_vcolucid_vco[]={+{249600000,2000000000,0},+};++staticstructclk_alpha_plla7pll={+.offset=0x100,+.vco_table=lucid_vco,+.num_vco=ARRAY_SIZE(lucid_vco),+.regs=clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID],+.clkr={+.hw.init=&(structclk_init_data){+.name="a7pll",+.parent_data=&(conststructclk_parent_data){+.fw_name="bi_tcxo",+},+.num_parents=1,+.ops=&clk_alpha_pll_lucid_ops,+},+},+};++staticconststructalpha_pll_configa7pll_config={+.l=0x39,+.config_ctl_val=0x20485699,+.config_ctl_hi_val=0x2261,+.config_ctl_hi1_val=0x029A699C,+.user_ctl_val=0x1,+.user_ctl_hi_val=0x805,+};++staticconststructregmap_configa7pll_regmap_config={+.reg_bits=32,+.reg_stride=4,+.val_bits=32,+.max_register=0x1000,+.fast_io=true,+};++staticintqcom_a7pll_probe(structplatform_device*pdev)+{+structdevice*dev=&pdev->dev;+structregmap*regmap;+void__iomem*base;+u32l_val;+intret;++base=devm_platform_ioremap_resource(pdev,0);+if(IS_ERR(base))+returnPTR_ERR(base);++regmap=devm_regmap_init_mmio(dev,base,&a7pll_regmap_config);+if(IS_ERR(regmap))+returnPTR_ERR(regmap);++/* Configure PLL only if the l_val is zero */+regmap_read(regmap,a7pll.offset+LUCID_PLL_OFF_L_VAL,&l_val);+if(!l_val)+clk_lucid_pll_configure(&a7pll,regmap,&a7pll_config);++ret=devm_clk_register_regmap(dev,&a7pll.clkr);+if(ret)+returnret;++returndevm_of_clk_add_hw_provider(dev,of_clk_hw_simple_get,+&a7pll.clkr.hw);+}++staticconststructof_device_idqcom_a7pll_match_table[]={+{.compatible="qcom,sdx55-a7pll"},+{}+};++staticstructplatform_driverqcom_a7pll_driver={+.probe=qcom_a7pll_probe,+.driver={+.name="qcom-a7pll",+.of_match_table=qcom_a7pll_match_table,+},+};+module_platform_driver(qcom_a7pll_driver);++MODULE_DESCRIPTION("Qualcomm A7 PLL Driver");+MODULE_LICENSE("GPL v2");
Add support for PLL found in Qualcomm SDX55 platforms which is used to
provide clock to the Cortex A7 CPU via a mux. This PLL can provide high
frequency clock to the CPU above 1GHz as compared to the other sources
like GPLL0.
In this driver, the power domain is attached to the cpudev. This is
required for CPUFreq functionality and there seems to be no better place
to do other than this driver (no dedicated CPUFreq driver).
Signed-off-by: Manivannan Sadhasivam <redacted>
---
Add a driver for the SDX55 APCS clock controller. It is part of the APCS
hardware block, which among other things implements also a combined mux
and half integer divider functionality. The APCS clock controller has 3
parent clocks:
1. Board XO
2. Fixed rate GPLL0
3. A7 PLL
This is required for enabling CPU frequency scaling on SDX55-based
platforms.
Signed-off-by: Manivannan Sadhasivam <redacted>
---
drivers/clk/qcom/Kconfig | 9 ++
drivers/clk/qcom/Makefile | 1 +
drivers/clk/qcom/apcs-sdx55.c | 149 ++++++++++++++++++++++++++++++++++
3 files changed, 159 insertions(+)
create mode 100644 drivers/clk/qcom/apcs-sdx55.c
@@ -0,0 +1,149 @@+// SPDX-License-Identifier: GPL-2.0+/*+*QualcommSDX55APCSclockcontrollerdriver+*+*Copyright(c)2020,LinaroLimited+*Author:ManivannanSadhasivam<manivannan.sadhasivam@linaro.org>+*/++#include<linux/clk.h>+#include<linux/clk-provider.h>+#include<linux/cpu.h>+#include<linux/kernel.h>+#include<linux/module.h>+#include<linux/platform_device.h>+#include<linux/pm_domain.h>+#include<linux/regmap.h>+#include<linux/slab.h>++#include"clk-regmap.h"+#include"clk-regmap-mux-div.h"++staticconstu32apcs_mux_clk_parent_map[]={0,1,5};++staticconststructclk_parent_datapdata[]={+{.fw_name="ref"},+{.fw_name="aux"},+{.fw_name="pll"},+};++/*+*Weusethenotifierfunctionforswitchingtoatemporarysafeconfiguration+*(muxanddivider),whiletheA7PLLisreconfigured.+*/+staticinta7cc_notifier_cb(structnotifier_block*nb,unsignedlongevent,+void*data)+{+intret=0;+structclk_regmap_mux_div*md=container_of(nb,+structclk_regmap_mux_div,+clk_nb);+if(event==PRE_RATE_CHANGE)+/* set the mux and divider to safe frequency (400mhz) */+ret=mux_div_set_src_div(md,1,2);++returnnotifier_from_errno(ret);+}++staticintqcom_apcs_sdx55_clk_probe(structplatform_device*pdev)+{+structdevice*dev=&pdev->dev;+structdevice*parent=dev->parent;+structdevice*cpu_dev;+structclk_regmap_mux_div*a7cc;+structregmap*regmap;+structclk_init_datainit={};+intret;++regmap=dev_get_regmap(parent,NULL);+if(!regmap){+dev_err_probe(dev,ret,"Failed to get parent regmap\n");+return-ENODEV;+}++a7cc=devm_kzalloc(dev,sizeof(*a7cc),GFP_KERNEL);+if(!a7cc)+return-ENOMEM;++init.name="a7mux";+init.parent_data=pdata;+init.num_parents=ARRAY_SIZE(pdata);+init.ops=&clk_regmap_mux_div_ops;++a7cc->clkr.hw.init=&init;+a7cc->clkr.regmap=regmap;+a7cc->reg_offset=0x8;+a7cc->hid_width=5;+a7cc->hid_shift=0;+a7cc->src_width=3;+a7cc->src_shift=8;+a7cc->parent_map=apcs_mux_clk_parent_map;++a7cc->pclk=devm_clk_get(parent,"pll");+if(IS_ERR(a7cc->pclk)){+ret=PTR_ERR(a7cc->pclk);+if(ret!=-EPROBE_DEFER)+dev_err_probe(dev,ret,"Failed to get PLL clk\n");+returnret;+}++a7cc->clk_nb.notifier_call=a7cc_notifier_cb;+ret=clk_notifier_register(a7cc->pclk,&a7cc->clk_nb);+if(ret){+dev_err_probe(dev,ret,"Failed to register clock notifier\n");+returnret;+}++ret=devm_clk_register_regmap(dev,&a7cc->clkr);+if(ret){+dev_err_probe(dev,ret,"Failed to register regmap clock\n");+gotoerr;+}++ret=devm_of_clk_add_hw_provider(dev,of_clk_hw_simple_get,+&a7cc->clkr.hw);+if(ret){+dev_err_probe(dev,ret,"Failed to add clock provider\n");+gotoerr;+}++platform_set_drvdata(pdev,a7cc);++/*+*Attachthepowerdomaintocpudev.Sincethereisnodedicateddriver+*forCPUsandtheSDX55platformlackshardwarespecificCPUFreq+*driver,thereseemstobenobetterplacetodothis.Sodoithere!+*/+cpu_dev=get_cpu_device(0);+dev_pm_domain_attach(cpu_dev,true);++return0;++err:+clk_notifier_unregister(a7cc->pclk,&a7cc->clk_nb);+returnret;+}++staticintqcom_apcs_sdx55_clk_remove(structplatform_device*pdev)+{+structdevice*cpu_dev=get_cpu_device(0);+structclk_regmap_mux_div*a7cc=platform_get_drvdata(pdev);++clk_notifier_unregister(a7cc->pclk,&a7cc->clk_nb);+dev_pm_domain_detach(cpu_dev,true);++return0;+}++staticstructplatform_driverqcom_apcs_sdx55_clk_driver={+.probe=qcom_apcs_sdx55_clk_probe,+.remove=qcom_apcs_sdx55_clk_remove,+.driver={+.name="qcom-sdx55-acps-clk",+},+};+module_platform_driver(qcom_apcs_sdx55_clk_driver);++MODULE_AUTHOR("Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>");+MODULE_LICENSE("GPL v2");+MODULE_DESCRIPTION("Qualcomm SDX55 APCS clock driver");
Add a driver for the SDX55 APCS clock controller. It is part of the APCS
hardware block, which among other things implements also a combined mux
and half integer divider functionality. The APCS clock controller has 3
parent clocks:
1. Board XO
2. Fixed rate GPLL0
3. A7 PLL
This is required for enabling CPU frequency scaling on SDX55-based
platforms.
Signed-off-by: Manivannan Sadhasivam <redacted>
---
Changes in v2:
* Modified the max_register value as per the SDX55 IPC offset in mailbox
driver.
Manivannan Sadhasivam (5):
dt-bindings: mailbox: Add binding for SDX55 APCS
mailbox: qcom: Add support for SDX55 APCS IPC
I think I can apply the clk patches to clk tree without the mailbox
patches, right?
Changes in v2:
* Modified the max_register value as per the SDX55 IPC offset in mailbox
driver.
Manivannan Sadhasivam (5):
dt-bindings: mailbox: Add binding for SDX55 APCS
mailbox: qcom: Add support for SDX55 APCS IPC
I think I can apply the clk patches to clk tree without the mailbox
patches, right?
Yes, you can. Thanks for applying!
Jassi: Can you please look into the mailbox patches?
Regards,
Mani
Changes in v2:
* Modified the max_register value as per the SDX55 IPC offset in mailbox
driver.
Manivannan Sadhasivam (5):
dt-bindings: mailbox: Add binding for SDX55 APCS
mailbox: qcom: Add support for SDX55 APCS IPC
I think I can apply the clk patches to clk tree without the mailbox
patches, right?
Yes, you can. Thanks for applying!
Jassi: Can you please look into the mailbox patches?
They are compatible strings mostly... so assume it ok.
cheers!