clk-slow.c 11 KB

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