1 /* 2 * Copyright (C) 2014 Google, Inc. 3 * 4 * This program is free software; you can redistribute it and/or modify it 5 * under the terms and conditions of the GNU General Public License, 6 * version 2, as published by the Free Software Foundation. 7 */ 8 9 #define pr_fmt(fmt) "%s: " fmt, __func__ 10 11 #include <linux/clk-provider.h> 12 #include <linux/io.h> 13 #include <linux/kernel.h> 14 #include <linux/printk.h> 15 #include <linux/slab.h> 16 17 #include "clk.h" 18 19 #define PLL_STATUS 0x0 20 #define PLL_STATUS_LOCK BIT(0) 21 22 #define PLL_CTRL1 0x4 23 #define PLL_CTRL1_REFDIV_SHIFT 0 24 #define PLL_CTRL1_REFDIV_MASK 0x3f 25 #define PLL_CTRL1_FBDIV_SHIFT 6 26 #define PLL_CTRL1_FBDIV_MASK 0xfff 27 #define PLL_INT_CTRL1_POSTDIV1_SHIFT 18 28 #define PLL_INT_CTRL1_POSTDIV1_MASK 0x7 29 #define PLL_INT_CTRL1_POSTDIV2_SHIFT 21 30 #define PLL_INT_CTRL1_POSTDIV2_MASK 0x7 31 #define PLL_INT_CTRL1_PD BIT(24) 32 #define PLL_INT_CTRL1_DSMPD BIT(25) 33 #define PLL_INT_CTRL1_FOUTPOSTDIVPD BIT(26) 34 #define PLL_INT_CTRL1_FOUTVCOPD BIT(27) 35 36 #define PLL_CTRL2 0x8 37 #define PLL_FRAC_CTRL2_FRAC_SHIFT 0 38 #define PLL_FRAC_CTRL2_FRAC_MASK 0xffffff 39 #define PLL_FRAC_CTRL2_POSTDIV1_SHIFT 24 40 #define PLL_FRAC_CTRL2_POSTDIV1_MASK 0x7 41 #define PLL_FRAC_CTRL2_POSTDIV2_SHIFT 27 42 #define PLL_FRAC_CTRL2_POSTDIV2_MASK 0x7 43 #define PLL_INT_CTRL2_BYPASS BIT(28) 44 45 #define PLL_CTRL3 0xc 46 #define PLL_FRAC_CTRL3_PD BIT(0) 47 #define PLL_FRAC_CTRL3_DACPD BIT(1) 48 #define PLL_FRAC_CTRL3_DSMPD BIT(2) 49 #define PLL_FRAC_CTRL3_FOUTPOSTDIVPD BIT(3) 50 #define PLL_FRAC_CTRL3_FOUT4PHASEPD BIT(4) 51 #define PLL_FRAC_CTRL3_FOUTVCOPD BIT(5) 52 53 #define PLL_CTRL4 0x10 54 #define PLL_FRAC_CTRL4_BYPASS BIT(28) 55 56 #define MIN_PFD 9600000UL 57 #define MIN_VCO_LA 400000000UL 58 #define MAX_VCO_LA 1600000000UL 59 #define MIN_VCO_FRAC_INT 600000000UL 60 #define MAX_VCO_FRAC_INT 1600000000UL 61 #define MIN_VCO_FRAC_FRAC 600000000UL 62 #define MAX_VCO_FRAC_FRAC 2400000000UL 63 #define MIN_OUTPUT_LA 8000000UL 64 #define MAX_OUTPUT_LA 1600000000UL 65 #define MIN_OUTPUT_FRAC 12000000UL 66 #define MAX_OUTPUT_FRAC 1600000000UL 67 68 struct pistachio_clk_pll { 69 struct clk_hw hw; 70 void __iomem *base; 71 struct pistachio_pll_rate_table *rates; 72 unsigned int nr_rates; 73 }; 74 75 static inline u32 pll_readl(struct pistachio_clk_pll *pll, u32 reg) 76 { 77 return readl(pll->base + reg); 78 } 79 80 static inline void pll_writel(struct pistachio_clk_pll *pll, u32 val, u32 reg) 81 { 82 writel(val, pll->base + reg); 83 } 84 85 static inline void pll_lock(struct pistachio_clk_pll *pll) 86 { 87 while (!(pll_readl(pll, PLL_STATUS) & PLL_STATUS_LOCK)) 88 cpu_relax(); 89 } 90 91 static inline u32 do_div_round_closest(u64 dividend, u32 divisor) 92 { 93 dividend += divisor / 2; 94 do_div(dividend, divisor); 95 96 return dividend; 97 } 98 99 static inline struct pistachio_clk_pll *to_pistachio_pll(struct clk_hw *hw) 100 { 101 return container_of(hw, struct pistachio_clk_pll, hw); 102 } 103 104 static struct pistachio_pll_rate_table * 105 pll_get_params(struct pistachio_clk_pll *pll, unsigned long fref, 106 unsigned long fout) 107 { 108 unsigned int i; 109 110 for (i = 0; i < pll->nr_rates; i++) { 111 if (pll->rates[i].fref == fref && pll->rates[i].fout == fout) 112 return &pll->rates[i]; 113 } 114 115 return NULL; 116 } 117 118 static long pll_round_rate(struct clk_hw *hw, unsigned long rate, 119 unsigned long *parent_rate) 120 { 121 struct pistachio_clk_pll *pll = to_pistachio_pll(hw); 122 unsigned int i; 123 124 for (i = 0; i < pll->nr_rates; i++) { 125 if (i > 0 && pll->rates[i].fref == *parent_rate && 126 pll->rates[i].fout <= rate) 127 return pll->rates[i - 1].fout; 128 } 129 130 return pll->rates[0].fout; 131 } 132 133 static int pll_gf40lp_frac_enable(struct clk_hw *hw) 134 { 135 struct pistachio_clk_pll *pll = to_pistachio_pll(hw); 136 u32 val; 137 138 val = pll_readl(pll, PLL_CTRL3); 139 val &= ~(PLL_FRAC_CTRL3_PD | PLL_FRAC_CTRL3_DACPD | 140 PLL_FRAC_CTRL3_DSMPD | PLL_FRAC_CTRL3_FOUTPOSTDIVPD | 141 PLL_FRAC_CTRL3_FOUT4PHASEPD | PLL_FRAC_CTRL3_FOUTVCOPD); 142 pll_writel(pll, val, PLL_CTRL3); 143 144 val = pll_readl(pll, PLL_CTRL4); 145 val &= ~PLL_FRAC_CTRL4_BYPASS; 146 pll_writel(pll, val, PLL_CTRL4); 147 148 pll_lock(pll); 149 150 return 0; 151 } 152 153 static void pll_gf40lp_frac_disable(struct clk_hw *hw) 154 { 155 struct pistachio_clk_pll *pll = to_pistachio_pll(hw); 156 u32 val; 157 158 val = pll_readl(pll, PLL_CTRL3); 159 val |= PLL_FRAC_CTRL3_PD; 160 pll_writel(pll, val, PLL_CTRL3); 161 } 162 163 static int pll_gf40lp_frac_is_enabled(struct clk_hw *hw) 164 { 165 struct pistachio_clk_pll *pll = to_pistachio_pll(hw); 166 167 return !(pll_readl(pll, PLL_CTRL3) & PLL_FRAC_CTRL3_PD); 168 } 169 170 static int pll_gf40lp_frac_set_rate(struct clk_hw *hw, unsigned long rate, 171 unsigned long parent_rate) 172 { 173 struct pistachio_clk_pll *pll = to_pistachio_pll(hw); 174 struct pistachio_pll_rate_table *params; 175 int enabled = pll_gf40lp_frac_is_enabled(hw); 176 u32 val, vco, old_postdiv1, old_postdiv2; 177 const char *name = __clk_get_name(hw->clk); 178 179 if (rate < MIN_OUTPUT_FRAC || rate > MAX_OUTPUT_FRAC) 180 return -EINVAL; 181 182 params = pll_get_params(pll, parent_rate, rate); 183 if (!params || !params->refdiv) 184 return -EINVAL; 185 186 vco = params->fref * params->fbdiv / params->refdiv; 187 if (vco < MIN_VCO_FRAC_FRAC || vco > MAX_VCO_FRAC_FRAC) 188 pr_warn("%s: VCO %u is out of range %lu..%lu\n", name, vco, 189 MIN_VCO_FRAC_FRAC, MAX_VCO_FRAC_FRAC); 190 191 val = params->fref / params->refdiv; 192 if (val < MIN_PFD) 193 pr_warn("%s: PFD %u is too low (min %lu)\n", 194 name, val, MIN_PFD); 195 if (val > vco / 16) 196 pr_warn("%s: PFD %u is too high (max %u)\n", 197 name, val, vco / 16); 198 199 val = pll_readl(pll, PLL_CTRL1); 200 val &= ~((PLL_CTRL1_REFDIV_MASK << PLL_CTRL1_REFDIV_SHIFT) | 201 (PLL_CTRL1_FBDIV_MASK << PLL_CTRL1_FBDIV_SHIFT)); 202 val |= (params->refdiv << PLL_CTRL1_REFDIV_SHIFT) | 203 (params->fbdiv << PLL_CTRL1_FBDIV_SHIFT); 204 pll_writel(pll, val, PLL_CTRL1); 205 206 val = pll_readl(pll, PLL_CTRL2); 207 208 old_postdiv1 = (val >> PLL_FRAC_CTRL2_POSTDIV1_SHIFT) & 209 PLL_FRAC_CTRL2_POSTDIV1_MASK; 210 old_postdiv2 = (val >> PLL_FRAC_CTRL2_POSTDIV2_SHIFT) & 211 PLL_FRAC_CTRL2_POSTDIV2_MASK; 212 if (enabled && 213 (params->postdiv1 != old_postdiv1 || 214 params->postdiv2 != old_postdiv2)) 215 pr_warn("%s: changing postdiv while PLL is enabled\n", name); 216 217 if (params->postdiv2 > params->postdiv1) 218 pr_warn("%s: postdiv2 should not exceed postdiv1\n", name); 219 220 val &= ~((PLL_FRAC_CTRL2_FRAC_MASK << PLL_FRAC_CTRL2_FRAC_SHIFT) | 221 (PLL_FRAC_CTRL2_POSTDIV1_MASK << 222 PLL_FRAC_CTRL2_POSTDIV1_SHIFT) | 223 (PLL_FRAC_CTRL2_POSTDIV2_MASK << 224 PLL_FRAC_CTRL2_POSTDIV2_SHIFT)); 225 val |= (params->frac << PLL_FRAC_CTRL2_FRAC_SHIFT) | 226 (params->postdiv1 << PLL_FRAC_CTRL2_POSTDIV1_SHIFT) | 227 (params->postdiv2 << PLL_FRAC_CTRL2_POSTDIV2_SHIFT); 228 pll_writel(pll, val, PLL_CTRL2); 229 230 if (enabled) 231 pll_lock(pll); 232 233 return 0; 234 } 235 236 static unsigned long pll_gf40lp_frac_recalc_rate(struct clk_hw *hw, 237 unsigned long parent_rate) 238 { 239 struct pistachio_clk_pll *pll = to_pistachio_pll(hw); 240 u32 val, prediv, fbdiv, frac, postdiv1, postdiv2; 241 u64 rate = parent_rate; 242 243 val = pll_readl(pll, PLL_CTRL1); 244 prediv = (val >> PLL_CTRL1_REFDIV_SHIFT) & PLL_CTRL1_REFDIV_MASK; 245 fbdiv = (val >> PLL_CTRL1_FBDIV_SHIFT) & PLL_CTRL1_FBDIV_MASK; 246 247 val = pll_readl(pll, PLL_CTRL2); 248 postdiv1 = (val >> PLL_FRAC_CTRL2_POSTDIV1_SHIFT) & 249 PLL_FRAC_CTRL2_POSTDIV1_MASK; 250 postdiv2 = (val >> PLL_FRAC_CTRL2_POSTDIV2_SHIFT) & 251 PLL_FRAC_CTRL2_POSTDIV2_MASK; 252 frac = (val >> PLL_FRAC_CTRL2_FRAC_SHIFT) & PLL_FRAC_CTRL2_FRAC_MASK; 253 254 rate *= (fbdiv << 24) + frac; 255 rate = do_div_round_closest(rate, (prediv * postdiv1 * postdiv2) << 24); 256 257 return rate; 258 } 259 260 static struct clk_ops pll_gf40lp_frac_ops = { 261 .enable = pll_gf40lp_frac_enable, 262 .disable = pll_gf40lp_frac_disable, 263 .is_enabled = pll_gf40lp_frac_is_enabled, 264 .recalc_rate = pll_gf40lp_frac_recalc_rate, 265 .round_rate = pll_round_rate, 266 .set_rate = pll_gf40lp_frac_set_rate, 267 }; 268 269 static struct clk_ops pll_gf40lp_frac_fixed_ops = { 270 .enable = pll_gf40lp_frac_enable, 271 .disable = pll_gf40lp_frac_disable, 272 .is_enabled = pll_gf40lp_frac_is_enabled, 273 .recalc_rate = pll_gf40lp_frac_recalc_rate, 274 }; 275 276 static int pll_gf40lp_laint_enable(struct clk_hw *hw) 277 { 278 struct pistachio_clk_pll *pll = to_pistachio_pll(hw); 279 u32 val; 280 281 val = pll_readl(pll, PLL_CTRL1); 282 val &= ~(PLL_INT_CTRL1_PD | PLL_INT_CTRL1_DSMPD | 283 PLL_INT_CTRL1_FOUTPOSTDIVPD | PLL_INT_CTRL1_FOUTVCOPD); 284 pll_writel(pll, val, PLL_CTRL1); 285 286 val = pll_readl(pll, PLL_CTRL2); 287 val &= ~PLL_INT_CTRL2_BYPASS; 288 pll_writel(pll, val, PLL_CTRL2); 289 290 pll_lock(pll); 291 292 return 0; 293 } 294 295 static void pll_gf40lp_laint_disable(struct clk_hw *hw) 296 { 297 struct pistachio_clk_pll *pll = to_pistachio_pll(hw); 298 u32 val; 299 300 val = pll_readl(pll, PLL_CTRL1); 301 val |= PLL_INT_CTRL1_PD; 302 pll_writel(pll, val, PLL_CTRL1); 303 } 304 305 static int pll_gf40lp_laint_is_enabled(struct clk_hw *hw) 306 { 307 struct pistachio_clk_pll *pll = to_pistachio_pll(hw); 308 309 return !(pll_readl(pll, PLL_CTRL1) & PLL_INT_CTRL1_PD); 310 } 311 312 static int pll_gf40lp_laint_set_rate(struct clk_hw *hw, unsigned long rate, 313 unsigned long parent_rate) 314 { 315 struct pistachio_clk_pll *pll = to_pistachio_pll(hw); 316 struct pistachio_pll_rate_table *params; 317 int enabled = pll_gf40lp_laint_is_enabled(hw); 318 u32 val, vco, old_postdiv1, old_postdiv2; 319 const char *name = __clk_get_name(hw->clk); 320 321 if (rate < MIN_OUTPUT_LA || rate > MAX_OUTPUT_LA) 322 return -EINVAL; 323 324 params = pll_get_params(pll, parent_rate, rate); 325 if (!params || !params->refdiv) 326 return -EINVAL; 327 328 vco = params->fref * params->fbdiv / params->refdiv; 329 if (vco < MIN_VCO_LA || vco > MAX_VCO_LA) 330 pr_warn("%s: VCO %u is out of range %lu..%lu\n", name, vco, 331 MIN_VCO_LA, MAX_VCO_LA); 332 333 val = params->fref / params->refdiv; 334 if (val < MIN_PFD) 335 pr_warn("%s: PFD %u is too low (min %lu)\n", 336 name, val, MIN_PFD); 337 if (val > vco / 16) 338 pr_warn("%s: PFD %u is too high (max %u)\n", 339 name, val, vco / 16); 340 341 val = pll_readl(pll, PLL_CTRL1); 342 343 old_postdiv1 = (val >> PLL_INT_CTRL1_POSTDIV1_SHIFT) & 344 PLL_INT_CTRL1_POSTDIV1_MASK; 345 old_postdiv2 = (val >> PLL_INT_CTRL1_POSTDIV2_SHIFT) & 346 PLL_INT_CTRL1_POSTDIV2_MASK; 347 if (enabled && 348 (params->postdiv1 != old_postdiv1 || 349 params->postdiv2 != old_postdiv2)) 350 pr_warn("%s: changing postdiv while PLL is enabled\n", name); 351 352 if (params->postdiv2 > params->postdiv1) 353 pr_warn("%s: postdiv2 should not exceed postdiv1\n", name); 354 355 val &= ~((PLL_CTRL1_REFDIV_MASK << PLL_CTRL1_REFDIV_SHIFT) | 356 (PLL_CTRL1_FBDIV_MASK << PLL_CTRL1_FBDIV_SHIFT) | 357 (PLL_INT_CTRL1_POSTDIV1_MASK << PLL_INT_CTRL1_POSTDIV1_SHIFT) | 358 (PLL_INT_CTRL1_POSTDIV2_MASK << PLL_INT_CTRL1_POSTDIV2_SHIFT)); 359 val |= (params->refdiv << PLL_CTRL1_REFDIV_SHIFT) | 360 (params->fbdiv << PLL_CTRL1_FBDIV_SHIFT) | 361 (params->postdiv1 << PLL_INT_CTRL1_POSTDIV1_SHIFT) | 362 (params->postdiv2 << PLL_INT_CTRL1_POSTDIV2_SHIFT); 363 pll_writel(pll, val, PLL_CTRL1); 364 365 if (enabled) 366 pll_lock(pll); 367 368 return 0; 369 } 370 371 static unsigned long pll_gf40lp_laint_recalc_rate(struct clk_hw *hw, 372 unsigned long parent_rate) 373 { 374 struct pistachio_clk_pll *pll = to_pistachio_pll(hw); 375 u32 val, prediv, fbdiv, postdiv1, postdiv2; 376 u64 rate = parent_rate; 377 378 val = pll_readl(pll, PLL_CTRL1); 379 prediv = (val >> PLL_CTRL1_REFDIV_SHIFT) & PLL_CTRL1_REFDIV_MASK; 380 fbdiv = (val >> PLL_CTRL1_FBDIV_SHIFT) & PLL_CTRL1_FBDIV_MASK; 381 postdiv1 = (val >> PLL_INT_CTRL1_POSTDIV1_SHIFT) & 382 PLL_INT_CTRL1_POSTDIV1_MASK; 383 postdiv2 = (val >> PLL_INT_CTRL1_POSTDIV2_SHIFT) & 384 PLL_INT_CTRL1_POSTDIV2_MASK; 385 386 rate *= fbdiv; 387 rate = do_div_round_closest(rate, prediv * postdiv1 * postdiv2); 388 389 return rate; 390 } 391 392 static struct clk_ops pll_gf40lp_laint_ops = { 393 .enable = pll_gf40lp_laint_enable, 394 .disable = pll_gf40lp_laint_disable, 395 .is_enabled = pll_gf40lp_laint_is_enabled, 396 .recalc_rate = pll_gf40lp_laint_recalc_rate, 397 .round_rate = pll_round_rate, 398 .set_rate = pll_gf40lp_laint_set_rate, 399 }; 400 401 static struct clk_ops pll_gf40lp_laint_fixed_ops = { 402 .enable = pll_gf40lp_laint_enable, 403 .disable = pll_gf40lp_laint_disable, 404 .is_enabled = pll_gf40lp_laint_is_enabled, 405 .recalc_rate = pll_gf40lp_laint_recalc_rate, 406 }; 407 408 static struct clk *pll_register(const char *name, const char *parent_name, 409 unsigned long flags, void __iomem *base, 410 enum pistachio_pll_type type, 411 struct pistachio_pll_rate_table *rates, 412 unsigned int nr_rates) 413 { 414 struct pistachio_clk_pll *pll; 415 struct clk_init_data init; 416 struct clk *clk; 417 418 pll = kzalloc(sizeof(*pll), GFP_KERNEL); 419 if (!pll) 420 return ERR_PTR(-ENOMEM); 421 422 init.name = name; 423 init.flags = flags | CLK_GET_RATE_NOCACHE; 424 init.parent_names = &parent_name; 425 init.num_parents = 1; 426 427 switch (type) { 428 case PLL_GF40LP_FRAC: 429 if (rates) 430 init.ops = &pll_gf40lp_frac_ops; 431 else 432 init.ops = &pll_gf40lp_frac_fixed_ops; 433 break; 434 case PLL_GF40LP_LAINT: 435 if (rates) 436 init.ops = &pll_gf40lp_laint_ops; 437 else 438 init.ops = &pll_gf40lp_laint_fixed_ops; 439 break; 440 default: 441 pr_err("Unrecognized PLL type %u\n", type); 442 kfree(pll); 443 return ERR_PTR(-EINVAL); 444 } 445 446 pll->hw.init = &init; 447 pll->base = base; 448 pll->rates = rates; 449 pll->nr_rates = nr_rates; 450 451 clk = clk_register(NULL, &pll->hw); 452 if (IS_ERR(clk)) 453 kfree(pll); 454 455 return clk; 456 } 457 458 void pistachio_clk_register_pll(struct pistachio_clk_provider *p, 459 struct pistachio_pll *pll, 460 unsigned int num) 461 { 462 struct clk *clk; 463 unsigned int i; 464 465 for (i = 0; i < num; i++) { 466 clk = pll_register(pll[i].name, pll[i].parent, 467 0, p->base + pll[i].reg_base, 468 pll[i].type, pll[i].rates, 469 pll[i].nr_rates); 470 p->clk_data.clks[pll[i].id] = clk; 471 } 472 } 473