1 /* 2 * Helper routines for SuperH Clock Pulse Generator blocks (CPG). 3 * 4 * Copyright (C) 2010 Magnus Damm 5 * 6 * This file is subject to the terms and conditions of the GNU General Public 7 * License. See the file "COPYING" in the main directory of this archive 8 * for more details. 9 */ 10 #include <linux/clk.h> 11 #include <linux/compiler.h> 12 #include <linux/slab.h> 13 #include <linux/io.h> 14 #include <linux/sh_clk.h> 15 16 static int sh_clk_mstp32_enable(struct clk *clk) 17 { 18 iowrite32(ioread32(clk->mapped_reg) & ~(1 << clk->enable_bit), 19 clk->mapped_reg); 20 return 0; 21 } 22 23 static void sh_clk_mstp32_disable(struct clk *clk) 24 { 25 iowrite32(ioread32(clk->mapped_reg) | (1 << clk->enable_bit), 26 clk->mapped_reg); 27 } 28 29 static struct clk_ops sh_clk_mstp32_clk_ops = { 30 .enable = sh_clk_mstp32_enable, 31 .disable = sh_clk_mstp32_disable, 32 .recalc = followparent_recalc, 33 }; 34 35 int __init sh_clk_mstp32_register(struct clk *clks, int nr) 36 { 37 struct clk *clkp; 38 int ret = 0; 39 int k; 40 41 for (k = 0; !ret && (k < nr); k++) { 42 clkp = clks + k; 43 clkp->ops = &sh_clk_mstp32_clk_ops; 44 ret |= clk_register(clkp); 45 } 46 47 return ret; 48 } 49 50 static long sh_clk_div_round_rate(struct clk *clk, unsigned long rate) 51 { 52 return clk_rate_table_round(clk, clk->freq_table, rate); 53 } 54 55 static int sh_clk_div6_divisors[64] = { 56 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 57 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 58 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 59 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64 60 }; 61 62 static struct clk_div_mult_table sh_clk_div6_table = { 63 .divisors = sh_clk_div6_divisors, 64 .nr_divisors = ARRAY_SIZE(sh_clk_div6_divisors), 65 }; 66 67 static unsigned long sh_clk_div6_recalc(struct clk *clk) 68 { 69 struct clk_div_mult_table *table = &sh_clk_div6_table; 70 unsigned int idx; 71 72 clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, 73 table, NULL); 74 75 idx = ioread32(clk->mapped_reg) & 0x003f; 76 77 return clk->freq_table[idx].frequency; 78 } 79 80 static int sh_clk_div6_set_parent(struct clk *clk, struct clk *parent) 81 { 82 struct clk_div_mult_table *table = &sh_clk_div6_table; 83 u32 value; 84 int ret, i; 85 86 if (!clk->parent_table || !clk->parent_num) 87 return -EINVAL; 88 89 /* Search the parent */ 90 for (i = 0; i < clk->parent_num; i++) 91 if (clk->parent_table[i] == parent) 92 break; 93 94 if (i == clk->parent_num) 95 return -ENODEV; 96 97 ret = clk_reparent(clk, parent); 98 if (ret < 0) 99 return ret; 100 101 value = ioread32(clk->mapped_reg) & 102 ~(((1 << clk->src_width) - 1) << clk->src_shift); 103 104 iowrite32(value | (i << clk->src_shift), clk->mapped_reg); 105 106 /* Rebuild the frequency table */ 107 clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, 108 table, NULL); 109 110 return 0; 111 } 112 113 static int sh_clk_div6_set_rate(struct clk *clk, unsigned long rate) 114 { 115 unsigned long value; 116 int idx; 117 118 idx = clk_rate_table_find(clk, clk->freq_table, rate); 119 if (idx < 0) 120 return idx; 121 122 value = ioread32(clk->mapped_reg); 123 value &= ~0x3f; 124 value |= idx; 125 iowrite32(value, clk->mapped_reg); 126 return 0; 127 } 128 129 static int sh_clk_div6_enable(struct clk *clk) 130 { 131 unsigned long value; 132 int ret; 133 134 ret = sh_clk_div6_set_rate(clk, clk->rate); 135 if (ret == 0) { 136 value = ioread32(clk->mapped_reg); 137 value &= ~0x100; /* clear stop bit to enable clock */ 138 iowrite32(value, clk->mapped_reg); 139 } 140 return ret; 141 } 142 143 static void sh_clk_div6_disable(struct clk *clk) 144 { 145 unsigned long value; 146 147 value = ioread32(clk->mapped_reg); 148 value |= 0x100; /* stop clock */ 149 value |= 0x3f; /* VDIV bits must be non-zero, overwrite divider */ 150 iowrite32(value, clk->mapped_reg); 151 } 152 153 static struct clk_ops sh_clk_div6_clk_ops = { 154 .recalc = sh_clk_div6_recalc, 155 .round_rate = sh_clk_div_round_rate, 156 .set_rate = sh_clk_div6_set_rate, 157 .enable = sh_clk_div6_enable, 158 .disable = sh_clk_div6_disable, 159 }; 160 161 static struct clk_ops sh_clk_div6_reparent_clk_ops = { 162 .recalc = sh_clk_div6_recalc, 163 .round_rate = sh_clk_div_round_rate, 164 .set_rate = sh_clk_div6_set_rate, 165 .enable = sh_clk_div6_enable, 166 .disable = sh_clk_div6_disable, 167 .set_parent = sh_clk_div6_set_parent, 168 }; 169 170 static int __init sh_clk_init_parent(struct clk *clk) 171 { 172 u32 val; 173 174 if (clk->parent) 175 return 0; 176 177 if (!clk->parent_table || !clk->parent_num) 178 return 0; 179 180 if (!clk->src_width) { 181 pr_err("sh_clk_init_parent: cannot select parent clock\n"); 182 return -EINVAL; 183 } 184 185 val = (ioread32(clk->mapped_reg) >> clk->src_shift); 186 val &= (1 << clk->src_width) - 1; 187 188 if (val >= clk->parent_num) { 189 pr_err("sh_clk_init_parent: parent table size failed\n"); 190 return -EINVAL; 191 } 192 193 clk->parent = clk->parent_table[val]; 194 if (!clk->parent) { 195 pr_err("sh_clk_init_parent: unable to set parent"); 196 return -EINVAL; 197 } 198 199 return 0; 200 } 201 202 static int __init sh_clk_div6_register_ops(struct clk *clks, int nr, 203 struct clk_ops *ops) 204 { 205 struct clk *clkp; 206 void *freq_table; 207 int nr_divs = sh_clk_div6_table.nr_divisors; 208 int freq_table_size = sizeof(struct cpufreq_frequency_table); 209 int ret = 0; 210 int k; 211 212 freq_table_size *= (nr_divs + 1); 213 freq_table = kzalloc(freq_table_size * nr, GFP_KERNEL); 214 if (!freq_table) { 215 pr_err("sh_clk_div6_register: unable to alloc memory\n"); 216 return -ENOMEM; 217 } 218 219 for (k = 0; !ret && (k < nr); k++) { 220 clkp = clks + k; 221 222 clkp->ops = ops; 223 clkp->freq_table = freq_table + (k * freq_table_size); 224 clkp->freq_table[nr_divs].frequency = CPUFREQ_TABLE_END; 225 ret = clk_register(clkp); 226 if (ret < 0) 227 break; 228 229 ret = sh_clk_init_parent(clkp); 230 } 231 232 return ret; 233 } 234 235 int __init sh_clk_div6_register(struct clk *clks, int nr) 236 { 237 return sh_clk_div6_register_ops(clks, nr, &sh_clk_div6_clk_ops); 238 } 239 240 int __init sh_clk_div6_reparent_register(struct clk *clks, int nr) 241 { 242 return sh_clk_div6_register_ops(clks, nr, 243 &sh_clk_div6_reparent_clk_ops); 244 } 245 246 static unsigned long sh_clk_div4_recalc(struct clk *clk) 247 { 248 struct clk_div4_table *d4t = clk->priv; 249 struct clk_div_mult_table *table = d4t->div_mult_table; 250 unsigned int idx; 251 252 clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, 253 table, &clk->arch_flags); 254 255 idx = (ioread32(clk->mapped_reg) >> clk->enable_bit) & 0x000f; 256 257 return clk->freq_table[idx].frequency; 258 } 259 260 static int sh_clk_div4_set_parent(struct clk *clk, struct clk *parent) 261 { 262 struct clk_div4_table *d4t = clk->priv; 263 struct clk_div_mult_table *table = d4t->div_mult_table; 264 u32 value; 265 int ret; 266 267 /* we really need a better way to determine parent index, but for 268 * now assume internal parent comes with CLK_ENABLE_ON_INIT set, 269 * no CLK_ENABLE_ON_INIT means external clock... 270 */ 271 272 if (parent->flags & CLK_ENABLE_ON_INIT) 273 value = ioread32(clk->mapped_reg) & ~(1 << 7); 274 else 275 value = ioread32(clk->mapped_reg) | (1 << 7); 276 277 ret = clk_reparent(clk, parent); 278 if (ret < 0) 279 return ret; 280 281 iowrite32(value, clk->mapped_reg); 282 283 /* Rebiuld the frequency table */ 284 clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, 285 table, &clk->arch_flags); 286 287 return 0; 288 } 289 290 static int sh_clk_div4_set_rate(struct clk *clk, unsigned long rate) 291 { 292 struct clk_div4_table *d4t = clk->priv; 293 unsigned long value; 294 int idx = clk_rate_table_find(clk, clk->freq_table, rate); 295 if (idx < 0) 296 return idx; 297 298 value = ioread32(clk->mapped_reg); 299 value &= ~(0xf << clk->enable_bit); 300 value |= (idx << clk->enable_bit); 301 iowrite32(value, clk->mapped_reg); 302 303 if (d4t->kick) 304 d4t->kick(clk); 305 306 return 0; 307 } 308 309 static int sh_clk_div4_enable(struct clk *clk) 310 { 311 iowrite32(ioread32(clk->mapped_reg) & ~(1 << 8), clk->mapped_reg); 312 return 0; 313 } 314 315 static void sh_clk_div4_disable(struct clk *clk) 316 { 317 iowrite32(ioread32(clk->mapped_reg) | (1 << 8), clk->mapped_reg); 318 } 319 320 static struct clk_ops sh_clk_div4_clk_ops = { 321 .recalc = sh_clk_div4_recalc, 322 .set_rate = sh_clk_div4_set_rate, 323 .round_rate = sh_clk_div_round_rate, 324 }; 325 326 static struct clk_ops sh_clk_div4_enable_clk_ops = { 327 .recalc = sh_clk_div4_recalc, 328 .set_rate = sh_clk_div4_set_rate, 329 .round_rate = sh_clk_div_round_rate, 330 .enable = sh_clk_div4_enable, 331 .disable = sh_clk_div4_disable, 332 }; 333 334 static struct clk_ops sh_clk_div4_reparent_clk_ops = { 335 .recalc = sh_clk_div4_recalc, 336 .set_rate = sh_clk_div4_set_rate, 337 .round_rate = sh_clk_div_round_rate, 338 .enable = sh_clk_div4_enable, 339 .disable = sh_clk_div4_disable, 340 .set_parent = sh_clk_div4_set_parent, 341 }; 342 343 static int __init sh_clk_div4_register_ops(struct clk *clks, int nr, 344 struct clk_div4_table *table, struct clk_ops *ops) 345 { 346 struct clk *clkp; 347 void *freq_table; 348 int nr_divs = table->div_mult_table->nr_divisors; 349 int freq_table_size = sizeof(struct cpufreq_frequency_table); 350 int ret = 0; 351 int k; 352 353 freq_table_size *= (nr_divs + 1); 354 freq_table = kzalloc(freq_table_size * nr, GFP_KERNEL); 355 if (!freq_table) { 356 pr_err("sh_clk_div4_register: unable to alloc memory\n"); 357 return -ENOMEM; 358 } 359 360 for (k = 0; !ret && (k < nr); k++) { 361 clkp = clks + k; 362 363 clkp->ops = ops; 364 clkp->priv = table; 365 366 clkp->freq_table = freq_table + (k * freq_table_size); 367 clkp->freq_table[nr_divs].frequency = CPUFREQ_TABLE_END; 368 369 ret = clk_register(clkp); 370 } 371 372 return ret; 373 } 374 375 int __init sh_clk_div4_register(struct clk *clks, int nr, 376 struct clk_div4_table *table) 377 { 378 return sh_clk_div4_register_ops(clks, nr, table, &sh_clk_div4_clk_ops); 379 } 380 381 int __init sh_clk_div4_enable_register(struct clk *clks, int nr, 382 struct clk_div4_table *table) 383 { 384 return sh_clk_div4_register_ops(clks, nr, table, 385 &sh_clk_div4_enable_clk_ops); 386 } 387 388 int __init sh_clk_div4_reparent_register(struct clk *clks, int nr, 389 struct clk_div4_table *table) 390 { 391 return sh_clk_div4_register_ops(clks, nr, table, 392 &sh_clk_div4_reparent_clk_ops); 393 } 394