From 819c1de344c5b8350bffd35be9a0fa74541292d3 Mon Sep 17 00:00:00 2001 From: James Hogan Date: Mon, 29 Jul 2013 12:25:01 +0100 Subject: clk: add CLK_SET_RATE_NO_REPARENT flag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a CLK_SET_RATE_NO_REPARENT clock flag, which will prevent muxes being reparented during clk_set_rate. To avoid breaking existing platforms, all callers of clk_register_mux() are adjusted to pass the new flag. Platform maintainers are encouraged to remove the flag if they wish to allow mux reparenting on set_rate. Signed-off-by: James Hogan Reviewed-by: Stephen Boyd Cc: Mike Turquette Cc: Russell King Cc: Sascha Hauer Cc: Stephen Warren Cc: Viresh Kumar Cc: Kukjin Kim Cc: Haojian Zhuang Cc: Chao Xie Cc: Arnd Bergmann Cc: "Emilio López" Cc: Gregory CLEMENT Cc: Maxime Ripard Cc: Prashant Gaikwad Cc: Thierry Reding Cc: Peter De Schrijver Cc: Pawel Moll Cc: Catalin Marinas Cc: Andrew Chew Cc: Doug Anderson Cc: Heiko Stuebner Cc: Paul Walmsley Cc: Sylwester Nawrocki Cc: Thomas Abraham Cc: Tomasz Figa Cc: linux-arm-kernel@lists.infradead.org Cc: linux-samsung-soc@vger.kernel.org Cc: spear-devel@list.st.com Cc: linux-tegra@vger.kernel.org Tested-by: Haojian Zhuang Acked-by: Stephen Warren [tegra] Acked-by: Maxime Ripard [sunxi] Acked-by: Sören Brinkmann [Zynq] Signed-off-by: Mike Turquette --- drivers/clk/zynq/clkc.c | 86 ++++++++++++++++++++++++++++--------------------- 1 file changed, 50 insertions(+), 36 deletions(-) (limited to 'drivers/clk/zynq') diff --git a/drivers/clk/zynq/clkc.c b/drivers/clk/zynq/clkc.c index 5c205b60a82a..e05c9e3f1385 100644 --- a/drivers/clk/zynq/clkc.c +++ b/drivers/clk/zynq/clkc.c @@ -124,8 +124,9 @@ static void __init zynq_clk_register_fclk(enum zynq_clk fclk, div0_name = kasprintf(GFP_KERNEL, "%s_div0", clk_name); div1_name = kasprintf(GFP_KERNEL, "%s_div1", clk_name); - clk = clk_register_mux(NULL, mux_name, parents, 4, 0, - fclk_ctrl_reg, 4, 2, 0, fclk_lock); + clk = clk_register_mux(NULL, mux_name, parents, 4, + CLK_SET_RATE_NO_REPARENT, fclk_ctrl_reg, 4, 2, 0, + fclk_lock); clk = clk_register_divider(NULL, div0_name, mux_name, 0, fclk_ctrl_reg, 8, 6, CLK_DIVIDER_ONE_BASED | @@ -167,8 +168,8 @@ static void __init zynq_clk_register_periph_clk(enum zynq_clk clk0, mux_name = kasprintf(GFP_KERNEL, "%s_mux", clk_name0); div_name = kasprintf(GFP_KERNEL, "%s_div", clk_name0); - clk = clk_register_mux(NULL, mux_name, parents, 4, 0, - clk_ctrl, 4, 2, 0, lock); + clk = clk_register_mux(NULL, mux_name, parents, 4, + CLK_SET_RATE_NO_REPARENT, clk_ctrl, 4, 2, 0, lock); clk = clk_register_divider(NULL, div_name, mux_name, 0, clk_ctrl, 8, 6, CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, lock); @@ -235,25 +236,26 @@ static void __init zynq_clk_setup(struct device_node *np) clk = clk_register_zynq_pll("armpll_int", "ps_clk", SLCR_ARMPLL_CTRL, SLCR_PLL_STATUS, 0, &armpll_lock); clks[armpll] = clk_register_mux(NULL, clk_output_name[armpll], - armpll_parents, 2, 0, SLCR_ARMPLL_CTRL, 4, 1, 0, - &armpll_lock); + armpll_parents, 2, CLK_SET_RATE_NO_REPARENT, + SLCR_ARMPLL_CTRL, 4, 1, 0, &armpll_lock); clk = clk_register_zynq_pll("ddrpll_int", "ps_clk", SLCR_DDRPLL_CTRL, SLCR_PLL_STATUS, 1, &ddrpll_lock); clks[ddrpll] = clk_register_mux(NULL, clk_output_name[ddrpll], - ddrpll_parents, 2, 0, SLCR_DDRPLL_CTRL, 4, 1, 0, - &ddrpll_lock); + ddrpll_parents, 2, CLK_SET_RATE_NO_REPARENT, + SLCR_DDRPLL_CTRL, 4, 1, 0, &ddrpll_lock); clk = clk_register_zynq_pll("iopll_int", "ps_clk", SLCR_IOPLL_CTRL, SLCR_PLL_STATUS, 2, &iopll_lock); clks[iopll] = clk_register_mux(NULL, clk_output_name[iopll], - iopll_parents, 2, 0, SLCR_IOPLL_CTRL, 4, 1, 0, - &iopll_lock); + iopll_parents, 2, CLK_SET_RATE_NO_REPARENT, + SLCR_IOPLL_CTRL, 4, 1, 0, &iopll_lock); /* CPU clocks */ tmp = readl(SLCR_621_TRUE) & 1; - clk = clk_register_mux(NULL, "cpu_mux", cpu_parents, 4, 0, - SLCR_ARM_CLK_CTRL, 4, 2, 0, &armclk_lock); + clk = clk_register_mux(NULL, "cpu_mux", cpu_parents, 4, + CLK_SET_RATE_NO_REPARENT, SLCR_ARM_CLK_CTRL, 4, 2, 0, + &armclk_lock); clk = clk_register_divider(NULL, "cpu_div", "cpu_mux", 0, SLCR_ARM_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, &armclk_lock); @@ -292,8 +294,9 @@ static void __init zynq_clk_setup(struct device_node *np) swdt_ext_clk_mux_parents[i + 1] = dummy_nm; } clks[swdt] = clk_register_mux(NULL, clk_output_name[swdt], - swdt_ext_clk_mux_parents, 2, CLK_SET_RATE_PARENT, - SLCR_SWDT_CLK_SEL, 0, 1, 0, &gem0clk_lock); + swdt_ext_clk_mux_parents, 2, CLK_SET_RATE_PARENT | + CLK_SET_RATE_NO_REPARENT, SLCR_SWDT_CLK_SEL, 0, 1, 0, + &gem0clk_lock); /* DDR clocks */ clk = clk_register_divider(NULL, "ddr2x_div", "ddrpll", 0, @@ -355,8 +358,9 @@ static void __init zynq_clk_setup(struct device_node *np) gem0_mux_parents[i + 1] = of_clk_get_parent_name(np, idx); } - clk = clk_register_mux(NULL, "gem0_mux", periph_parents, 4, 0, - SLCR_GEM0_CLK_CTRL, 4, 2, 0, &gem0clk_lock); + clk = clk_register_mux(NULL, "gem0_mux", periph_parents, 4, + CLK_SET_RATE_NO_REPARENT, SLCR_GEM0_CLK_CTRL, 4, 2, 0, + &gem0clk_lock); clk = clk_register_divider(NULL, "gem0_div0", "gem0_mux", 0, SLCR_GEM0_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, &gem0clk_lock); @@ -364,8 +368,9 @@ static void __init zynq_clk_setup(struct device_node *np) CLK_SET_RATE_PARENT, SLCR_GEM0_CLK_CTRL, 20, 6, CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, &gem0clk_lock); - clk = clk_register_mux(NULL, "gem0_emio_mux", gem0_mux_parents, 2, 0, - SLCR_GEM0_CLK_CTRL, 6, 1, 0, &gem0clk_lock); + clk = clk_register_mux(NULL, "gem0_emio_mux", gem0_mux_parents, 2, + CLK_SET_RATE_NO_REPARENT, SLCR_GEM0_CLK_CTRL, 6, 1, 0, + &gem0clk_lock); clks[gem0] = clk_register_gate(NULL, clk_output_name[gem0], "gem0_emio_mux", CLK_SET_RATE_PARENT, SLCR_GEM0_CLK_CTRL, 0, 0, &gem0clk_lock); @@ -377,8 +382,9 @@ static void __init zynq_clk_setup(struct device_node *np) gem1_mux_parents[i + 1] = of_clk_get_parent_name(np, idx); } - clk = clk_register_mux(NULL, "gem1_mux", periph_parents, 4, 0, - SLCR_GEM1_CLK_CTRL, 4, 2, 0, &gem1clk_lock); + clk = clk_register_mux(NULL, "gem1_mux", periph_parents, 4, + CLK_SET_RATE_NO_REPARENT, SLCR_GEM1_CLK_CTRL, 4, 2, 0, + &gem1clk_lock); clk = clk_register_divider(NULL, "gem1_div0", "gem1_mux", 0, SLCR_GEM1_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, &gem1clk_lock); @@ -386,8 +392,9 @@ static void __init zynq_clk_setup(struct device_node *np) CLK_SET_RATE_PARENT, SLCR_GEM1_CLK_CTRL, 20, 6, CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, &gem1clk_lock); - clk = clk_register_mux(NULL, "gem1_emio_mux", gem1_mux_parents, 2, 0, - SLCR_GEM1_CLK_CTRL, 6, 1, 0, &gem1clk_lock); + clk = clk_register_mux(NULL, "gem1_emio_mux", gem1_mux_parents, 2, + CLK_SET_RATE_NO_REPARENT, SLCR_GEM1_CLK_CTRL, 6, 1, 0, + &gem1clk_lock); clks[gem1] = clk_register_gate(NULL, clk_output_name[gem1], "gem1_emio_mux", CLK_SET_RATE_PARENT, SLCR_GEM1_CLK_CTRL, 0, 0, &gem1clk_lock); @@ -406,8 +413,9 @@ static void __init zynq_clk_setup(struct device_node *np) can_mio_mux_parents[i] = dummy_nm; } kfree(clk_name); - clk = clk_register_mux(NULL, "can_mux", periph_parents, 4, 0, - SLCR_CAN_CLK_CTRL, 4, 2, 0, &canclk_lock); + clk = clk_register_mux(NULL, "can_mux", periph_parents, 4, + CLK_SET_RATE_NO_REPARENT, SLCR_CAN_CLK_CTRL, 4, 2, 0, + &canclk_lock); clk = clk_register_divider(NULL, "can_div0", "can_mux", 0, SLCR_CAN_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, &canclk_lock); @@ -422,17 +430,21 @@ static void __init zynq_clk_setup(struct device_node *np) CLK_SET_RATE_PARENT, SLCR_CAN_CLK_CTRL, 1, 0, &canclk_lock); clk = clk_register_mux(NULL, "can0_mio_mux", - can_mio_mux_parents, 54, CLK_SET_RATE_PARENT, - SLCR_CAN_MIOCLK_CTRL, 0, 6, 0, &canmioclk_lock); + can_mio_mux_parents, 54, CLK_SET_RATE_PARENT | + CLK_SET_RATE_NO_REPARENT, SLCR_CAN_MIOCLK_CTRL, 0, 6, 0, + &canmioclk_lock); clk = clk_register_mux(NULL, "can1_mio_mux", - can_mio_mux_parents, 54, CLK_SET_RATE_PARENT, - SLCR_CAN_MIOCLK_CTRL, 16, 6, 0, &canmioclk_lock); + can_mio_mux_parents, 54, CLK_SET_RATE_PARENT | + CLK_SET_RATE_NO_REPARENT, SLCR_CAN_MIOCLK_CTRL, 16, 6, + 0, &canmioclk_lock); clks[can0] = clk_register_mux(NULL, clk_output_name[can0], - can0_mio_mux2_parents, 2, CLK_SET_RATE_PARENT, - SLCR_CAN_MIOCLK_CTRL, 6, 1, 0, &canmioclk_lock); + can0_mio_mux2_parents, 2, CLK_SET_RATE_PARENT | + CLK_SET_RATE_NO_REPARENT, SLCR_CAN_MIOCLK_CTRL, 6, 1, 0, + &canmioclk_lock); clks[can1] = clk_register_mux(NULL, clk_output_name[can1], - can1_mio_mux2_parents, 2, CLK_SET_RATE_PARENT, - SLCR_CAN_MIOCLK_CTRL, 22, 1, 0, &canmioclk_lock); + can1_mio_mux2_parents, 2, CLK_SET_RATE_PARENT | + CLK_SET_RATE_NO_REPARENT, SLCR_CAN_MIOCLK_CTRL, 22, 1, + 0, &canmioclk_lock); for (i = 0; i < ARRAY_SIZE(dbgtrc_emio_input_names); i++) { int idx = of_property_match_string(np, "clock-names", @@ -441,13 +453,15 @@ static void __init zynq_clk_setup(struct device_node *np) dbg_emio_mux_parents[i + 1] = of_clk_get_parent_name(np, idx); } - clk = clk_register_mux(NULL, "dbg_mux", periph_parents, 4, 0, - SLCR_DBG_CLK_CTRL, 4, 2, 0, &dbgclk_lock); + clk = clk_register_mux(NULL, "dbg_mux", periph_parents, 4, + CLK_SET_RATE_NO_REPARENT, SLCR_DBG_CLK_CTRL, 4, 2, 0, + &dbgclk_lock); clk = clk_register_divider(NULL, "dbg_div", "dbg_mux", 0, SLCR_DBG_CLK_CTRL, 8, 6, CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, &dbgclk_lock); - clk = clk_register_mux(NULL, "dbg_emio_mux", dbg_emio_mux_parents, 2, 0, - SLCR_DBG_CLK_CTRL, 6, 1, 0, &dbgclk_lock); + clk = clk_register_mux(NULL, "dbg_emio_mux", dbg_emio_mux_parents, 2, + CLK_SET_RATE_NO_REPARENT, SLCR_DBG_CLK_CTRL, 6, 1, 0, + &dbgclk_lock); clks[dbg_trc] = clk_register_gate(NULL, clk_output_name[dbg_trc], "dbg_emio_mux", CLK_SET_RATE_PARENT, SLCR_DBG_CLK_CTRL, 0, 0, &dbgclk_lock); -- cgit v1.2.3 From 14924ba288921c536a72e71baeb14322ece44b39 Mon Sep 17 00:00:00 2001 From: Soren Brinkmann Date: Fri, 19 Jul 2013 10:16:44 -0700 Subject: clk/zynq/pll: Fix documentation for PLL register function Signed-off-by: Soren Brinkmann Signed-off-by: Michal Simek --- drivers/clk/zynq/pll.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers/clk/zynq') diff --git a/drivers/clk/zynq/pll.c b/drivers/clk/zynq/pll.c index 47e307c25a7b..6daa7b6702ed 100644 --- a/drivers/clk/zynq/pll.c +++ b/drivers/clk/zynq/pll.c @@ -182,7 +182,13 @@ static const struct clk_ops zynq_pll_ops = { /** * clk_register_zynq_pll() - Register PLL with the clock framework - * @np Pointer to the DT device node + * @name PLL name + * @parent Parent clock name + * @pll_ctrl Pointer to PLL control register + * @pll_status Pointer to PLL status register + * @lock_index Bit index to this PLL's lock status bit in @pll_status + * @lock Register lock + * Returns handle to the registered clock. */ struct clk *clk_register_zynq_pll(const char *name, const char *parent, void __iomem *pll_ctrl, void __iomem *pll_status, u8 lock_index, -- cgit v1.2.3 From 353dc6c47d67c83f7cc20334f8deb251674e6864 Mon Sep 17 00:00:00 2001 From: Soren Brinkmann Date: Fri, 19 Jul 2013 10:16:45 -0700 Subject: clk/zynq/pll: Use #defines for fbdiv min/max values Use more descriptive #defines for the minimum and maximum PLL feedback divider. Signed-off-by: Soren Brinkmann Signed-off-by: Michal Simek --- drivers/clk/zynq/pll.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'drivers/clk/zynq') diff --git a/drivers/clk/zynq/pll.c b/drivers/clk/zynq/pll.c index 6daa7b6702ed..3226f54fa595 100644 --- a/drivers/clk/zynq/pll.c +++ b/drivers/clk/zynq/pll.c @@ -50,6 +50,9 @@ struct zynq_pll { #define PLLCTRL_RESET_MASK 1 #define PLLCTRL_RESET_SHIFT 0 +#define PLL_FBDIV_MIN 13 +#define PLL_FBDIV_MAX 66 + /** * zynq_pll_round_rate() - Round a clock frequency * @hw: Handle between common and hardware-specific interfaces @@ -63,10 +66,10 @@ static long zynq_pll_round_rate(struct clk_hw *hw, unsigned long rate, u32 fbdiv; fbdiv = DIV_ROUND_CLOSEST(rate, *prate); - if (fbdiv < 13) - fbdiv = 13; - else if (fbdiv > 66) - fbdiv = 66; + if (fbdiv < PLL_FBDIV_MIN) + fbdiv = PLL_FBDIV_MIN; + else if (fbdiv > PLL_FBDIV_MAX) + fbdiv = PLL_FBDIV_MAX; return *prate * fbdiv; } -- cgit v1.2.3