1 /* 2 * Copyright (C) 2015 Atmel Corporation, 3 * Nicolas Ferre <nicolas.ferre@atmel.com> 4 * 5 * Based on clk-programmable & clk-peripheral drivers by Boris BREZILLON. 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 */ 13 14 #include <linux/clk-provider.h> 15 #include <linux/clkdev.h> 16 #include <linux/clk/at91_pmc.h> 17 #include <linux/of.h> 18 #include <linux/mfd/syscon.h> 19 #include <linux/regmap.h> 20 21 #include "pmc.h" 22 23 #define GENERATED_MAX_DIV 255 24 25 #define GCK_INDEX_DT_AUDIO_PLL 5 26 27 struct clk_generated { 28 struct clk_hw hw; 29 struct regmap *regmap; 30 struct clk_range range; 31 spinlock_t *lock; 32 u32 id; 33 u32 gckdiv; 34 u8 parent_id; 35 bool audio_pll_allowed; 36 }; 37 38 #define to_clk_generated(hw) \ 39 container_of(hw, struct clk_generated, hw) 40 41 static int clk_generated_enable(struct clk_hw *hw) 42 { 43 struct clk_generated *gck = to_clk_generated(hw); 44 unsigned long flags; 45 46 pr_debug("GCLK: %s, gckdiv = %d, parent id = %d\n", 47 __func__, gck->gckdiv, gck->parent_id); 48 49 spin_lock_irqsave(gck->lock, flags); 50 regmap_write(gck->regmap, AT91_PMC_PCR, 51 (gck->id & AT91_PMC_PCR_PID_MASK)); 52 regmap_update_bits(gck->regmap, AT91_PMC_PCR, 53 AT91_PMC_PCR_GCKDIV_MASK | AT91_PMC_PCR_GCKCSS_MASK | 54 AT91_PMC_PCR_CMD | AT91_PMC_PCR_GCKEN, 55 AT91_PMC_PCR_GCKCSS(gck->parent_id) | 56 AT91_PMC_PCR_CMD | 57 AT91_PMC_PCR_GCKDIV(gck->gckdiv) | 58 AT91_PMC_PCR_GCKEN); 59 spin_unlock_irqrestore(gck->lock, flags); 60 return 0; 61 } 62 63 static void clk_generated_disable(struct clk_hw *hw) 64 { 65 struct clk_generated *gck = to_clk_generated(hw); 66 unsigned long flags; 67 68 spin_lock_irqsave(gck->lock, flags); 69 regmap_write(gck->regmap, AT91_PMC_PCR, 70 (gck->id & AT91_PMC_PCR_PID_MASK)); 71 regmap_update_bits(gck->regmap, AT91_PMC_PCR, 72 AT91_PMC_PCR_CMD | AT91_PMC_PCR_GCKEN, 73 AT91_PMC_PCR_CMD); 74 spin_unlock_irqrestore(gck->lock, flags); 75 } 76 77 static int clk_generated_is_enabled(struct clk_hw *hw) 78 { 79 struct clk_generated *gck = to_clk_generated(hw); 80 unsigned long flags; 81 unsigned int status; 82 83 spin_lock_irqsave(gck->lock, flags); 84 regmap_write(gck->regmap, AT91_PMC_PCR, 85 (gck->id & AT91_PMC_PCR_PID_MASK)); 86 regmap_read(gck->regmap, AT91_PMC_PCR, &status); 87 spin_unlock_irqrestore(gck->lock, flags); 88 89 return status & AT91_PMC_PCR_GCKEN ? 1 : 0; 90 } 91 92 static unsigned long 93 clk_generated_recalc_rate(struct clk_hw *hw, 94 unsigned long parent_rate) 95 { 96 struct clk_generated *gck = to_clk_generated(hw); 97 98 return DIV_ROUND_CLOSEST(parent_rate, gck->gckdiv + 1); 99 } 100 101 static void clk_generated_best_diff(struct clk_rate_request *req, 102 struct clk_hw *parent, 103 unsigned long parent_rate, u32 div, 104 int *best_diff, long *best_rate) 105 { 106 unsigned long tmp_rate; 107 int tmp_diff; 108 109 if (!div) 110 tmp_rate = parent_rate; 111 else 112 tmp_rate = parent_rate / div; 113 tmp_diff = abs(req->rate - tmp_rate); 114 115 if (*best_diff < 0 || *best_diff > tmp_diff) { 116 *best_rate = tmp_rate; 117 *best_diff = tmp_diff; 118 req->best_parent_rate = parent_rate; 119 req->best_parent_hw = parent; 120 } 121 } 122 123 static int clk_generated_determine_rate(struct clk_hw *hw, 124 struct clk_rate_request *req) 125 { 126 struct clk_generated *gck = to_clk_generated(hw); 127 struct clk_hw *parent = NULL; 128 struct clk_rate_request req_parent = *req; 129 long best_rate = -EINVAL; 130 unsigned long min_rate, parent_rate; 131 int best_diff = -1; 132 int i; 133 u32 div; 134 135 for (i = 0; i < clk_hw_get_num_parents(hw) - 1; i++) { 136 parent = clk_hw_get_parent_by_index(hw, i); 137 if (!parent) 138 continue; 139 140 parent_rate = clk_hw_get_rate(parent); 141 min_rate = DIV_ROUND_CLOSEST(parent_rate, GENERATED_MAX_DIV + 1); 142 if (!parent_rate || 143 (gck->range.max && min_rate > gck->range.max)) 144 continue; 145 146 div = DIV_ROUND_CLOSEST(parent_rate, req->rate); 147 148 clk_generated_best_diff(req, parent, parent_rate, div, 149 &best_diff, &best_rate); 150 151 if (!best_diff) 152 break; 153 } 154 155 /* 156 * The audio_pll rate can be modified, unlike the five others clocks 157 * that should never be altered. 158 * The audio_pll can technically be used by multiple consumers. However, 159 * with the rate locking, the first consumer to enable to clock will be 160 * the one definitely setting the rate of the clock. 161 * Since audio IPs are most likely to request the same rate, we enforce 162 * that the only clks able to modify gck rate are those of audio IPs. 163 */ 164 165 if (!gck->audio_pll_allowed) 166 goto end; 167 168 parent = clk_hw_get_parent_by_index(hw, GCK_INDEX_DT_AUDIO_PLL); 169 if (!parent) 170 goto end; 171 172 for (div = 1; div < GENERATED_MAX_DIV + 2; div++) { 173 req_parent.rate = req->rate * div; 174 __clk_determine_rate(parent, &req_parent); 175 clk_generated_best_diff(req, parent, req_parent.rate, div, 176 &best_diff, &best_rate); 177 178 if (!best_diff) 179 break; 180 } 181 182 end: 183 pr_debug("GCLK: %s, best_rate = %ld, parent clk: %s @ %ld\n", 184 __func__, best_rate, 185 __clk_get_name((req->best_parent_hw)->clk), 186 req->best_parent_rate); 187 188 if (best_rate < 0) 189 return best_rate; 190 191 req->rate = best_rate; 192 return 0; 193 } 194 195 /* No modification of hardware as we have the flag CLK_SET_PARENT_GATE set */ 196 static int clk_generated_set_parent(struct clk_hw *hw, u8 index) 197 { 198 struct clk_generated *gck = to_clk_generated(hw); 199 200 if (index >= clk_hw_get_num_parents(hw)) 201 return -EINVAL; 202 203 gck->parent_id = index; 204 return 0; 205 } 206 207 static u8 clk_generated_get_parent(struct clk_hw *hw) 208 { 209 struct clk_generated *gck = to_clk_generated(hw); 210 211 return gck->parent_id; 212 } 213 214 /* No modification of hardware as we have the flag CLK_SET_RATE_GATE set */ 215 static int clk_generated_set_rate(struct clk_hw *hw, 216 unsigned long rate, 217 unsigned long parent_rate) 218 { 219 struct clk_generated *gck = to_clk_generated(hw); 220 u32 div; 221 222 if (!rate) 223 return -EINVAL; 224 225 if (gck->range.max && rate > gck->range.max) 226 return -EINVAL; 227 228 div = DIV_ROUND_CLOSEST(parent_rate, rate); 229 if (div > GENERATED_MAX_DIV + 1 || !div) 230 return -EINVAL; 231 232 gck->gckdiv = div - 1; 233 return 0; 234 } 235 236 static const struct clk_ops generated_ops = { 237 .enable = clk_generated_enable, 238 .disable = clk_generated_disable, 239 .is_enabled = clk_generated_is_enabled, 240 .recalc_rate = clk_generated_recalc_rate, 241 .determine_rate = clk_generated_determine_rate, 242 .get_parent = clk_generated_get_parent, 243 .set_parent = clk_generated_set_parent, 244 .set_rate = clk_generated_set_rate, 245 }; 246 247 /** 248 * clk_generated_startup - Initialize a given clock to its default parent and 249 * divisor parameter. 250 * 251 * @gck: Generated clock to set the startup parameters for. 252 * 253 * Take parameters from the hardware and update local clock configuration 254 * accordingly. 255 */ 256 static void clk_generated_startup(struct clk_generated *gck) 257 { 258 u32 tmp; 259 unsigned long flags; 260 261 spin_lock_irqsave(gck->lock, flags); 262 regmap_write(gck->regmap, AT91_PMC_PCR, 263 (gck->id & AT91_PMC_PCR_PID_MASK)); 264 regmap_read(gck->regmap, AT91_PMC_PCR, &tmp); 265 spin_unlock_irqrestore(gck->lock, flags); 266 267 gck->parent_id = (tmp & AT91_PMC_PCR_GCKCSS_MASK) 268 >> AT91_PMC_PCR_GCKCSS_OFFSET; 269 gck->gckdiv = (tmp & AT91_PMC_PCR_GCKDIV_MASK) 270 >> AT91_PMC_PCR_GCKDIV_OFFSET; 271 } 272 273 struct clk_hw * __init 274 at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock, 275 const char *name, const char **parent_names, 276 u8 num_parents, u8 id, bool pll_audio, 277 const struct clk_range *range) 278 { 279 struct clk_generated *gck; 280 struct clk_init_data init; 281 struct clk_hw *hw; 282 int ret; 283 284 gck = kzalloc(sizeof(*gck), GFP_KERNEL); 285 if (!gck) 286 return ERR_PTR(-ENOMEM); 287 288 init.name = name; 289 init.ops = &generated_ops; 290 init.parent_names = parent_names; 291 init.num_parents = num_parents; 292 init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | 293 CLK_SET_RATE_PARENT; 294 295 gck->id = id; 296 gck->hw.init = &init; 297 gck->regmap = regmap; 298 gck->lock = lock; 299 gck->range = *range; 300 gck->audio_pll_allowed = pll_audio; 301 302 clk_generated_startup(gck); 303 hw = &gck->hw; 304 ret = clk_hw_register(NULL, &gck->hw); 305 if (ret) { 306 kfree(gck); 307 hw = ERR_PTR(ret); 308 } else { 309 pmc_register_id(id); 310 } 311 312 return hw; 313 } 314