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/sched.h> 25 #include <linux/wait.h> 26 27 #include "pmc.h" 28 #include "sckc.h" 29 30 #define SLOW_CLOCK_FREQ 32768 31 #define SLOWCK_SW_CYCLES 5 32 #define SLOWCK_SW_TIME_USEC ((SLOWCK_SW_CYCLES * USEC_PER_SEC) / \ 33 SLOW_CLOCK_FREQ) 34 35 #define AT91_SCKC_CR 0x00 36 #define AT91_SCKC_RCEN (1 << 0) 37 #define AT91_SCKC_OSC32EN (1 << 1) 38 #define AT91_SCKC_OSC32BYP (1 << 2) 39 #define AT91_SCKC_OSCSEL (1 << 3) 40 41 struct clk_slow_osc { 42 struct clk_hw hw; 43 void __iomem *sckcr; 44 unsigned long startup_usec; 45 }; 46 47 #define to_clk_slow_osc(hw) container_of(hw, struct clk_slow_osc, hw) 48 49 struct clk_slow_rc_osc { 50 struct clk_hw hw; 51 void __iomem *sckcr; 52 unsigned long frequency; 53 unsigned long accuracy; 54 unsigned long startup_usec; 55 }; 56 57 #define to_clk_slow_rc_osc(hw) container_of(hw, struct clk_slow_rc_osc, hw) 58 59 struct clk_sam9260_slow { 60 struct clk_hw hw; 61 struct at91_pmc *pmc; 62 }; 63 64 #define to_clk_sam9260_slow(hw) container_of(hw, struct clk_sam9260_slow, hw) 65 66 struct clk_sam9x5_slow { 67 struct clk_hw hw; 68 void __iomem *sckcr; 69 u8 parent; 70 }; 71 72 #define to_clk_sam9x5_slow(hw) container_of(hw, struct clk_sam9x5_slow, hw) 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 372 num_parents = of_clk_get_parent_count(np); 373 if (num_parents <= 0 || num_parents > 2) 374 return; 375 376 of_clk_parent_fill(np, parent_names, num_parents); 377 378 of_property_read_string(np, "clock-output-names", &name); 379 380 clk = at91_clk_register_sam9x5_slow(sckcr, name, parent_names, 381 num_parents); 382 if (IS_ERR(clk)) 383 return; 384 385 of_clk_add_provider(np, of_clk_src_simple_get, clk); 386 } 387 388 static u8 clk_sam9260_slow_get_parent(struct clk_hw *hw) 389 { 390 struct clk_sam9260_slow *slowck = to_clk_sam9260_slow(hw); 391 392 return !!(pmc_read(slowck->pmc, AT91_PMC_SR) & AT91_PMC_OSCSEL); 393 } 394 395 static const struct clk_ops sam9260_slow_ops = { 396 .get_parent = clk_sam9260_slow_get_parent, 397 }; 398 399 static struct clk * __init 400 at91_clk_register_sam9260_slow(struct at91_pmc *pmc, 401 const char *name, 402 const char **parent_names, 403 int num_parents) 404 { 405 struct clk_sam9260_slow *slowck; 406 struct clk *clk = NULL; 407 struct clk_init_data init; 408 409 if (!pmc || !name) 410 return ERR_PTR(-EINVAL); 411 412 if (!parent_names || !num_parents) 413 return ERR_PTR(-EINVAL); 414 415 slowck = kzalloc(sizeof(*slowck), GFP_KERNEL); 416 if (!slowck) 417 return ERR_PTR(-ENOMEM); 418 419 init.name = name; 420 init.ops = &sam9260_slow_ops; 421 init.parent_names = parent_names; 422 init.num_parents = num_parents; 423 init.flags = 0; 424 425 slowck->hw.init = &init; 426 slowck->pmc = pmc; 427 428 clk = clk_register(NULL, &slowck->hw); 429 if (IS_ERR(clk)) 430 kfree(slowck); 431 432 return clk; 433 } 434 435 void __init of_at91sam9260_clk_slow_setup(struct device_node *np, 436 struct at91_pmc *pmc) 437 { 438 struct clk *clk; 439 const char *parent_names[2]; 440 int num_parents; 441 const char *name = np->name; 442 443 num_parents = of_clk_get_parent_count(np); 444 if (num_parents != 2) 445 return; 446 447 of_clk_parent_fill(np, parent_names, num_parents); 448 449 of_property_read_string(np, "clock-output-names", &name); 450 451 clk = at91_clk_register_sam9260_slow(pmc, name, parent_names, 452 num_parents); 453 if (IS_ERR(clk)) 454 return; 455 456 of_clk_add_provider(np, of_clk_src_simple_get, clk); 457 } 458