diff options
author | Linaro CI <ci_notify@linaro.org> | 2021-10-18 15:51:28 +0000 |
---|---|---|
committer | Linaro CI <ci_notify@linaro.org> | 2021-10-18 15:51:28 +0000 |
commit | e5a6fe5cec19d6ca96c5e1887bd677dea0a978fd (patch) | |
tree | 850324a879261cdc4993d3a39cabe8e7978649a8 | |
parent | 381e56c5af246267c3c14b0b78b1c0bfa1b5358f (diff) | |
parent | b0ec4d7fab3bc62bd16d0de28c234980416b863b (diff) |
Merge remote-tracking branch 'sm8250-gdsc/tracking-qcomlt-sm8250-gdsc' into integration-linux-qcomlt
-rw-r--r-- | Documentation/devicetree/bindings/clock/qcom,dispcc-sm8x50.yaml | 13 | ||||
-rw-r--r-- | Documentation/devicetree/bindings/clock/qcom,videocc.yaml | 13 | ||||
-rw-r--r-- | arch/arm64/boot/dts/qcom/sm8250.dtsi | 13 | ||||
-rw-r--r-- | drivers/clk/qcom/dispcc-sm8250.c | 28 | ||||
-rw-r--r-- | drivers/clk/qcom/gdsc.c | 51 | ||||
-rw-r--r-- | drivers/clk/qcom/gdsc.h | 2 | ||||
-rw-r--r-- | drivers/clk/qcom/videocc-sm8250.c | 31 |
7 files changed, 130 insertions, 21 deletions
diff --git a/Documentation/devicetree/bindings/clock/qcom,dispcc-sm8x50.yaml b/Documentation/devicetree/bindings/clock/qcom,dispcc-sm8x50.yaml index 6667261dc665..31497677e8de 100644 --- a/Documentation/devicetree/bindings/clock/qcom,dispcc-sm8x50.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,dispcc-sm8x50.yaml @@ -56,6 +56,16 @@ properties: reg: maxItems: 1 + power-domains: + description: + A phandle and PM domain specifier for the MMCX power domain. + maxItems: 1 + + required-opps: + description: + A phandle to an OPP node describing required MMCX performance point. + maxItems: 1 + required: - compatible - reg @@ -70,6 +80,7 @@ additionalProperties: false examples: - | #include <dt-bindings/clock/qcom,rpmh.h> + #include <dt-bindings/power/qcom-rpmpd.h> clock-controller@af00000 { compatible = "qcom,sm8250-dispcc"; reg = <0x0af00000 0x10000>; @@ -90,5 +101,7 @@ examples: #clock-cells = <1>; #reset-cells = <1>; #power-domain-cells = <1>; + power-domains = <&rpmhpd SM8250_MMCX>; + required-opps = <&rpmhpd_opp_low_svs>; }; ... diff --git a/Documentation/devicetree/bindings/clock/qcom,videocc.yaml b/Documentation/devicetree/bindings/clock/qcom,videocc.yaml index 0d224f114b5b..3cdbcebdc1a1 100644 --- a/Documentation/devicetree/bindings/clock/qcom,videocc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,videocc.yaml @@ -49,6 +49,16 @@ properties: reg: maxItems: 1 + power-domains: + description: + A phandle and PM domain specifier for the MMCX power domain. + maxItems: 1 + + required-opps: + description: + A phandle to an OPP node describing required MMCX performance point. + maxItems: 1 + required: - compatible - reg @@ -63,6 +73,7 @@ additionalProperties: false examples: - | #include <dt-bindings/clock/qcom,rpmh.h> + #include <dt-bindings/power/qcom-rpmpd.h> clock-controller@ab00000 { compatible = "qcom,sdm845-videocc"; reg = <0x0ab00000 0x10000>; @@ -71,5 +82,7 @@ examples: #clock-cells = <1>; #reset-cells = <1>; #power-domain-cells = <1>; + power-domains = <&rpmhpd SM8250_MMCX>; + required-opps = <&rpmhpd_opp_low_svs>; }; ... diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi b/arch/arm64/boot/dts/qcom/sm8250.dtsi index 0495a9f1d935..1fe47248bd20 100644 --- a/arch/arm64/boot/dts/qcom/sm8250.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi @@ -351,13 +351,6 @@ reg = <0x0 0x80000000 0x0 0x0>; }; - mmcx_reg: mmcx-reg { - compatible = "regulator-fixed-domain"; - power-domains = <&rpmhpd SM8250_MMCX>; - required-opps = <&rpmhpd_opp_low_svs>; - regulator-name = "MMCX"; - }; - pmu { compatible = "arm,armv8-pmuv3"; interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>; @@ -2684,7 +2677,8 @@ clocks = <&gcc GCC_VIDEO_AHB_CLK>, <&rpmhcc RPMH_CXO_CLK>, <&rpmhcc RPMH_CXO_CLK_A>; - mmcx-supply = <&mmcx_reg>; + power-domains = <&rpmhpd SM8250_MMCX>; + required-opps = <&rpmhpd_opp_low_svs>; clock-names = "iface", "bi_tcxo", "bi_tcxo_ao"; #clock-cells = <1>; #reset-cells = <1>; @@ -2958,7 +2952,8 @@ dispcc: clock-controller@af00000 { compatible = "qcom,sm8250-dispcc"; reg = <0 0x0af00000 0 0x10000>; - mmcx-supply = <&mmcx_reg>; + power-domains = <&rpmhpd SM8250_MMCX>; + required-opps = <&rpmhpd_opp_low_svs>; clocks = <&rpmhcc RPMH_CXO_CLK>, <&dsi0_phy 0>, <&dsi0_phy 1>, diff --git a/drivers/clk/qcom/dispcc-sm8250.c b/drivers/clk/qcom/dispcc-sm8250.c index bf9ffe1a1cf4..ac6e68064ea5 100644 --- a/drivers/clk/qcom/dispcc-sm8250.c +++ b/drivers/clk/qcom/dispcc-sm8250.c @@ -6,6 +6,7 @@ #include <linux/clk-provider.h> #include <linux/module.h> #include <linux/platform_device.h> +#include <linux/pm_runtime.h> #include <linux/regmap.h> #include <linux/reset-controller.h> @@ -1130,7 +1131,6 @@ static struct gdsc mdss_gdsc = { }, .pwrsts = PWRSTS_OFF_ON, .flags = HW_CTRL, - .supply = "mmcx", }; static struct clk_regmap *disp_cc_sm8250_clocks[] = { @@ -1228,13 +1228,31 @@ static const struct of_device_id disp_cc_sm8250_match_table[] = { }; MODULE_DEVICE_TABLE(of, disp_cc_sm8250_match_table); +static void disp_cc_sm8250_pm_runtime_disable(void *data) +{ + pm_runtime_disable(data); +} + static int disp_cc_sm8250_probe(struct platform_device *pdev) { struct regmap *regmap; + int ret; + + pm_runtime_enable(&pdev->dev); + + ret = devm_add_action_or_reset(&pdev->dev, disp_cc_sm8250_pm_runtime_disable, &pdev->dev); + if (ret) + return ret; + + ret = pm_runtime_resume_and_get(&pdev->dev); + if (ret) + return ret; regmap = qcom_cc_map(pdev, &disp_cc_sm8250_desc); - if (IS_ERR(regmap)) + if (IS_ERR(regmap)) { + pm_runtime_put(&pdev->dev); return PTR_ERR(regmap); + } /* note: trion == lucid, except for the prepare() op */ BUILD_BUG_ON(CLK_ALPHA_PLL_TYPE_TRION != CLK_ALPHA_PLL_TYPE_LUCID); @@ -1259,7 +1277,11 @@ static int disp_cc_sm8250_probe(struct platform_device *pdev) /* DISP_CC_XO_CLK always-on */ regmap_update_bits(regmap, 0x605c, BIT(0), BIT(0)); - return qcom_cc_really_probe(pdev, &disp_cc_sm8250_desc, regmap); + ret = qcom_cc_really_probe(pdev, &disp_cc_sm8250_desc, regmap); + + pm_runtime_put(&pdev->dev); + + return ret; } static struct platform_driver disp_cc_sm8250_driver = { diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c index 4ece326ea233..7e1dd8ccfa38 100644 --- a/drivers/clk/qcom/gdsc.c +++ b/drivers/clk/qcom/gdsc.c @@ -11,6 +11,7 @@ #include <linux/kernel.h> #include <linux/ktime.h> #include <linux/pm_domain.h> +#include <linux/pm_runtime.h> #include <linux/regmap.h> #include <linux/regulator/consumer.h> #include <linux/reset-controller.h> @@ -50,6 +51,22 @@ enum gdsc_status { GDSC_ON }; +static int gdsc_pm_runtime_get(struct gdsc *sc) +{ + if (!sc->dev) + return 0; + + return pm_runtime_resume_and_get(sc->dev); +} + +static int gdsc_pm_runtime_put(struct gdsc *sc) +{ + if (!sc->dev) + return 0; + + return pm_runtime_put_sync(sc->dev); +} + /* Returns 1 if GDSC status is status, 0 if not, and < 0 on error */ static int gdsc_check_status(struct gdsc *sc, enum gdsc_status status) { @@ -232,9 +249,8 @@ static void gdsc_retain_ff_on(struct gdsc *sc) regmap_update_bits(sc->regmap, sc->gdscr, mask, mask); } -static int gdsc_enable(struct generic_pm_domain *domain) +static int _gdsc_enable(struct gdsc *sc) { - struct gdsc *sc = domain_to_gdsc(domain); int ret; if (sc->pwrsts == PWRSTS_ON) @@ -290,11 +306,22 @@ static int gdsc_enable(struct generic_pm_domain *domain) return 0; } -static int gdsc_disable(struct generic_pm_domain *domain) +static int gdsc_enable(struct generic_pm_domain *domain) { struct gdsc *sc = domain_to_gdsc(domain); int ret; + ret = gdsc_pm_runtime_get(sc); + if (ret) + return ret; + + return _gdsc_enable(sc); +} + +static int _gdsc_disable(struct gdsc *sc) +{ + int ret; + if (sc->pwrsts == PWRSTS_ON) return gdsc_assert_reset(sc); @@ -329,6 +356,18 @@ static int gdsc_disable(struct generic_pm_domain *domain) return 0; } +static int gdsc_disable(struct generic_pm_domain *domain) +{ + struct gdsc *sc = domain_to_gdsc(domain); + int ret; + + ret = _gdsc_disable(sc); + + gdsc_pm_runtime_put(sc); + + return ret; +} + static int gdsc_init(struct gdsc *sc) { u32 mask, val; @@ -443,6 +482,8 @@ int gdsc_register(struct gdsc_desc *desc, for (i = 0; i < num; i++) { if (!scs[i]) continue; + if (pm_runtime_enabled(dev)) + scs[i]->dev = dev; scs[i]->regmap = regmap; scs[i]->rcdev = rcdev; ret = gdsc_init(scs[i]); @@ -457,6 +498,8 @@ int gdsc_register(struct gdsc_desc *desc, continue; if (scs[i]->parent) pm_genpd_add_subdomain(scs[i]->parent, &scs[i]->pd); + else if (!IS_ERR_OR_NULL(dev->pm_domain)) + pm_genpd_add_subdomain(pd_to_genpd(dev->pm_domain), &scs[i]->pd); } return of_genpd_add_provider_onecell(dev->of_node, data); @@ -475,6 +518,8 @@ void gdsc_unregister(struct gdsc_desc *desc) continue; if (scs[i]->parent) pm_genpd_remove_subdomain(scs[i]->parent, &scs[i]->pd); + else if (!IS_ERR_OR_NULL(dev->pm_domain)) + pm_genpd_remove_subdomain(pd_to_genpd(dev->pm_domain), &scs[i]->pd); } of_genpd_del_provider(dev->of_node); } diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h index 5bb396b344d1..702d47a87af6 100644 --- a/drivers/clk/qcom/gdsc.h +++ b/drivers/clk/qcom/gdsc.h @@ -25,6 +25,7 @@ struct reset_controller_dev; * @resets: ids of resets associated with this gdsc * @reset_count: number of @resets * @rcdev: reset controller + * @dev: the device holding the GDSC, used for pm_runtime calls */ struct gdsc { struct generic_pm_domain pd; @@ -58,6 +59,7 @@ struct gdsc { const char *supply; struct regulator *rsupply; + struct device *dev; }; struct gdsc_desc { diff --git a/drivers/clk/qcom/videocc-sm8250.c b/drivers/clk/qcom/videocc-sm8250.c index 7b435a1c2c4b..f28f2cb051d7 100644 --- a/drivers/clk/qcom/videocc-sm8250.c +++ b/drivers/clk/qcom/videocc-sm8250.c @@ -6,6 +6,7 @@ #include <linux/clk-provider.h> #include <linux/module.h> #include <linux/platform_device.h> +#include <linux/pm_runtime.h> #include <linux/regmap.h> #include <dt-bindings/clock/qcom,videocc-sm8250.h> @@ -276,7 +277,6 @@ static struct gdsc mvs0c_gdsc = { }, .flags = 0, .pwrsts = PWRSTS_OFF_ON, - .supply = "mmcx", }; static struct gdsc mvs1c_gdsc = { @@ -286,7 +286,6 @@ static struct gdsc mvs1c_gdsc = { }, .flags = 0, .pwrsts = PWRSTS_OFF_ON, - .supply = "mmcx", }; static struct gdsc mvs0_gdsc = { @@ -296,7 +295,6 @@ static struct gdsc mvs0_gdsc = { }, .flags = HW_CTRL, .pwrsts = PWRSTS_OFF_ON, - .supply = "mmcx", }; static struct gdsc mvs1_gdsc = { @@ -306,7 +304,6 @@ static struct gdsc mvs1_gdsc = { }, .flags = HW_CTRL, .pwrsts = PWRSTS_OFF_ON, - .supply = "mmcx", }; static struct clk_regmap *video_cc_sm8250_clocks[] = { @@ -364,13 +361,31 @@ static const struct of_device_id video_cc_sm8250_match_table[] = { }; MODULE_DEVICE_TABLE(of, video_cc_sm8250_match_table); +static void video_cc_sm8250_pm_runtime_disable(void *data) +{ + pm_runtime_disable(data); +} + static int video_cc_sm8250_probe(struct platform_device *pdev) { struct regmap *regmap; + int ret; + + pm_runtime_enable(&pdev->dev); + + ret = devm_add_action_or_reset(&pdev->dev, video_cc_sm8250_pm_runtime_disable, &pdev->dev); + if (ret) + return ret; + + ret = pm_runtime_resume_and_get(&pdev->dev); + if (ret) + return ret; regmap = qcom_cc_map(pdev, &video_cc_sm8250_desc); - if (IS_ERR(regmap)) + if (IS_ERR(regmap)) { + pm_runtime_put(&pdev->dev); return PTR_ERR(regmap); + } clk_lucid_pll_configure(&video_pll0, regmap, &video_pll0_config); clk_lucid_pll_configure(&video_pll1, regmap, &video_pll1_config); @@ -379,7 +394,11 @@ static int video_cc_sm8250_probe(struct platform_device *pdev) regmap_update_bits(regmap, 0xe58, BIT(0), BIT(0)); regmap_update_bits(regmap, 0xeec, BIT(0), BIT(0)); - return qcom_cc_really_probe(pdev, &video_cc_sm8250_desc, regmap); + ret = qcom_cc_really_probe(pdev, &video_cc_sm8250_desc, regmap); + + pm_runtime_put(&pdev->dev); + + return ret; } static struct platform_driver video_cc_sm8250_driver = { |