aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChao Xie <chao.xie@marvell.com>2014-10-30 22:13:43 -0400
committerMichael Turquette <mturquette@linaro.org>2014-11-12 19:33:43 -0500
commit0c4c11f3556b244469af32a7bc13485ecbbc77f9 (patch)
treefa38971cdee67b4d09178816a3c59f374ced668d
parent61256133919e76ea51e458c9713a9ee9d9ec4a67 (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.c40
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
121void 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
121static struct clk_ops clk_factor_ops = { 160static 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
127struct clk *mmp_clk_register_factor(const char *name, const char *parent_name, 167struct clk *mmp_clk_register_factor(const char *name, const char *parent_name,