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