As pointed out during patch review, we should make sure that we turn on
the CX power domain when camcc is in use, and also disable it (or remove
our vote on it) when camcc is not in use.
For this add pm_runtime support to the driver and stick the power-domain
in the devicetree.
Signed-off-by: Luca Weiss <[email protected]>
---
Changes in v2:
- no change resend since I messed up To/CC in the initial submission
- Link to v1: https://lore.kernel.org/r/[email protected]
---
Luca Weiss (2):
clk: qcom: camcc-sm6350: add pm_runtime support
arm64: dts: qcom: sm6350: add power domain to camcc
arch/arm64/boot/dts/qcom/sm6350.dtsi | 2 ++
drivers/clk/qcom/camcc-sm6350.c | 29 ++++++++++++++++++++++++++++-
2 files changed, 30 insertions(+), 1 deletion(-)
---
base-commit: 09e41676e35ab06e4bce8870ea3bf1f191c3cb90
change-id: 20230213-sm6350-camcc-runtime_pm-639b75c3d4b1
Best regards,
--
Luca Weiss <[email protected]>
Make sure that we can enable and disable the power domains used for
camcc when the clocks are and aren't used.
Signed-off-by: Luca Weiss <[email protected]>
---
drivers/clk/qcom/camcc-sm6350.c | 29 ++++++++++++++++++++++++++++-
1 file changed, 28 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/qcom/camcc-sm6350.c b/drivers/clk/qcom/camcc-sm6350.c
index acba9f99d960..dd65f3ef0857 100644
--- a/drivers/clk/qcom/camcc-sm6350.c
+++ b/drivers/clk/qcom/camcc-sm6350.c
@@ -7,6 +7,8 @@
#include <linux/clk-provider.h>
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/pm_clock.h>
+#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <dt-bindings/clock/qcom,sm6350-camcc.h>
@@ -1869,6 +1871,19 @@ MODULE_DEVICE_TABLE(of, camcc_sm6350_match_table);
static int camcc_sm6350_probe(struct platform_device *pdev)
{
struct regmap *regmap;
+ int ret;
+
+ ret = devm_pm_runtime_enable(&pdev->dev);
+ if (ret < 0)
+ return ret;
+
+ ret = devm_pm_clk_create(&pdev->dev);
+ if (ret < 0)
+ return ret;
+
+ ret = pm_runtime_get(&pdev->dev);
+ if (ret)
+ return ret;
regmap = qcom_cc_map(pdev, &camcc_sm6350_desc);
if (IS_ERR(regmap))
@@ -1879,14 +1894,26 @@ static int camcc_sm6350_probe(struct platform_device *pdev)
clk_agera_pll_configure(&camcc_pll2, regmap, &camcc_pll2_config);
clk_fabia_pll_configure(&camcc_pll3, regmap, &camcc_pll3_config);
- return qcom_cc_really_probe(pdev, &camcc_sm6350_desc, regmap);
+ ret = qcom_cc_really_probe(pdev, &camcc_sm6350_desc, regmap);
+ pm_runtime_put(&pdev->dev);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Failed to register CAM CC clocks\n");
+ return ret;
+ }
+
+ return 0;
}
+static const struct dev_pm_ops camcc_pm_ops = {
+ SET_RUNTIME_PM_OPS(pm_clk_suspend, pm_clk_resume, NULL)
+};
+
static struct platform_driver camcc_sm6350_driver = {
.probe = camcc_sm6350_probe,
.driver = {
.name = "sm6350-camcc",
.of_match_table = camcc_sm6350_match_table,
+ .pm = &camcc_pm_ops,
},
};
--
2.39.1
Add the CX power domain to the camcc node so the power domain gets
marked as in-use when camcc is used.
Signed-off-by: Luca Weiss <[email protected]>
---
arch/arm64/boot/dts/qcom/sm6350.dtsi | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/sm6350.dtsi b/arch/arm64/boot/dts/qcom/sm6350.dtsi
index 1e1d366c92c1..62d6dcd8d1fe 100644
--- a/arch/arm64/boot/dts/qcom/sm6350.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm6350.dtsi
@@ -1507,6 +1507,8 @@ camcc: clock-controller@ad00000 {
compatible = "qcom,sm6350-camcc";
reg = <0 0x0ad00000 0 0x16000>;
clocks = <&rpmhcc RPMH_CXO_CLK>;
+ power-domains = <&rpmhpd SM6350_CX>;
+ required-opps = <&rpmhpd_opp_low_svs>;
#clock-cells = <1>;
#reset-cells = <1>;
#power-domain-cells = <1>;
--
2.39.1
On Montag, 13. Februar 2023 14:08:06 CET Luca Weiss wrote:
> Make sure that we can enable and disable the power domains used for
> camcc when the clocks are and aren't used.
>
> Signed-off-by: Luca Weiss <[email protected]>
Apparently I messed up v2 too and had the wrong email in my git config. Will
send a v3 to fix that as well...
> ---
> drivers/clk/qcom/camcc-sm6350.c | 29 ++++++++++++++++++++++++++++-
> 1 file changed, 28 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/clk/qcom/camcc-sm6350.c
> b/drivers/clk/qcom/camcc-sm6350.c index acba9f99d960..dd65f3ef0857 100644
> --- a/drivers/clk/qcom/camcc-sm6350.c
> +++ b/drivers/clk/qcom/camcc-sm6350.c
> @@ -7,6 +7,8 @@
> #include <linux/clk-provider.h>
> #include <linux/module.h>
> #include <linux/platform_device.h>
> +#include <linux/pm_clock.h>
> +#include <linux/pm_runtime.h>
> #include <linux/regmap.h>
>
> #include <dt-bindings/clock/qcom,sm6350-camcc.h>
> @@ -1869,6 +1871,19 @@ MODULE_DEVICE_TABLE(of, camcc_sm6350_match_table);
> static int camcc_sm6350_probe(struct platform_device *pdev)
> {
> struct regmap *regmap;
> + int ret;
> +
> + ret = devm_pm_runtime_enable(&pdev->dev);
> + if (ret < 0)
> + return ret;
> +
> + ret = devm_pm_clk_create(&pdev->dev);
> + if (ret < 0)
> + return ret;
> +
> + ret = pm_runtime_get(&pdev->dev);
> + if (ret)
> + return ret;
>
> regmap = qcom_cc_map(pdev, &camcc_sm6350_desc);
> if (IS_ERR(regmap))
> @@ -1879,14 +1894,26 @@ static int camcc_sm6350_probe(struct platform_device
> *pdev) clk_agera_pll_configure(&camcc_pll2, regmap, &camcc_pll2_config);
> clk_fabia_pll_configure(&camcc_pll3, regmap, &camcc_pll3_config);
>
> - return qcom_cc_really_probe(pdev, &camcc_sm6350_desc, regmap);
> + ret = qcom_cc_really_probe(pdev, &camcc_sm6350_desc, regmap);
> + pm_runtime_put(&pdev->dev);
> + if (ret < 0) {
> + dev_err(&pdev->dev, "Failed to register CAM CC
clocks\n");
> + return ret;
> + }
> +
> + return 0;
> }
>
> +static const struct dev_pm_ops camcc_pm_ops = {
> + SET_RUNTIME_PM_OPS(pm_clk_suspend, pm_clk_resume, NULL)
> +};
> +
> static struct platform_driver camcc_sm6350_driver = {
> .probe = camcc_sm6350_probe,
> .driver = {
> .name = "sm6350-camcc",
> .of_match_table = camcc_sm6350_match_table,
> + .pm = &camcc_pm_ops,
> },
> };