Loading Documentation/devicetree/bindings/arm/msm/clock-controller-v2.txt +81 −0 Original line number Diff line number Diff line Loading @@ -310,3 +310,84 @@ mmss_gpll0_clk_src: mmss_gpll0_clk_src { qcom,parent = <&gpll0>; qcom,delay = <1>; }; ***************************************************************************** "qcom,votable-pll" A software construct defining a PLL (Phase-locked Loop) which can be voted for. Required Properties: - compatible: Must be "qcom,votable-pll" - qcom,en-offset: Register offset from the region described in parent clock controller. - qcom,en-bit: Bit used to enable the clock - qcom,status-offset: Register offset from the region described in parent clock controller. - qcom,status-bit: Status bit indicating the clock is on - qcom,pll-config-rate: The rate this clock runs at. This rate is not changeable. Recommended Properties: - qcom,parent: See "General Optional Properties" - qcom,supply-group: See "General Optional Properties" - qcom,clk-fmax: See "General Optional Properties" gpll4: gpll4 { compatible = "qcom,votable-pll"; qcom,en-offset = <GCC_APCS_GPLL_ENA_VOTE>; qcom,en-bit = <4>; qcom,status-offset = <GCC_GPLL4_MODE>; qcom,status-bit = <30>; qcom,pll-config-rate = <1536000000>; qcom,parent = <&gcc_xo>; qcom,supply-group = <&gcc_vdd_dig>; qcom,clk-fmax = <FMAX_LOWER 400000000>, <FMAX_LOW 800000000>, <FMAX_NOM 1600000000>, <FMAX_TURBO 1600000000>; }; ***************************************************************************** "qcom,sleep-active-pll" A software construct wrapping the normal votable pll hw. Like rpm_clocks, these clocks also support "active" and "sleep" modes of operation. Required Properties: - compatible: "qcom,active-only-pll", "qcom,sleep-active-pll" - qcom,en-offset: Register offset from the region described in parent clock controller. - qcom,en-bit: Bit used to enable the clock - qcom,status-offset: Register offset from the region described in parent clock controller. - qcom,status-bit: Status bit indicating the clock is on - qcom,peer: Phandle to the other clock in the pair - qcom,pll-config-rate: The rate this clock runs at. This rate is not changeable. Recommended Properties: - qcom,parent: See "General Optional Properties" - qcom,clk-fmax: See "General Optional Properties" gpll0: gpll0 { compatible = "qcom,sleep-active-pll"; qcom,en-offset = <GCC_APCS_GPLL_ENA_VOTE>; qcom,en-bit = <0>; qcom,status-offset = <GCC_GPLL0_MODE>; qcom,status-bit = <30>; qcom,pll-config-rate = <600000000>; qcom,parent = <&gcc_xo>; qcom,peer = <&gpll0_ao>; }; gpll0_ao: gpll0_ao { compatible = "qcom,active-only-pll"; qcom,en-offset = <GCC_APCS_GPLL_ENA_VOTE>; qcom,en-bit = <0>; qcom,status-offset = <GCC_GPLL0_MODE>; qcom,status-bit = <30>; qcom,pll-config-rate = <600000000>; qcom,parent = <&gcc_xo_ao>; qcom,peer = <&gpll0>; }; drivers/clk/qcom/clock-pll.c +92 −0 Original line number Diff line number Diff line Loading @@ -12,12 +12,15 @@ * */ #define pr_fmt(fmt) "%s: " fmt, __func__ #include <linux/kernel.h> #include <linux/delay.h> #include <linux/err.h> #include <linux/clk.h> #include <linux/io.h> #include <soc/qcom/clock-pll.h> #include <soc/qcom/msm-clock-controller.h> #include "clock.h" Loading Loading @@ -829,3 +832,92 @@ void configure_sr_hpm_lp_pll(struct pll_config *config, __set_fsm_mode(PLL_MODE_REG(regs), 0x1, 0x0); } static void *votable_pll_clk_dt_parser(struct device *dev, struct device_node *np) { struct pll_vote_clk *v, *peer; struct clk *c; u32 val, rc; phandle p; struct msmclk_data *drv; v = devm_kzalloc(dev, sizeof(*v), GFP_KERNEL); if (!v) { dt_err(np, "memory alloc failure\n"); return ERR_PTR(-ENOMEM); } drv = msmclk_parse_phandle(dev, np->parent->phandle); if (IS_ERR_OR_NULL(drv)) return ERR_CAST(drv); v->base = &drv->base; rc = of_property_read_u32(np, "qcom,en-offset", (u32 *)&v->en_reg); if (rc) { dt_err(np, "missing qcom,en-offset dt property\n"); return ERR_PTR(-EINVAL); } rc = of_property_read_u32(np, "qcom,en-bit", &val); if (rc) { dt_err(np, "missing qcom,en-bit dt property\n"); return ERR_PTR(-EINVAL); } v->en_mask = BIT(val); rc = of_property_read_u32(np, "qcom,status-offset", (u32 *)&v->status_reg); if (rc) { dt_err(np, "missing qcom,status-offset dt property\n"); return ERR_PTR(-EINVAL); } rc = of_property_read_u32(np, "qcom,status-bit", &val); if (rc) { dt_err(np, "missing qcom,status-bit dt property\n"); return ERR_PTR(-EINVAL); } v->status_mask = BIT(val); rc = of_property_read_u32(np, "qcom,pll-config-rate", &val); if (rc) { dt_err(np, "missing qcom,pll-config-rate dt property\n"); return ERR_PTR(-EINVAL); } v->c.rate = val; if (of_device_is_compatible(np, "qcom,active-only-pll")) v->soft_vote_mask = PLL_SOFT_VOTE_ACPU; else if (of_device_is_compatible(np, "qcom,sleep-active-pll")) v->soft_vote_mask = PLL_SOFT_VOTE_PRIMARY; if (of_device_is_compatible(np, "qcom,votable-pll")) { v->c.ops = &clk_ops_pll_vote; return msmclk_generic_clk_init(dev, np, &v->c); } rc = of_property_read_phandle_index(np, "qcom,peer", 0, &p); if (rc) { dt_err(np, "missing qcom,peer dt property\n"); return ERR_PTR(-EINVAL); } c = msmclk_lookup_phandle(dev, p); if (!IS_ERR_OR_NULL(c)) { v->soft_vote = devm_kzalloc(dev, sizeof(*v->soft_vote), GFP_KERNEL); if (!v->soft_vote) { dt_err(np, "memory alloc failure\n"); return ERR_PTR(-ENOMEM); } peer = to_pll_vote_clk(c); peer->soft_vote = v->soft_vote; } v->c.ops = &clk_ops_pll_acpu_vote; return msmclk_generic_clk_init(dev, np, &v->c); } MSMCLK_PARSER(votable_pll_clk_dt_parser, "qcom,active-only-pll", 0); MSMCLK_PARSER(votable_pll_clk_dt_parser, "qcom,sleep-active-pll", 1); MSMCLK_PARSER(votable_pll_clk_dt_parser, "qcom,votable-pll", 2); include/soc/qcom/clock-pll.h +3 −3 Original line number Diff line number Diff line Loading @@ -82,11 +82,11 @@ struct pll_config_vals { */ struct pll_vote_clk { u32 *soft_vote; const u32 soft_vote_mask; u32 soft_vote_mask; void __iomem *const en_reg; const u32 en_mask; u32 en_mask; void __iomem *const status_reg; const u32 status_mask; u32 status_mask; struct clk c; void *const __iomem *base; Loading Loading
Documentation/devicetree/bindings/arm/msm/clock-controller-v2.txt +81 −0 Original line number Diff line number Diff line Loading @@ -310,3 +310,84 @@ mmss_gpll0_clk_src: mmss_gpll0_clk_src { qcom,parent = <&gpll0>; qcom,delay = <1>; }; ***************************************************************************** "qcom,votable-pll" A software construct defining a PLL (Phase-locked Loop) which can be voted for. Required Properties: - compatible: Must be "qcom,votable-pll" - qcom,en-offset: Register offset from the region described in parent clock controller. - qcom,en-bit: Bit used to enable the clock - qcom,status-offset: Register offset from the region described in parent clock controller. - qcom,status-bit: Status bit indicating the clock is on - qcom,pll-config-rate: The rate this clock runs at. This rate is not changeable. Recommended Properties: - qcom,parent: See "General Optional Properties" - qcom,supply-group: See "General Optional Properties" - qcom,clk-fmax: See "General Optional Properties" gpll4: gpll4 { compatible = "qcom,votable-pll"; qcom,en-offset = <GCC_APCS_GPLL_ENA_VOTE>; qcom,en-bit = <4>; qcom,status-offset = <GCC_GPLL4_MODE>; qcom,status-bit = <30>; qcom,pll-config-rate = <1536000000>; qcom,parent = <&gcc_xo>; qcom,supply-group = <&gcc_vdd_dig>; qcom,clk-fmax = <FMAX_LOWER 400000000>, <FMAX_LOW 800000000>, <FMAX_NOM 1600000000>, <FMAX_TURBO 1600000000>; }; ***************************************************************************** "qcom,sleep-active-pll" A software construct wrapping the normal votable pll hw. Like rpm_clocks, these clocks also support "active" and "sleep" modes of operation. Required Properties: - compatible: "qcom,active-only-pll", "qcom,sleep-active-pll" - qcom,en-offset: Register offset from the region described in parent clock controller. - qcom,en-bit: Bit used to enable the clock - qcom,status-offset: Register offset from the region described in parent clock controller. - qcom,status-bit: Status bit indicating the clock is on - qcom,peer: Phandle to the other clock in the pair - qcom,pll-config-rate: The rate this clock runs at. This rate is not changeable. Recommended Properties: - qcom,parent: See "General Optional Properties" - qcom,clk-fmax: See "General Optional Properties" gpll0: gpll0 { compatible = "qcom,sleep-active-pll"; qcom,en-offset = <GCC_APCS_GPLL_ENA_VOTE>; qcom,en-bit = <0>; qcom,status-offset = <GCC_GPLL0_MODE>; qcom,status-bit = <30>; qcom,pll-config-rate = <600000000>; qcom,parent = <&gcc_xo>; qcom,peer = <&gpll0_ao>; }; gpll0_ao: gpll0_ao { compatible = "qcom,active-only-pll"; qcom,en-offset = <GCC_APCS_GPLL_ENA_VOTE>; qcom,en-bit = <0>; qcom,status-offset = <GCC_GPLL0_MODE>; qcom,status-bit = <30>; qcom,pll-config-rate = <600000000>; qcom,parent = <&gcc_xo_ao>; qcom,peer = <&gpll0>; };
drivers/clk/qcom/clock-pll.c +92 −0 Original line number Diff line number Diff line Loading @@ -12,12 +12,15 @@ * */ #define pr_fmt(fmt) "%s: " fmt, __func__ #include <linux/kernel.h> #include <linux/delay.h> #include <linux/err.h> #include <linux/clk.h> #include <linux/io.h> #include <soc/qcom/clock-pll.h> #include <soc/qcom/msm-clock-controller.h> #include "clock.h" Loading Loading @@ -829,3 +832,92 @@ void configure_sr_hpm_lp_pll(struct pll_config *config, __set_fsm_mode(PLL_MODE_REG(regs), 0x1, 0x0); } static void *votable_pll_clk_dt_parser(struct device *dev, struct device_node *np) { struct pll_vote_clk *v, *peer; struct clk *c; u32 val, rc; phandle p; struct msmclk_data *drv; v = devm_kzalloc(dev, sizeof(*v), GFP_KERNEL); if (!v) { dt_err(np, "memory alloc failure\n"); return ERR_PTR(-ENOMEM); } drv = msmclk_parse_phandle(dev, np->parent->phandle); if (IS_ERR_OR_NULL(drv)) return ERR_CAST(drv); v->base = &drv->base; rc = of_property_read_u32(np, "qcom,en-offset", (u32 *)&v->en_reg); if (rc) { dt_err(np, "missing qcom,en-offset dt property\n"); return ERR_PTR(-EINVAL); } rc = of_property_read_u32(np, "qcom,en-bit", &val); if (rc) { dt_err(np, "missing qcom,en-bit dt property\n"); return ERR_PTR(-EINVAL); } v->en_mask = BIT(val); rc = of_property_read_u32(np, "qcom,status-offset", (u32 *)&v->status_reg); if (rc) { dt_err(np, "missing qcom,status-offset dt property\n"); return ERR_PTR(-EINVAL); } rc = of_property_read_u32(np, "qcom,status-bit", &val); if (rc) { dt_err(np, "missing qcom,status-bit dt property\n"); return ERR_PTR(-EINVAL); } v->status_mask = BIT(val); rc = of_property_read_u32(np, "qcom,pll-config-rate", &val); if (rc) { dt_err(np, "missing qcom,pll-config-rate dt property\n"); return ERR_PTR(-EINVAL); } v->c.rate = val; if (of_device_is_compatible(np, "qcom,active-only-pll")) v->soft_vote_mask = PLL_SOFT_VOTE_ACPU; else if (of_device_is_compatible(np, "qcom,sleep-active-pll")) v->soft_vote_mask = PLL_SOFT_VOTE_PRIMARY; if (of_device_is_compatible(np, "qcom,votable-pll")) { v->c.ops = &clk_ops_pll_vote; return msmclk_generic_clk_init(dev, np, &v->c); } rc = of_property_read_phandle_index(np, "qcom,peer", 0, &p); if (rc) { dt_err(np, "missing qcom,peer dt property\n"); return ERR_PTR(-EINVAL); } c = msmclk_lookup_phandle(dev, p); if (!IS_ERR_OR_NULL(c)) { v->soft_vote = devm_kzalloc(dev, sizeof(*v->soft_vote), GFP_KERNEL); if (!v->soft_vote) { dt_err(np, "memory alloc failure\n"); return ERR_PTR(-ENOMEM); } peer = to_pll_vote_clk(c); peer->soft_vote = v->soft_vote; } v->c.ops = &clk_ops_pll_acpu_vote; return msmclk_generic_clk_init(dev, np, &v->c); } MSMCLK_PARSER(votable_pll_clk_dt_parser, "qcom,active-only-pll", 0); MSMCLK_PARSER(votable_pll_clk_dt_parser, "qcom,sleep-active-pll", 1); MSMCLK_PARSER(votable_pll_clk_dt_parser, "qcom,votable-pll", 2);
include/soc/qcom/clock-pll.h +3 −3 Original line number Diff line number Diff line Loading @@ -82,11 +82,11 @@ struct pll_config_vals { */ struct pll_vote_clk { u32 *soft_vote; const u32 soft_vote_mask; u32 soft_vote_mask; void __iomem *const en_reg; const u32 en_mask; u32 en_mask; void __iomem *const status_reg; const u32 status_mask; u32 status_mask; struct clk c; void *const __iomem *base; Loading