1 /* 2 * Helper routines for SuperH Clock Pulse Generator blocks (CPG). 3 * 4 * Copyright (C) 2010 Magnus Damm 5 * Copyright (C) 2010 - 2012 Paul Mundt 6 * 7 * This file is subject to the terms and conditions of the GNU General Public 8 * License. See the file "COPYING" in the main directory of this archive 9 * for more details. 10 */ 11 #include <linux/clk.h> 12 #include <linux/compiler.h> 13 #include <linux/slab.h> 14 #include <linux/io.h> 15 #include <linux/sh_clk.h> 16 17 #define CPG_CKSTP_BIT BIT(8) 18 19 static unsigned int sh_clk_read(struct clk *clk) 20 { 21 if (clk->flags & CLK_ENABLE_REG_8BIT) 22 return ioread8(clk->mapped_reg); 23 else if (clk->flags & CLK_ENABLE_REG_16BIT) 24 return ioread16(clk->mapped_reg); 25 26 return ioread32(clk->mapped_reg); 27 } 28 29 static unsigned int sh_clk_read_status(struct clk *clk) 30 { 31 void __iomem *mapped_status = (phys_addr_t)clk->status_reg - 32 (phys_addr_t)clk->enable_reg + clk->mapped_reg; 33 34 if (clk->flags & CLK_ENABLE_REG_8BIT) 35 return ioread8(mapped_status); 36 else if (clk->flags & CLK_ENABLE_REG_16BIT) 37 return ioread16(mapped_status); 38 39 return ioread32(mapped_status); 40 } 41 42 static void sh_clk_write(int value, struct clk *clk) 43 { 44 if (clk->flags & CLK_ENABLE_REG_8BIT) 45 iowrite8(value, clk->mapped_reg); 46 else if (clk->flags & CLK_ENABLE_REG_16BIT) 47 iowrite16(value, clk->mapped_reg); 48 else 49 iowrite32(value, clk->mapped_reg); 50 } 51 52 static int sh_clk_mstp_enable(struct clk *clk) 53 { 54 sh_clk_write(sh_clk_read(clk) & ~(1 << clk->enable_bit), clk); 55 if (clk->status_reg) { 56 int i; 57 58 for (i = 1000; 59 (sh_clk_read_status(clk) & (1 << clk->enable_bit)) && i; 60 i--) 61 cpu_relax(); 62 if (!i) { 63 pr_err("cpg: failed to enable %p[%d]\n", 64 clk->enable_reg, clk->enable_bit); 65 return -ETIMEDOUT; 66 } 67 } 68 return 0; 69 } 70 71 static void sh_clk_mstp_disable(struct clk *clk) 72 { 73 sh_clk_write(sh_clk_read(clk) | (1 << clk->enable_bit), clk); 74 } 75 76 static struct sh_clk_ops sh_clk_mstp_clk_ops = { 77 .enable = sh_clk_mstp_enable, 78 .disable = sh_clk_mstp_disable, 79 .recalc = followparent_recalc, 80 }; 81 82 int __init sh_clk_mstp_register(struct clk *clks, int nr) 83 { 84 struct clk *clkp; 85 int ret = 0; 86 int k; 87 88 for (k = 0; !ret && (k < nr); k++) { 89 clkp = clks + k; 90 clkp->ops = &sh_clk_mstp_clk_ops; 91 ret |= clk_register(clkp); 92 } 93 94 return ret; 95 } 96 97 /* 98 * Div/mult table lookup helpers 99 */ 100 static inline struct clk_div_table *clk_to_div_table(struct clk *clk) 101 { 102 return clk->priv; 103 } 104 105 static inline struct clk_div_mult_table *clk_to_div_mult_table(struct clk *clk) 106 { 107 return clk_to_div_table(clk)->div_mult_table; 108 } 109 110 /* 111 * Common div ops 112 */ 113 static long sh_clk_div_round_rate(struct clk *clk, unsigned long rate) 114 { 115 return clk_rate_table_round(clk, clk->freq_table, rate); 116 } 117 118 static unsigned long sh_clk_div_recalc(struct clk *clk) 119 { 120 struct clk_div_mult_table *table = clk_to_div_mult_table(clk); 121 unsigned int idx; 122 123 clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, 124 table, clk->arch_flags ? &clk->arch_flags : NULL); 125 126 idx = (sh_clk_read(clk) >> clk->enable_bit) & clk->div_mask; 127 128 return clk->freq_table[idx].frequency; 129 } 130 131 static int sh_clk_div_set_rate(struct clk *clk, unsigned long rate) 132 { 133 struct clk_div_table *dt = clk_to_div_table(clk); 134 unsigned long value; 135 int idx; 136 137 idx = clk_rate_table_find(clk, clk->freq_table, rate); 138 if (idx < 0) 139 return idx; 140 141 value = sh_clk_read(clk); 142 value &= ~(clk->div_mask << clk->enable_bit); 143 value |= (idx << clk->enable_bit); 144 sh_clk_write(value, clk); 145 146 /* XXX: Should use a post-change notifier */ 147 if (dt->kick) 148 dt->kick(clk); 149 150 return 0; 151 } 152 153 static int sh_clk_div_enable(struct clk *clk) 154 { 155 if (clk->div_mask == SH_CLK_DIV6_MSK) { 156 int ret = sh_clk_div_set_rate(clk, clk->rate); 157 if (ret < 0) 158 return ret; 159 } 160 161 sh_clk_write(sh_clk_read(clk) & ~CPG_CKSTP_BIT, clk); 162 return 0; 163 } 164 165 static void sh_clk_div_disable(struct clk *clk) 166 { 167 unsigned int val; 168 169 val = sh_clk_read(clk); 170 val |= CPG_CKSTP_BIT; 171 172 /* 173 * div6 clocks require the divisor field to be non-zero or the 174 * above CKSTP toggle silently fails. Ensure that the divisor 175 * array is reset to its initial state on disable. 176 */ 177 if (clk->flags & CLK_MASK_DIV_ON_DISABLE) 178 val |= clk->div_mask; 179 180 sh_clk_write(val, clk); 181 } 182 183 static struct sh_clk_ops sh_clk_div_clk_ops = { 184 .recalc = sh_clk_div_recalc, 185 .set_rate = sh_clk_div_set_rate, 186 .round_rate = sh_clk_div_round_rate, 187 }; 188 189 static struct sh_clk_ops sh_clk_div_enable_clk_ops = { 190 .recalc = sh_clk_div_recalc, 191 .set_rate = sh_clk_div_set_rate, 192 .round_rate = sh_clk_div_round_rate, 193 .enable = sh_clk_div_enable, 194 .disable = sh_clk_div_disable, 195 }; 196 197 static int __init sh_clk_init_parent(struct clk *clk) 198 { 199 u32 val; 200 201 if (clk->parent) 202 return 0; 203 204 if (!clk->parent_table || !clk->parent_num) 205 return 0; 206 207 if (!clk->src_width) { 208 pr_err("sh_clk_init_parent: cannot select parent clock\n"); 209 return -EINVAL; 210 } 211 212 val = (sh_clk_read(clk) >> clk->src_shift); 213 val &= (1 << clk->src_width) - 1; 214 215 if (val >= clk->parent_num) { 216 pr_err("sh_clk_init_parent: parent table size failed\n"); 217 return -EINVAL; 218 } 219 220 clk_reparent(clk, clk->parent_table[val]); 221 if (!clk->parent) { 222 pr_err("sh_clk_init_parent: unable to set parent"); 223 return -EINVAL; 224 } 225 226 return 0; 227 } 228 229 static int __init sh_clk_div_register_ops(struct clk *clks, int nr, 230 struct clk_div_table *table, struct sh_clk_ops *ops) 231 { 232 struct clk *clkp; 233 void *freq_table; 234 int nr_divs = table->div_mult_table->nr_divisors; 235 int freq_table_size = sizeof(struct cpufreq_frequency_table); 236 int ret = 0; 237 int k; 238 239 freq_table_size *= (nr_divs + 1); 240 freq_table = kcalloc(nr, freq_table_size, GFP_KERNEL); 241 if (!freq_table) { 242 pr_err("%s: unable to alloc memory\n", __func__); 243 return -ENOMEM; 244 } 245 246 for (k = 0; !ret && (k < nr); k++) { 247 clkp = clks + k; 248 249 clkp->ops = ops; 250 clkp->priv = table; 251 252 clkp->freq_table = freq_table + (k * freq_table_size); 253 clkp->freq_table[nr_divs].frequency = CPUFREQ_TABLE_END; 254 255 ret = clk_register(clkp); 256 if (ret == 0) 257 ret = sh_clk_init_parent(clkp); 258 } 259 260 return ret; 261 } 262 263 /* 264 * div6 support 265 */ 266 static int sh_clk_div6_divisors[64] = { 267 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 268 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 269 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 270 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64 271 }; 272 273 static struct clk_div_mult_table div6_div_mult_table = { 274 .divisors = sh_clk_div6_divisors, 275 .nr_divisors = ARRAY_SIZE(sh_clk_div6_divisors), 276 }; 277 278 static struct clk_div_table sh_clk_div6_table = { 279 .div_mult_table = &div6_div_mult_table, 280 }; 281 282 static int sh_clk_div6_set_parent(struct clk *clk, struct clk *parent) 283 { 284 struct clk_div_mult_table *table = clk_to_div_mult_table(clk); 285 u32 value; 286 int ret, i; 287 288 if (!clk->parent_table || !clk->parent_num) 289 return -EINVAL; 290 291 /* Search the parent */ 292 for (i = 0; i < clk->parent_num; i++) 293 if (clk->parent_table[i] == parent) 294 break; 295 296 if (i == clk->parent_num) 297 return -ENODEV; 298 299 ret = clk_reparent(clk, parent); 300 if (ret < 0) 301 return ret; 302 303 value = sh_clk_read(clk) & 304 ~(((1 << clk->src_width) - 1) << clk->src_shift); 305 306 sh_clk_write(value | (i << clk->src_shift), clk); 307 308 /* Rebuild the frequency table */ 309 clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, 310 table, NULL); 311 312 return 0; 313 } 314 315 static struct sh_clk_ops sh_clk_div6_reparent_clk_ops = { 316 .recalc = sh_clk_div_recalc, 317 .round_rate = sh_clk_div_round_rate, 318 .set_rate = sh_clk_div_set_rate, 319 .enable = sh_clk_div_enable, 320 .disable = sh_clk_div_disable, 321 .set_parent = sh_clk_div6_set_parent, 322 }; 323 324 int __init sh_clk_div6_register(struct clk *clks, int nr) 325 { 326 return sh_clk_div_register_ops(clks, nr, &sh_clk_div6_table, 327 &sh_clk_div_enable_clk_ops); 328 } 329 330 int __init sh_clk_div6_reparent_register(struct clk *clks, int nr) 331 { 332 return sh_clk_div_register_ops(clks, nr, &sh_clk_div6_table, 333 &sh_clk_div6_reparent_clk_ops); 334 } 335 336 /* 337 * div4 support 338 */ 339 static int sh_clk_div4_set_parent(struct clk *clk, struct clk *parent) 340 { 341 struct clk_div_mult_table *table = clk_to_div_mult_table(clk); 342 u32 value; 343 int ret; 344 345 /* we really need a better way to determine parent index, but for 346 * now assume internal parent comes with CLK_ENABLE_ON_INIT set, 347 * no CLK_ENABLE_ON_INIT means external clock... 348 */ 349 350 if (parent->flags & CLK_ENABLE_ON_INIT) 351 value = sh_clk_read(clk) & ~(1 << 7); 352 else 353 value = sh_clk_read(clk) | (1 << 7); 354 355 ret = clk_reparent(clk, parent); 356 if (ret < 0) 357 return ret; 358 359 sh_clk_write(value, clk); 360 361 /* Rebiuld the frequency table */ 362 clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, 363 table, &clk->arch_flags); 364 365 return 0; 366 } 367 368 static struct sh_clk_ops sh_clk_div4_reparent_clk_ops = { 369 .recalc = sh_clk_div_recalc, 370 .set_rate = sh_clk_div_set_rate, 371 .round_rate = sh_clk_div_round_rate, 372 .enable = sh_clk_div_enable, 373 .disable = sh_clk_div_disable, 374 .set_parent = sh_clk_div4_set_parent, 375 }; 376 377 int __init sh_clk_div4_register(struct clk *clks, int nr, 378 struct clk_div4_table *table) 379 { 380 return sh_clk_div_register_ops(clks, nr, table, &sh_clk_div_clk_ops); 381 } 382 383 int __init sh_clk_div4_enable_register(struct clk *clks, int nr, 384 struct clk_div4_table *table) 385 { 386 return sh_clk_div_register_ops(clks, nr, table, 387 &sh_clk_div_enable_clk_ops); 388 } 389 390 int __init sh_clk_div4_reparent_register(struct clk *clks, int nr, 391 struct clk_div4_table *table) 392 { 393 return sh_clk_div_register_ops(clks, nr, table, 394 &sh_clk_div4_reparent_clk_ops); 395 } 396 397 /* FSI-DIV */ 398 static unsigned long fsidiv_recalc(struct clk *clk) 399 { 400 u32 value; 401 402 value = __raw_readl(clk->mapping->base); 403 404 value >>= 16; 405 if (value < 2) 406 return clk->parent->rate; 407 408 return clk->parent->rate / value; 409 } 410 411 static long fsidiv_round_rate(struct clk *clk, unsigned long rate) 412 { 413 return clk_rate_div_range_round(clk, 1, 0xffff, rate); 414 } 415 416 static void fsidiv_disable(struct clk *clk) 417 { 418 __raw_writel(0, clk->mapping->base); 419 } 420 421 static int fsidiv_enable(struct clk *clk) 422 { 423 u32 value; 424 425 value = __raw_readl(clk->mapping->base) >> 16; 426 if (value < 2) 427 return 0; 428 429 __raw_writel((value << 16) | 0x3, clk->mapping->base); 430 431 return 0; 432 } 433 434 static int fsidiv_set_rate(struct clk *clk, unsigned long rate) 435 { 436 int idx; 437 438 idx = (clk->parent->rate / rate) & 0xffff; 439 if (idx < 2) 440 __raw_writel(0, clk->mapping->base); 441 else 442 __raw_writel(idx << 16, clk->mapping->base); 443 444 return 0; 445 } 446 447 static struct sh_clk_ops fsidiv_clk_ops = { 448 .recalc = fsidiv_recalc, 449 .round_rate = fsidiv_round_rate, 450 .set_rate = fsidiv_set_rate, 451 .enable = fsidiv_enable, 452 .disable = fsidiv_disable, 453 }; 454 455 int __init sh_clk_fsidiv_register(struct clk *clks, int nr) 456 { 457 struct clk_mapping *map; 458 int i; 459 460 for (i = 0; i < nr; i++) { 461 462 map = kzalloc(sizeof(struct clk_mapping), GFP_KERNEL); 463 if (!map) { 464 pr_err("%s: unable to alloc memory\n", __func__); 465 return -ENOMEM; 466 } 467 468 /* clks[i].enable_reg came from SH_CLK_FSIDIV() */ 469 map->phys = (phys_addr_t)clks[i].enable_reg; 470 map->len = 8; 471 472 clks[i].enable_reg = 0; /* remove .enable_reg */ 473 clks[i].ops = &fsidiv_clk_ops; 474 clks[i].mapping = map; 475 476 clk_register(&clks[i]); 477 } 478 479 return 0; 480 } 481