diff options
author | Chao Xie <chao.xie@marvell.com> | 2014-10-30 22:13:43 -0400 |
---|---|---|
committer | Michael Turquette <mturquette@linaro.org> | 2014-11-12 19:33:43 -0500 |
commit | 0c4c11f3556b244469af32a7bc13485ecbbc77f9 (patch) | |
tree | fa38971cdee67b4d09178816a3c59f374ced668d | |
parent | 61256133919e76ea51e458c9713a9ee9d9ec4a67 (diff) |
clk: mmp: add init callback for clk-frac
For the clk-frac, we need to make sure that the initial
clock rate is one item of the table.
If it is not, we use the first item in the table by default.
Signed-off-by: Chao Xie <chao.xie@marvell.com>
Acked-by: Haojian Zhuang <haojian.zhuang@gmail.com>
Signed-off-by: Michael Turquette <mturquette@linaro.org>
-rw-r--r-- | drivers/clk/mmp/clk-frac.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/drivers/clk/mmp/clk-frac.c b/drivers/clk/mmp/clk-frac.c index e29d006ab85e..1876d2c94bd3 100644 --- a/drivers/clk/mmp/clk-frac.c +++ b/drivers/clk/mmp/clk-frac.c | |||
@@ -118,10 +118,50 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned long drate, | |||
118 | return 0; | 118 | return 0; |
119 | } | 119 | } |
120 | 120 | ||
121 | void clk_factor_init(struct clk_hw *hw) | ||
122 | { | ||
123 | struct mmp_clk_factor *factor = to_clk_factor(hw); | ||
124 | struct mmp_clk_factor_masks *masks = factor->masks; | ||
125 | u32 val, num, den; | ||
126 | int i; | ||
127 | unsigned long flags = 0; | ||
128 | |||
129 | if (factor->lock) | ||
130 | spin_lock_irqsave(factor->lock, flags); | ||
131 | |||
132 | val = readl(factor->base); | ||
133 | |||
134 | /* calculate numerator */ | ||
135 | num = (val >> masks->num_shift) & masks->num_mask; | ||
136 | |||
137 | /* calculate denominator */ | ||
138 | den = (val >> masks->den_shift) & masks->den_mask; | ||
139 | |||
140 | for (i = 0; i < factor->ftbl_cnt; i++) | ||
141 | if (den == factor->ftbl[i].den && num == factor->ftbl[i].num) | ||
142 | break; | ||
143 | |||
144 | if (i >= factor->ftbl_cnt) { | ||
145 | val &= ~(masks->num_mask << masks->num_shift); | ||
146 | val |= (factor->ftbl[0].num & masks->num_mask) << | ||
147 | masks->num_shift; | ||
148 | |||
149 | val &= ~(masks->den_mask << masks->den_shift); | ||
150 | val |= (factor->ftbl[0].den & masks->den_mask) << | ||
151 | masks->den_shift; | ||
152 | |||
153 | writel(val, factor->base); | ||
154 | } | ||
155 | |||
156 | if (factor->lock) | ||
157 | spin_unlock_irqrestore(factor->lock, flags); | ||
158 | } | ||
159 | |||
121 | static struct clk_ops clk_factor_ops = { | 160 | static struct clk_ops clk_factor_ops = { |
122 | .recalc_rate = clk_factor_recalc_rate, | 161 | .recalc_rate = clk_factor_recalc_rate, |
123 | .round_rate = clk_factor_round_rate, | 162 | .round_rate = clk_factor_round_rate, |
124 | .set_rate = clk_factor_set_rate, | 163 | .set_rate = clk_factor_set_rate, |
164 | .init = clk_factor_init, | ||
125 | }; | 165 | }; |
126 | 166 | ||
127 | struct clk *mmp_clk_register_factor(const char *name, const char *parent_name, | 167 | struct clk *mmp_clk_register_factor(const char *name, const char *parent_name, |