1 /* 2 * Copyright (C) 2011 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de> 3 * Copyright (C) 2011 Richard Zhao, Linaro <richard.zhao@linaro.org> 4 * Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd <mturquette@linaro.org> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 as 8 * published by the Free Software Foundation. 9 * 10 * Adjustable divider clock implementation 11 */ 12 13 #include <linux/clk-provider.h> 14 #include <linux/module.h> 15 #include <linux/slab.h> 16 #include <linux/io.h> 17 #include <linux/err.h> 18 #include <linux/string.h> 19 20 /* 21 * DOC: basic adjustable divider clock that cannot gate 22 * 23 * Traits of this clock: 24 * prepare - clk_prepare only ensures that parents are prepared 25 * enable - clk_enable only ensures that parents are enabled 26 * rate - rate is adjustable. clk->rate = parent->rate / divisor 27 * parent - fixed parent. No clk_set_parent support 28 */ 29 30 #define to_clk_divider(_hw) container_of(_hw, struct clk_divider, hw) 31 32 #define div_mask(d) ((1 << (d->width)) - 1) 33 34 static unsigned long clk_divider_recalc_rate(struct clk_hw *hw, 35 unsigned long parent_rate) 36 { 37 struct clk_divider *divider = to_clk_divider(hw); 38 unsigned int div; 39 40 div = readl(divider->reg) >> divider->shift; 41 div &= div_mask(divider); 42 43 if (!(divider->flags & CLK_DIVIDER_ONE_BASED)) 44 div++; 45 46 return parent_rate / div; 47 } 48 49 /* 50 * The reverse of DIV_ROUND_UP: The maximum number which 51 * divided by m is r 52 */ 53 #define MULT_ROUND_UP(r, m) ((r) * (m) + (m) - 1) 54 55 static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate, 56 unsigned long *best_parent_rate) 57 { 58 struct clk_divider *divider = to_clk_divider(hw); 59 int i, bestdiv = 0; 60 unsigned long parent_rate, best = 0, now, maxdiv; 61 62 if (!rate) 63 rate = 1; 64 65 maxdiv = (1 << divider->width); 66 67 if (divider->flags & CLK_DIVIDER_ONE_BASED) 68 maxdiv--; 69 70 if (!(__clk_get_flags(hw->clk) & CLK_SET_RATE_PARENT)) { 71 parent_rate = *best_parent_rate; 72 bestdiv = DIV_ROUND_UP(parent_rate, rate); 73 bestdiv = bestdiv == 0 ? 1 : bestdiv; 74 bestdiv = bestdiv > maxdiv ? maxdiv : bestdiv; 75 return bestdiv; 76 } 77 78 /* 79 * The maximum divider we can use without overflowing 80 * unsigned long in rate * i below 81 */ 82 maxdiv = min(ULONG_MAX / rate, maxdiv); 83 84 for (i = 1; i <= maxdiv; i++) { 85 parent_rate = __clk_round_rate(__clk_get_parent(hw->clk), 86 MULT_ROUND_UP(rate, i)); 87 now = parent_rate / i; 88 if (now <= rate && now > best) { 89 bestdiv = i; 90 best = now; 91 *best_parent_rate = parent_rate; 92 } 93 } 94 95 if (!bestdiv) { 96 bestdiv = (1 << divider->width); 97 if (divider->flags & CLK_DIVIDER_ONE_BASED) 98 bestdiv--; 99 *best_parent_rate = __clk_round_rate(__clk_get_parent(hw->clk), 1); 100 } 101 102 return bestdiv; 103 } 104 105 static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate, 106 unsigned long *prate) 107 { 108 int div; 109 div = clk_divider_bestdiv(hw, rate, prate); 110 111 return *prate / div; 112 } 113 114 static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate, 115 unsigned long parent_rate) 116 { 117 struct clk_divider *divider = to_clk_divider(hw); 118 unsigned int div; 119 unsigned long flags = 0; 120 u32 val; 121 122 div = parent_rate / rate; 123 124 if (!(divider->flags & CLK_DIVIDER_ONE_BASED)) 125 div--; 126 127 if (div > div_mask(divider)) 128 div = div_mask(divider); 129 130 if (divider->lock) 131 spin_lock_irqsave(divider->lock, flags); 132 133 val = readl(divider->reg); 134 val &= ~(div_mask(divider) << divider->shift); 135 val |= div << divider->shift; 136 writel(val, divider->reg); 137 138 if (divider->lock) 139 spin_unlock_irqrestore(divider->lock, flags); 140 141 return 0; 142 } 143 144 const struct clk_ops clk_divider_ops = { 145 .recalc_rate = clk_divider_recalc_rate, 146 .round_rate = clk_divider_round_rate, 147 .set_rate = clk_divider_set_rate, 148 }; 149 EXPORT_SYMBOL_GPL(clk_divider_ops); 150 151 /** 152 * clk_register_divider - register a divider clock with the clock framework 153 * @dev: device registering this clock 154 * @name: name of this clock 155 * @parent_name: name of clock's parent 156 * @flags: framework-specific flags 157 * @reg: register address to adjust divider 158 * @shift: number of bits to shift the bitfield 159 * @width: width of the bitfield 160 * @clk_divider_flags: divider-specific flags for this clock 161 * @lock: shared register lock for this clock 162 */ 163 struct clk *clk_register_divider(struct device *dev, const char *name, 164 const char *parent_name, unsigned long flags, 165 void __iomem *reg, u8 shift, u8 width, 166 u8 clk_divider_flags, spinlock_t *lock) 167 { 168 struct clk_divider *div; 169 struct clk *clk; 170 struct clk_init_data init; 171 172 /* allocate the divider */ 173 div = kzalloc(sizeof(struct clk_divider), GFP_KERNEL); 174 if (!div) { 175 pr_err("%s: could not allocate divider clk\n", __func__); 176 return ERR_PTR(-ENOMEM); 177 } 178 179 init.name = name; 180 init.ops = &clk_divider_ops; 181 init.flags = flags; 182 init.parent_names = (parent_name ? &parent_name: NULL); 183 init.num_parents = (parent_name ? 1 : 0); 184 185 /* struct clk_divider assignments */ 186 div->reg = reg; 187 div->shift = shift; 188 div->width = width; 189 div->flags = clk_divider_flags; 190 div->lock = lock; 191 div->hw.init = &init; 192 193 /* register the clock */ 194 clk = clk_register(dev, &div->hw); 195 196 if (IS_ERR(clk)) 197 kfree(div); 198 199 return clk; 200 } 201