aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter De Schrijver <pdeschrijver@nvidia.com>2018-07-12 07:53:00 -0400
committerStephen Boyd <sboyd@kernel.org>2018-07-25 16:43:34 -0400
commitcb3ac5947afb3bb7e2f89c1b59f61dcf3e115fe1 (patch)
tree7111e58446fef9a299069b9104c9e32a09732a11
parent0cbb61a313979b53d6b2dc838a92f07471440708 (diff)
clk: tegra: Refactor fractional divider calculation
Move this to a separate file so it can be used to calculate the sdmmc clock dividers. Signed-off-by: Peter De-Schrijver <pdeschrijver@nvidia.com> Signed-off-by: Aapo Vienamo <avienamo@nvidia.com> Acked-by: Peter De Schrijver <pdeschrijver@nvidia.com> Acked-by: Jon Hunter <jonathanh@nvidia.com> Signed-off-by: Stephen Boyd <sboyd@kernel.org>
-rw-r--r--drivers/clk/tegra/Makefile1
-rw-r--r--drivers/clk/tegra/clk-divider.c30
-rw-r--r--drivers/clk/tegra/clk-utils.c43
-rw-r--r--drivers/clk/tegra/clk.h3
4 files changed, 52 insertions, 25 deletions
diff --git a/drivers/clk/tegra/Makefile b/drivers/clk/tegra/Makefile
index b71692391bd6..c77d072eb333 100644
--- a/drivers/clk/tegra/Makefile
+++ b/drivers/clk/tegra/Makefile
@@ -24,3 +24,4 @@ obj-$(CONFIG_ARCH_TEGRA_132_SOC) += clk-tegra124.o
24obj-y += cvb.o 24obj-y += cvb.o
25obj-$(CONFIG_ARCH_TEGRA_210_SOC) += clk-tegra210.o 25obj-$(CONFIG_ARCH_TEGRA_210_SOC) += clk-tegra210.o
26obj-$(CONFIG_CLK_TEGRA_BPMP) += clk-bpmp.o 26obj-$(CONFIG_CLK_TEGRA_BPMP) += clk-bpmp.o
27obj-y += clk-utils.o
diff --git a/drivers/clk/tegra/clk-divider.c b/drivers/clk/tegra/clk-divider.c
index 16e0aee14773..8f175ff62f73 100644
--- a/drivers/clk/tegra/clk-divider.c
+++ b/drivers/clk/tegra/clk-divider.c
@@ -32,35 +32,15 @@
32static int get_div(struct tegra_clk_frac_div *divider, unsigned long rate, 32static int get_div(struct tegra_clk_frac_div *divider, unsigned long rate,
33 unsigned long parent_rate) 33 unsigned long parent_rate)
34{ 34{
35 u64 divider_ux1 = parent_rate; 35 int div;
36 u8 flags = divider->flags;
37 int mul;
38
39 if (!rate)
40 return 0;
41
42 mul = get_mul(divider);
43
44 if (!(flags & TEGRA_DIVIDER_INT))
45 divider_ux1 *= mul;
46
47 if (flags & TEGRA_DIVIDER_ROUND_UP)
48 divider_ux1 += rate - 1;
49
50 do_div(divider_ux1, rate);
51
52 if (flags & TEGRA_DIVIDER_INT)
53 divider_ux1 *= mul;
54 36
55 divider_ux1 -= mul; 37 div = div_frac_get(rate, parent_rate, divider->width,
38 divider->frac_width, divider->flags);
56 39
57 if ((s64)divider_ux1 < 0) 40 if (div < 0)
58 return 0; 41 return 0;
59 42
60 if (divider_ux1 > get_max_div(divider)) 43 return div;
61 return get_max_div(divider);
62
63 return divider_ux1;
64} 44}
65 45
66static unsigned long clk_frac_div_recalc_rate(struct clk_hw *hw, 46static unsigned long clk_frac_div_recalc_rate(struct clk_hw *hw,
diff --git a/drivers/clk/tegra/clk-utils.c b/drivers/clk/tegra/clk-utils.c
new file mode 100644
index 000000000000..1a5daae4e501
--- /dev/null
+++ b/drivers/clk/tegra/clk-utils.c
@@ -0,0 +1,43 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
4 */
5
6#include <asm/div64.h>
7
8#include "clk.h"
9
10#define div_mask(w) ((1 << (w)) - 1)
11
12int div_frac_get(unsigned long rate, unsigned parent_rate, u8 width,
13 u8 frac_width, u8 flags)
14{
15 u64 divider_ux1 = parent_rate;
16 int mul;
17
18 if (!rate)
19 return 0;
20
21 mul = 1 << frac_width;
22
23 if (!(flags & TEGRA_DIVIDER_INT))
24 divider_ux1 *= mul;
25
26 if (flags & TEGRA_DIVIDER_ROUND_UP)
27 divider_ux1 += rate - 1;
28
29 do_div(divider_ux1, rate);
30
31 if (flags & TEGRA_DIVIDER_INT)
32 divider_ux1 *= mul;
33
34 if (divider_ux1 < mul)
35 return 0;
36
37 divider_ux1 -= mul;
38
39 if (divider_ux1 > div_mask(width))
40 return div_mask(width);
41
42 return divider_ux1;
43}
diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h
index e3b9c22ad8b2..c733841aa6db 100644
--- a/drivers/clk/tegra/clk.h
+++ b/drivers/clk/tegra/clk.h
@@ -812,6 +812,9 @@ extern tegra_clk_apply_init_table_func tegra_clk_apply_init_table;
812int tegra_pll_wait_for_lock(struct tegra_clk_pll *pll); 812int tegra_pll_wait_for_lock(struct tegra_clk_pll *pll);
813u16 tegra_pll_get_fixed_mdiv(struct clk_hw *hw, unsigned long input_rate); 813u16 tegra_pll_get_fixed_mdiv(struct clk_hw *hw, unsigned long input_rate);
814int tegra_pll_p_div_to_hw(struct tegra_clk_pll *pll, u8 p_div); 814int tegra_pll_p_div_to_hw(struct tegra_clk_pll *pll, u8 p_div);
815int div_frac_get(unsigned long rate, unsigned parent_rate, u8 width,
816 u8 frac_width, u8 flags);
817
815 818
816/* Combined read fence with delay */ 819/* Combined read fence with delay */
817#define fence_udelay(delay, reg) \ 820#define fence_udelay(delay, reg) \