1 /* 2 * drivers/clk/at91/clk-slow.c 3 * 4 * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com> 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 as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 */ 12 13 #include <linux/clk.h> 14 #include <linux/clk-provider.h> 15 #include <linux/clkdev.h> 16 #include <linux/slab.h> 17 #include <linux/clk/at91_pmc.h> 18 #include <linux/delay.h> 19 #include <linux/of.h> 20 #include <linux/of_address.h> 21 #include <linux/of_irq.h> 22 #include <linux/io.h> 23 #include <linux/interrupt.h> 24 #include <linux/irq.h> 25 #include <linux/sched.h> 26 #include <linux/wait.h> 27 28 #include "pmc.h" 29 #include "sckc.h" 30 31 #define SLOW_CLOCK_FREQ 32768 32 #define SLOWCK_SW_CYCLES 5 33 #define SLOWCK_SW_TIME_USEC ((SLOWCK_SW_CYCLES * USEC_PER_SEC) / \ 34 SLOW_CLOCK_FREQ) 35 36 #define AT91_SCKC_CR 0x00 37 #define AT91_SCKC_RCEN (1 << 0) 38 #define AT91_SCKC_OSC32EN (1 << 1) 39 #define AT91_SCKC_OSC32BYP (1 << 2) 40 #define AT91_SCKC_OSCSEL (1 << 3) 41 42 struct clk_slow_osc { 43 struct clk_hw hw; 44 void __iomem *sckcr; 45 unsigned long startup_usec; 46 }; 47 48 #define to_clk_slow_osc(hw) container_of(hw, struct clk_slow_osc, hw) 49 50 struct clk_slow_rc_osc { 51 struct clk_hw hw; 52 void __iomem *sckcr; 53 unsigned long frequency; 54 unsigned long accuracy; 55 unsigned long startup_usec; 56 }; 57 58 #define to_clk_slow_rc_osc(hw) container_of(hw, struct clk_slow_rc_osc, hw) 59 60 struct clk_sam9260_slow { 61 struct clk_hw hw; 62 struct at91_pmc *pmc; 63 }; 64 65 #define to_clk_sam9260_slow(hw) container_of(hw, struct clk_sam9260_slow, hw) 66 67 struct clk_sam9x5_slow { 68 struct clk_hw hw; 69 void __iomem *sckcr; 70 u8 parent; 71 }; 72 73 #define to_clk_sam9x5_slow(hw) container_of(hw, struct clk_sam9x5_slow, hw) 74 75 static struct clk *slow_clk; 76 77 static int clk_slow_osc_prepare(struct clk_hw *hw) 78 { 79 struct clk_slow_osc *osc = to_clk_slow_osc(hw); 80 void __iomem *sckcr = osc->sckcr; 81 u32 tmp = readl(sckcr); 82 83 if (tmp & AT91_SCKC_OSC32BYP) 84 return 0; 85 86 writel(tmp | AT91_SCKC_OSC32EN, sckcr); 87 88 usleep_range(osc->startup_usec, osc->startup_usec + 1); 89 90 return 0; 91 } 92 93 static void clk_slow_osc_unprepare(struct clk_hw *hw) 94 { 95 struct clk_slow_osc *osc = to_clk_slow_osc(hw); 96 void __iomem *sckcr = osc->sckcr; 97 u32 tmp = readl(sckcr); 98 99 if (tmp & AT91_SCKC_OSC32BYP) 100 return; 101 102 writel(tmp & ~AT91_SCKC_OSC32EN, sckcr); 103 } 104 105 static int clk_slow_osc_is_prepared(struct clk_hw *hw) 106 { 107 struct clk_slow_osc *osc = to_clk_slow_osc(hw); 108 void __iomem *sckcr = osc->sckcr; 109 u32 tmp = readl(sckcr); 110 111 if (tmp & AT91_SCKC_OSC32BYP) 112 return 1; 113 114 return !!(tmp & AT91_SCKC_OSC32EN); 115 } 116 117 static const struct clk_ops slow_osc_ops = { 118 .prepare = clk_slow_osc_prepare, 119 .unprepare = clk_slow_osc_unprepare, 120 .is_prepared = clk_slow_osc_is_prepared, 121 }; 122 123 static struct clk * __init 124 at91_clk_register_slow_osc(void __iomem *sckcr, 125 const char *name, 126 const char *parent_name, 127 unsigned long startup, 128 bool bypass) 129 { 130 struct clk_slow_osc *osc; 131 struct clk *clk = NULL; 132 struct clk_init_data init; 133 134 if (!sckcr || !name || !parent_name) 135 return ERR_PTR(-EINVAL); 136 137 osc = kzalloc(sizeof(*osc), GFP_KERNEL); 138 if (!osc) 139 return ERR_PTR(-ENOMEM); 140 141 init.name = name; 142 init.ops = &slow_osc_ops; 143 init.parent_names = &parent_name; 144 init.num_parents = 1; 145 init.flags = CLK_IGNORE_UNUSED; 146 147 osc->hw.init = &init; 148 osc->sckcr = sckcr; 149 osc->startup_usec = startup; 150 151 if (bypass) 152 writel((readl(sckcr) & ~AT91_SCKC_OSC32EN) | AT91_SCKC_OSC32BYP, 153 sckcr); 154 155 clk = clk_register(NULL, &osc->hw); 156 if (IS_ERR(clk)) 157 kfree(osc); 158 159 return clk; 160 } 161 162 void __init of_at91sam9x5_clk_slow_osc_setup(struct device_node *np, 163 void __iomem *sckcr) 164 { 165 struct clk *clk; 166 const char *parent_name; 167 const char *name = np->name; 168 u32 startup; 169 bool bypass; 170 171 parent_name = of_clk_get_parent_name(np, 0); 172 of_property_read_string(np, "clock-output-names", &name); 173 of_property_read_u32(np, "atmel,startup-time-usec", &startup); 174 bypass = of_property_read_bool(np, "atmel,osc-bypass"); 175 176 clk = at91_clk_register_slow_osc(sckcr, name, parent_name, startup, 177 bypass); 178 if (IS_ERR(clk)) 179 return; 180 181 of_clk_add_provider(np, of_clk_src_simple_get, clk); 182 } 183 184 static unsigned long clk_slow_rc_osc_recalc_rate(struct clk_hw *hw, 185 unsigned long parent_rate) 186 { 187 struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw); 188 189 return osc->frequency; 190 } 191 192 static unsigned long clk_slow_rc_osc_recalc_accuracy(struct clk_hw *hw, 193 unsigned long parent_acc) 194 { 195 struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw); 196 197 return osc->accuracy; 198 } 199 200 static int clk_slow_rc_osc_prepare(struct clk_hw *hw) 201 { 202 struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw); 203 void __iomem *sckcr = osc->sckcr; 204 205 writel(readl(sckcr) | AT91_SCKC_RCEN, sckcr); 206 207 usleep_range(osc->startup_usec, osc->startup_usec + 1); 208 209 return 0; 210 } 211 212 static void clk_slow_rc_osc_unprepare(struct clk_hw *hw) 213 { 214 struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw); 215 void __iomem *sckcr = osc->sckcr; 216 217 writel(readl(sckcr) & ~AT91_SCKC_RCEN, sckcr); 218 } 219 220 static int clk_slow_rc_osc_is_prepared(struct clk_hw *hw) 221 { 222 struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw); 223 224 return !!(readl(osc->sckcr) & AT91_SCKC_RCEN); 225 } 226 227 static const struct clk_ops slow_rc_osc_ops = { 228 .prepare = clk_slow_rc_osc_prepare, 229 .unprepare = clk_slow_rc_osc_unprepare, 230 .is_prepared = clk_slow_rc_osc_is_prepared, 231 .recalc_rate = clk_slow_rc_osc_recalc_rate, 232 .recalc_accuracy = clk_slow_rc_osc_recalc_accuracy, 233 }; 234 235 static struct clk * __init 236 at91_clk_register_slow_rc_osc(void __iomem *sckcr, 237 const char *name, 238 unsigned long frequency, 239 unsigned long accuracy, 240 unsigned long startup) 241 { 242 struct clk_slow_rc_osc *osc; 243 struct clk *clk = NULL; 244 struct clk_init_data init; 245 246 if (!sckcr || !name) 247 return ERR_PTR(-EINVAL); 248 249 osc = kzalloc(sizeof(*osc), GFP_KERNEL); 250 if (!osc) 251 return ERR_PTR(-ENOMEM); 252 253 init.name = name; 254 init.ops = &slow_rc_osc_ops; 255 init.parent_names = NULL; 256 init.num_parents = 0; 257 init.flags = CLK_IS_ROOT | CLK_IGNORE_UNUSED; 258 259 osc->hw.init = &init; 260 osc->sckcr = sckcr; 261 osc->frequency = frequency; 262 osc->accuracy = accuracy; 263 osc->startup_usec = startup; 264 265 clk = clk_register(NULL, &osc->hw); 266 if (IS_ERR(clk)) 267 kfree(osc); 268 269 return clk; 270 } 271 272 void __init of_at91sam9x5_clk_slow_rc_osc_setup(struct device_node *np, 273 void __iomem *sckcr) 274 { 275 struct clk *clk; 276 u32 frequency = 0; 277 u32 accuracy = 0; 278 u32 startup = 0; 279 const char *name = np->name; 280 281 of_property_read_string(np, "clock-output-names", &name); 282 of_property_read_u32(np, "clock-frequency", &frequency); 283 of_property_read_u32(np, "clock-accuracy", &accuracy); 284 of_property_read_u32(np, "atmel,startup-time-usec", &startup); 285 286 clk = at91_clk_register_slow_rc_osc(sckcr, name, frequency, accuracy, 287 startup); 288 if (IS_ERR(clk)) 289 return; 290 291 of_clk_add_provider(np, of_clk_src_simple_get, clk); 292 } 293 294 static int clk_sam9x5_slow_set_parent(struct clk_hw *hw, u8 index) 295 { 296 struct clk_sam9x5_slow *slowck = to_clk_sam9x5_slow(hw); 297 void __iomem *sckcr = slowck->sckcr; 298 u32 tmp; 299 300 if (index > 1) 301 return -EINVAL; 302 303 tmp = readl(sckcr); 304 305 if ((!index && !(tmp & AT91_SCKC_OSCSEL)) || 306 (index && (tmp & AT91_SCKC_OSCSEL))) 307 return 0; 308 309 if (index) 310 tmp |= AT91_SCKC_OSCSEL; 311 else 312 tmp &= ~AT91_SCKC_OSCSEL; 313 314 writel(tmp, sckcr); 315 316 usleep_range(SLOWCK_SW_TIME_USEC, SLOWCK_SW_TIME_USEC + 1); 317 318 return 0; 319 } 320 321 static u8 clk_sam9x5_slow_get_parent(struct clk_hw *hw) 322 { 323 struct clk_sam9x5_slow *slowck = to_clk_sam9x5_slow(hw); 324 325 return !!(readl(slowck->sckcr) & AT91_SCKC_OSCSEL); 326 } 327 328 static const struct clk_ops sam9x5_slow_ops = { 329 .set_parent = clk_sam9x5_slow_set_parent, 330 .get_parent = clk_sam9x5_slow_get_parent, 331 }; 332 333 static struct clk * __init 334 at91_clk_register_sam9x5_slow(void __iomem *sckcr, 335 const char *name, 336 const char **parent_names, 337 int num_parents) 338 { 339 struct clk_sam9x5_slow *slowck; 340 struct clk *clk = NULL; 341 struct clk_init_data init; 342 343 if (!sckcr || !name || !parent_names || !num_parents) 344 return ERR_PTR(-EINVAL); 345 346 slowck = kzalloc(sizeof(*slowck), GFP_KERNEL); 347 if (!slowck) 348 return ERR_PTR(-ENOMEM); 349 350 init.name = name; 351 init.ops = &sam9x5_slow_ops; 352 init.parent_names = parent_names; 353 init.num_parents = num_parents; 354 init.flags = 0; 355 356 slowck->hw.init = &init; 357 slowck->sckcr = sckcr; 358 slowck->parent = !!(readl(sckcr) & AT91_SCKC_OSCSEL); 359 360 clk = clk_register(NULL, &slowck->hw); 361 if (IS_ERR(clk)) 362 kfree(slowck); 363 else 364 slow_clk = clk; 365 366 return clk; 367 } 368 369 void __init of_at91sam9x5_clk_slow_setup(struct device_node *np, 370 void __iomem *sckcr) 371 { 372 struct clk *clk; 373 const char *parent_names[2]; 374 int num_parents; 375 const char *name = np->name; 376 377 num_parents = of_clk_get_parent_count(np); 378 if (num_parents <= 0 || num_parents > 2) 379 return; 380 381 of_clk_parent_fill(np, parent_names, num_parents); 382 383 of_property_read_string(np, "clock-output-names", &name); 384 385 clk = at91_clk_register_sam9x5_slow(sckcr, name, parent_names, 386 num_parents); 387 if (IS_ERR(clk)) 388 return; 389 390 of_clk_add_provider(np, of_clk_src_simple_get, clk); 391 } 392 393 static u8 clk_sam9260_slow_get_parent(struct clk_hw *hw) 394 { 395 struct clk_sam9260_slow *slowck = to_clk_sam9260_slow(hw); 396 397 return !!(pmc_read(slowck->pmc, AT91_PMC_SR) & AT91_PMC_OSCSEL); 398 } 399 400 static const struct clk_ops sam9260_slow_ops = { 401 .get_parent = clk_sam9260_slow_get_parent, 402 }; 403 404 static struct clk * __init 405 at91_clk_register_sam9260_slow(struct at91_pmc *pmc, 406 const char *name, 407 const char **parent_names, 408 int num_parents) 409 { 410 struct clk_sam9260_slow *slowck; 411 struct clk *clk = NULL; 412 struct clk_init_data init; 413 414 if (!pmc || !name) 415 return ERR_PTR(-EINVAL); 416 417 if (!parent_names || !num_parents) 418 return ERR_PTR(-EINVAL); 419 420 slowck = kzalloc(sizeof(*slowck), GFP_KERNEL); 421 if (!slowck) 422 return ERR_PTR(-ENOMEM); 423 424 init.name = name; 425 init.ops = &sam9260_slow_ops; 426 init.parent_names = parent_names; 427 init.num_parents = num_parents; 428 init.flags = 0; 429 430 slowck->hw.init = &init; 431 slowck->pmc = pmc; 432 433 clk = clk_register(NULL, &slowck->hw); 434 if (IS_ERR(clk)) 435 kfree(slowck); 436 else 437 slow_clk = clk; 438 439 return clk; 440 } 441 442 void __init of_at91sam9260_clk_slow_setup(struct device_node *np, 443 struct at91_pmc *pmc) 444 { 445 struct clk *clk; 446 const char *parent_names[2]; 447 int num_parents; 448 const char *name = np->name; 449 450 num_parents = of_clk_get_parent_count(np); 451 if (num_parents != 2) 452 return; 453 454 of_clk_parent_fill(np, parent_names, num_parents); 455 456 of_property_read_string(np, "clock-output-names", &name); 457 458 clk = at91_clk_register_sam9260_slow(pmc, name, parent_names, 459 num_parents); 460 if (IS_ERR(clk)) 461 return; 462 463 of_clk_add_provider(np, of_clk_src_simple_get, clk); 464 } 465 466 /* 467 * FIXME: All slow clk users are not properly claiming it (get + prepare + 468 * enable) before using it. 469 * If all users properly claiming this clock decide that they don't need it 470 * anymore (or are removed), it is disabled while faulty users are still 471 * requiring it, and the system hangs. 472 * Prevent this clock from being disabled until all users are properly 473 * requesting it. 474 * Once this is done we should remove this function and the slow_clk variable. 475 */ 476 static int __init of_at91_clk_slow_retain(void) 477 { 478 if (!slow_clk) 479 return 0; 480 481 __clk_get(slow_clk); 482 clk_prepare_enable(slow_clk); 483 484 return 0; 485 } 486 arch_initcall(of_at91_clk_slow_retain); 487