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