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 40 struct 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 48 struct 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 58 struct 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 65 struct 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 73 74 static int clk_slow_osc_prepare(struct clk_hw *hw) 75 { 76 struct clk_slow_osc *osc = to_clk_slow_osc(hw); 77 void __iomem *sckcr = osc->sckcr; 78 u32 tmp = readl(sckcr); 79 80 if (tmp & AT91_SCKC_OSC32BYP) 81 return 0; 82 83 writel(tmp | AT91_SCKC_OSC32EN, sckcr); 84 85 usleep_range(osc->startup_usec, osc->startup_usec + 1); 86 87 return 0; 88 } 89 90 static void clk_slow_osc_unprepare(struct clk_hw *hw) 91 { 92 struct clk_slow_osc *osc = to_clk_slow_osc(hw); 93 void __iomem *sckcr = osc->sckcr; 94 u32 tmp = readl(sckcr); 95 96 if (tmp & AT91_SCKC_OSC32BYP) 97 return; 98 99 writel(tmp & ~AT91_SCKC_OSC32EN, sckcr); 100 } 101 102 static int clk_slow_osc_is_prepared(struct clk_hw *hw) 103 { 104 struct clk_slow_osc *osc = to_clk_slow_osc(hw); 105 void __iomem *sckcr = osc->sckcr; 106 u32 tmp = readl(sckcr); 107 108 if (tmp & AT91_SCKC_OSC32BYP) 109 return 1; 110 111 return !!(tmp & AT91_SCKC_OSC32EN); 112 } 113 114 static const struct clk_ops slow_osc_ops = { 115 .prepare = clk_slow_osc_prepare, 116 .unprepare = clk_slow_osc_unprepare, 117 .is_prepared = clk_slow_osc_is_prepared, 118 }; 119 120 static struct clk * __init 121 at91_clk_register_slow_osc(void __iomem *sckcr, 122 const char *name, 123 const char *parent_name, 124 unsigned long startup, 125 bool bypass) 126 { 127 struct clk_slow_osc *osc; 128 struct clk *clk = NULL; 129 struct clk_init_data init; 130 131 if (!sckcr || !name || !parent_name) 132 return ERR_PTR(-EINVAL); 133 134 osc = kzalloc(sizeof(*osc), GFP_KERNEL); 135 if (!osc) 136 return ERR_PTR(-ENOMEM); 137 138 init.name = name; 139 init.ops = &slow_osc_ops; 140 init.parent_names = &parent_name; 141 init.num_parents = 1; 142 init.flags = CLK_IGNORE_UNUSED; 143 144 osc->hw.init = &init; 145 osc->sckcr = sckcr; 146 osc->startup_usec = startup; 147 148 if (bypass) 149 writel((readl(sckcr) & ~AT91_SCKC_OSC32EN) | AT91_SCKC_OSC32BYP, 150 sckcr); 151 152 clk = clk_register(NULL, &osc->hw); 153 if (IS_ERR(clk)) 154 kfree(osc); 155 156 return clk; 157 } 158 159 void __init of_at91sam9x5_clk_slow_osc_setup(struct device_node *np, 160 void __iomem *sckcr) 161 { 162 struct clk *clk; 163 const char *parent_name; 164 const char *name = np->name; 165 u32 startup; 166 bool bypass; 167 168 parent_name = of_clk_get_parent_name(np, 0); 169 of_property_read_string(np, "clock-output-names", &name); 170 of_property_read_u32(np, "atmel,startup-time-usec", &startup); 171 bypass = of_property_read_bool(np, "atmel,osc-bypass"); 172 173 clk = at91_clk_register_slow_osc(sckcr, name, parent_name, startup, 174 bypass); 175 if (IS_ERR(clk)) 176 return; 177 178 of_clk_add_provider(np, of_clk_src_simple_get, clk); 179 } 180 181 static unsigned long clk_slow_rc_osc_recalc_rate(struct clk_hw *hw, 182 unsigned long parent_rate) 183 { 184 struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw); 185 186 return osc->frequency; 187 } 188 189 static unsigned long clk_slow_rc_osc_recalc_accuracy(struct clk_hw *hw, 190 unsigned long parent_acc) 191 { 192 struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw); 193 194 return osc->accuracy; 195 } 196 197 static int clk_slow_rc_osc_prepare(struct clk_hw *hw) 198 { 199 struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw); 200 void __iomem *sckcr = osc->sckcr; 201 202 writel(readl(sckcr) | AT91_SCKC_RCEN, sckcr); 203 204 usleep_range(osc->startup_usec, osc->startup_usec + 1); 205 206 return 0; 207 } 208 209 static void clk_slow_rc_osc_unprepare(struct clk_hw *hw) 210 { 211 struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw); 212 void __iomem *sckcr = osc->sckcr; 213 214 writel(readl(sckcr) & ~AT91_SCKC_RCEN, sckcr); 215 } 216 217 static int clk_slow_rc_osc_is_prepared(struct clk_hw *hw) 218 { 219 struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw); 220 221 return !!(readl(osc->sckcr) & AT91_SCKC_RCEN); 222 } 223 224 static const struct clk_ops slow_rc_osc_ops = { 225 .prepare = clk_slow_rc_osc_prepare, 226 .unprepare = clk_slow_rc_osc_unprepare, 227 .is_prepared = clk_slow_rc_osc_is_prepared, 228 .recalc_rate = clk_slow_rc_osc_recalc_rate, 229 .recalc_accuracy = clk_slow_rc_osc_recalc_accuracy, 230 }; 231 232 static struct clk * __init 233 at91_clk_register_slow_rc_osc(void __iomem *sckcr, 234 const char *name, 235 unsigned long frequency, 236 unsigned long accuracy, 237 unsigned long startup) 238 { 239 struct clk_slow_rc_osc *osc; 240 struct clk *clk = NULL; 241 struct clk_init_data init; 242 243 if (!sckcr || !name) 244 return ERR_PTR(-EINVAL); 245 246 osc = kzalloc(sizeof(*osc), GFP_KERNEL); 247 if (!osc) 248 return ERR_PTR(-ENOMEM); 249 250 init.name = name; 251 init.ops = &slow_rc_osc_ops; 252 init.parent_names = NULL; 253 init.num_parents = 0; 254 init.flags = CLK_IS_ROOT | CLK_IGNORE_UNUSED; 255 256 osc->hw.init = &init; 257 osc->sckcr = sckcr; 258 osc->frequency = frequency; 259 osc->accuracy = accuracy; 260 osc->startup_usec = startup; 261 262 clk = clk_register(NULL, &osc->hw); 263 if (IS_ERR(clk)) 264 kfree(osc); 265 266 return clk; 267 } 268 269 void __init of_at91sam9x5_clk_slow_rc_osc_setup(struct device_node *np, 270 void __iomem *sckcr) 271 { 272 struct clk *clk; 273 u32 frequency = 0; 274 u32 accuracy = 0; 275 u32 startup = 0; 276 const char *name = np->name; 277 278 of_property_read_string(np, "clock-output-names", &name); 279 of_property_read_u32(np, "clock-frequency", &frequency); 280 of_property_read_u32(np, "clock-accuracy", &accuracy); 281 of_property_read_u32(np, "atmel,startup-time-usec", &startup); 282 283 clk = at91_clk_register_slow_rc_osc(sckcr, name, frequency, accuracy, 284 startup); 285 if (IS_ERR(clk)) 286 return; 287 288 of_clk_add_provider(np, of_clk_src_simple_get, clk); 289 } 290 291 static int clk_sam9x5_slow_set_parent(struct clk_hw *hw, u8 index) 292 { 293 struct clk_sam9x5_slow *slowck = to_clk_sam9x5_slow(hw); 294 void __iomem *sckcr = slowck->sckcr; 295 u32 tmp; 296 297 if (index > 1) 298 return -EINVAL; 299 300 tmp = readl(sckcr); 301 302 if ((!index && !(tmp & AT91_SCKC_OSCSEL)) || 303 (index && (tmp & AT91_SCKC_OSCSEL))) 304 return 0; 305 306 if (index) 307 tmp |= AT91_SCKC_OSCSEL; 308 else 309 tmp &= ~AT91_SCKC_OSCSEL; 310 311 writel(tmp, sckcr); 312 313 usleep_range(SLOWCK_SW_TIME_USEC, SLOWCK_SW_TIME_USEC + 1); 314 315 return 0; 316 } 317 318 static u8 clk_sam9x5_slow_get_parent(struct clk_hw *hw) 319 { 320 struct clk_sam9x5_slow *slowck = to_clk_sam9x5_slow(hw); 321 322 return !!(readl(slowck->sckcr) & AT91_SCKC_OSCSEL); 323 } 324 325 static const struct clk_ops sam9x5_slow_ops = { 326 .set_parent = clk_sam9x5_slow_set_parent, 327 .get_parent = clk_sam9x5_slow_get_parent, 328 }; 329 330 static struct clk * __init 331 at91_clk_register_sam9x5_slow(void __iomem *sckcr, 332 const char *name, 333 const char **parent_names, 334 int num_parents) 335 { 336 struct clk_sam9x5_slow *slowck; 337 struct clk *clk = NULL; 338 struct clk_init_data init; 339 340 if (!sckcr || !name || !parent_names || !num_parents) 341 return ERR_PTR(-EINVAL); 342 343 slowck = kzalloc(sizeof(*slowck), GFP_KERNEL); 344 if (!slowck) 345 return ERR_PTR(-ENOMEM); 346 347 init.name = name; 348 init.ops = &sam9x5_slow_ops; 349 init.parent_names = parent_names; 350 init.num_parents = num_parents; 351 init.flags = 0; 352 353 slowck->hw.init = &init; 354 slowck->sckcr = sckcr; 355 slowck->parent = !!(readl(sckcr) & AT91_SCKC_OSCSEL); 356 357 clk = clk_register(NULL, &slowck->hw); 358 if (IS_ERR(clk)) 359 kfree(slowck); 360 361 return clk; 362 } 363 364 void __init of_at91sam9x5_clk_slow_setup(struct device_node *np, 365 void __iomem *sckcr) 366 { 367 struct clk *clk; 368 const char *parent_names[2]; 369 int num_parents; 370 const char *name = np->name; 371 int i; 372 373 num_parents = of_count_phandle_with_args(np, "clocks", "#clock-cells"); 374 if (num_parents <= 0 || num_parents > 2) 375 return; 376 377 for (i = 0; i < num_parents; ++i) { 378 parent_names[i] = of_clk_get_parent_name(np, i); 379 if (!parent_names[i]) 380 return; 381 } 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 437 return clk; 438 } 439 440 void __init of_at91sam9260_clk_slow_setup(struct device_node *np, 441 struct at91_pmc *pmc) 442 { 443 struct clk *clk; 444 const char *parent_names[2]; 445 int num_parents; 446 const char *name = np->name; 447 int i; 448 449 num_parents = of_count_phandle_with_args(np, "clocks", "#clock-cells"); 450 if (num_parents != 2) 451 return; 452 453 for (i = 0; i < num_parents; ++i) { 454 parent_names[i] = of_clk_get_parent_name(np, i); 455 if (!parent_names[i]) 456 return; 457 } 458 459 of_property_read_string(np, "clock-output-names", &name); 460 461 clk = at91_clk_register_sam9260_slow(pmc, name, parent_names, 462 num_parents); 463 if (IS_ERR(clk)) 464 return; 465 466 of_clk_add_provider(np, of_clk_src_simple_get, clk); 467 } 468