clk-main.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Main clock support for AT91 architectures.
  4. *
  5. * Copyright (C) 2020 Microchip Technology Inc. and its subsidiaries
  6. *
  7. * Author: Claudiu Beznea <claudiu.beznea@microchip.com>
  8. *
  9. * Based on drivers/clk/at91/clk-main.c from Linux.
  10. */
  11. #include <asm/processor.h>
  12. #include <common.h>
  13. #include <clk-uclass.h>
  14. #include <dm.h>
  15. #include <linux/clk-provider.h>
  16. #include <linux/clk/at91_pmc.h>
  17. #include <linux/delay.h>
  18. #include <linux/io.h>
  19. #include "pmc.h"
  20. #define UBOOT_DM_CLK_AT91_MAIN_RC "at91-main-rc-clk"
  21. #define UBOOT_DM_CLK_AT91_MAIN_OSC "at91-main-osc-clk"
  22. #define UBOOT_DM_CLK_AT91_RM9200_MAIN "at91-rm9200-main-clk"
  23. #define UBOOT_DM_CLK_AT91_SAM9X5_MAIN "at91-sam9x5-main-clk"
  24. #define MOR_KEY_MASK GENMASK(23, 16)
  25. #define USEC_PER_SEC 1000000UL
  26. #define SLOW_CLOCK_FREQ 32768
  27. #define clk_main_parent_select(s) (((s) & \
  28. (AT91_PMC_MOSCEN | \
  29. AT91_PMC_OSCBYPASS)) ? 1 : 0)
  30. struct clk_main_rc {
  31. void __iomem *reg;
  32. struct clk clk;
  33. };
  34. #define to_clk_main_rc(_clk) container_of(_clk, struct clk_main_rc, clk)
  35. struct clk_main_osc {
  36. void __iomem *reg;
  37. struct clk clk;
  38. };
  39. #define to_clk_main_osc(_clk) container_of(_clk, struct clk_main_osc, clk)
  40. struct clk_main {
  41. void __iomem *reg;
  42. const unsigned int *clk_mux_table;
  43. const char * const *parent_names;
  44. unsigned int num_parents;
  45. int type;
  46. struct clk clk;
  47. };
  48. #define to_clk_main(_clk) container_of(_clk, struct clk_main, clk)
  49. static int main_rc_enable(struct clk *clk)
  50. {
  51. struct clk_main_rc *main_rc = to_clk_main_rc(clk);
  52. void __iomem *reg = main_rc->reg;
  53. unsigned int val;
  54. pmc_read(reg, AT91_CKGR_MOR, &val);
  55. if (!(val & AT91_PMC_MOSCRCEN)) {
  56. pmc_update_bits(reg, AT91_CKGR_MOR,
  57. MOR_KEY_MASK | AT91_PMC_MOSCRCEN,
  58. AT91_PMC_KEY | AT91_PMC_MOSCRCEN);
  59. }
  60. pmc_read(reg, AT91_PMC_SR, &val);
  61. while (!(val & AT91_PMC_MOSCRCS)) {
  62. pmc_read(reg, AT91_PMC_SR, &val);
  63. debug("waiting for main rc...\n");
  64. cpu_relax();
  65. }
  66. return 0;
  67. }
  68. static int main_rc_disable(struct clk *clk)
  69. {
  70. struct clk_main_rc *main_rc = to_clk_main_rc(clk);
  71. struct reg *reg = main_rc->reg;
  72. unsigned int val;
  73. pmc_read(reg, AT91_CKGR_MOR, &val);
  74. if (!(val & AT91_PMC_MOSCRCEN))
  75. return 0;
  76. pmc_update_bits(reg, AT91_CKGR_MOR, MOR_KEY_MASK | AT91_PMC_MOSCRCEN,
  77. AT91_PMC_KEY);
  78. return 0;
  79. }
  80. static const struct clk_ops main_rc_clk_ops = {
  81. .enable = main_rc_enable,
  82. .disable = main_rc_disable,
  83. .get_rate = clk_generic_get_rate,
  84. };
  85. struct clk *at91_clk_main_rc(void __iomem *reg, const char *name,
  86. const char *parent_name)
  87. {
  88. struct clk_main_rc *main_rc;
  89. struct clk *clk;
  90. int ret;
  91. if (!reg || !name || !parent_name)
  92. return ERR_PTR(-EINVAL);
  93. main_rc = kzalloc(sizeof(*main_rc), GFP_KERNEL);
  94. if (!main_rc)
  95. return ERR_PTR(-ENOMEM);
  96. main_rc->reg = reg;
  97. clk = &main_rc->clk;
  98. ret = clk_register(clk, UBOOT_DM_CLK_AT91_MAIN_RC, name,
  99. parent_name);
  100. if (ret) {
  101. kfree(main_rc);
  102. clk = ERR_PTR(ret);
  103. }
  104. return clk;
  105. }
  106. U_BOOT_DRIVER(at91_main_rc_clk) = {
  107. .name = UBOOT_DM_CLK_AT91_MAIN_RC,
  108. .id = UCLASS_CLK,
  109. .ops = &main_rc_clk_ops,
  110. .flags = DM_FLAG_PRE_RELOC,
  111. };
  112. static int clk_main_osc_enable(struct clk *clk)
  113. {
  114. struct clk_main_osc *main = to_clk_main_osc(clk);
  115. void __iomem *reg = main->reg;
  116. unsigned int val;
  117. pmc_read(reg, AT91_CKGR_MOR, &val);
  118. val &= ~MOR_KEY_MASK;
  119. if (val & AT91_PMC_OSCBYPASS)
  120. return 0;
  121. if (!(val & AT91_PMC_MOSCEN)) {
  122. val |= AT91_PMC_MOSCEN | AT91_PMC_KEY;
  123. pmc_write(reg, AT91_CKGR_MOR, val);
  124. }
  125. pmc_read(reg, AT91_PMC_SR, &val);
  126. while (!(val & AT91_PMC_MOSCS)) {
  127. pmc_read(reg, AT91_PMC_SR, &val);
  128. debug("waiting for main osc..\n");
  129. cpu_relax();
  130. }
  131. return 0;
  132. }
  133. static int clk_main_osc_disable(struct clk *clk)
  134. {
  135. struct clk_main_osc *main = to_clk_main_osc(clk);
  136. void __iomem *reg = main->reg;
  137. unsigned int val;
  138. pmc_read(reg, AT91_CKGR_MOR, &val);
  139. if (val & AT91_PMC_OSCBYPASS)
  140. return 0;
  141. if (!(val & AT91_PMC_MOSCEN))
  142. return 0;
  143. val &= ~(AT91_PMC_KEY | AT91_PMC_MOSCEN);
  144. pmc_write(reg, AT91_CKGR_MOR, val | AT91_PMC_KEY);
  145. return 0;
  146. }
  147. static const struct clk_ops main_osc_clk_ops = {
  148. .enable = clk_main_osc_enable,
  149. .disable = clk_main_osc_disable,
  150. .get_rate = clk_generic_get_rate,
  151. };
  152. struct clk *at91_clk_main_osc(void __iomem *reg, const char *name,
  153. const char *parent_name, bool bypass)
  154. {
  155. struct clk_main_osc *main;
  156. struct clk *clk;
  157. int ret;
  158. if (!reg || !name || !parent_name)
  159. return ERR_PTR(-EINVAL);
  160. main = kzalloc(sizeof(*main), GFP_KERNEL);
  161. if (!main)
  162. return ERR_PTR(-ENOMEM);
  163. main->reg = reg;
  164. clk = &main->clk;
  165. if (bypass) {
  166. pmc_update_bits(reg, AT91_CKGR_MOR,
  167. MOR_KEY_MASK | AT91_PMC_OSCBYPASS,
  168. AT91_PMC_KEY | AT91_PMC_OSCBYPASS);
  169. }
  170. ret = clk_register(clk, UBOOT_DM_CLK_AT91_MAIN_OSC, name, parent_name);
  171. if (ret) {
  172. kfree(main);
  173. clk = ERR_PTR(ret);
  174. }
  175. return clk;
  176. }
  177. U_BOOT_DRIVER(at91_main_osc_clk) = {
  178. .name = UBOOT_DM_CLK_AT91_MAIN_OSC,
  179. .id = UCLASS_CLK,
  180. .ops = &main_osc_clk_ops,
  181. .flags = DM_FLAG_PRE_RELOC,
  182. };
  183. static int clk_main_probe_frequency(void __iomem *reg)
  184. {
  185. unsigned int cycles = 16;
  186. unsigned int cycle = DIV_ROUND_UP(USEC_PER_SEC, SLOW_CLOCK_FREQ);
  187. unsigned int mcfr;
  188. while (cycles--) {
  189. pmc_read(reg, AT91_CKGR_MCFR, &mcfr);
  190. if (mcfr & AT91_PMC_MAINRDY)
  191. return 0;
  192. udelay(cycle);
  193. }
  194. return -ETIMEDOUT;
  195. }
  196. static int clk_rm9200_main_enable(struct clk *clk)
  197. {
  198. struct clk_main *main = to_clk_main(clk);
  199. return clk_main_probe_frequency(main->reg);
  200. }
  201. static const struct clk_ops rm9200_main_clk_ops = {
  202. .enable = clk_rm9200_main_enable,
  203. };
  204. struct clk *at91_clk_rm9200_main(void __iomem *reg, const char *name,
  205. const char *parent_name)
  206. {
  207. struct clk_main *main;
  208. struct clk *clk;
  209. int ret;
  210. if (!reg || !name || !parent_name)
  211. return ERR_PTR(-EINVAL);
  212. main = kzalloc(sizeof(*main), GFP_KERNEL);
  213. if (!main)
  214. return ERR_PTR(-ENOMEM);
  215. main->reg = reg;
  216. clk = &main->clk;
  217. ret = clk_register(clk, UBOOT_DM_CLK_AT91_RM9200_MAIN, name,
  218. parent_name);
  219. if (ret) {
  220. kfree(main);
  221. clk = ERR_PTR(ret);
  222. }
  223. return clk;
  224. }
  225. U_BOOT_DRIVER(at91_rm9200_main_clk) = {
  226. .name = UBOOT_DM_CLK_AT91_RM9200_MAIN,
  227. .id = UCLASS_CLK,
  228. .ops = &rm9200_main_clk_ops,
  229. .flags = DM_FLAG_PRE_RELOC,
  230. };
  231. static inline bool clk_sam9x5_main_ready(void __iomem *reg)
  232. {
  233. unsigned int val;
  234. pmc_read(reg, AT91_PMC_SR, &val);
  235. return !!(val & AT91_PMC_MOSCSELS);
  236. }
  237. static int clk_sam9x5_main_enable(struct clk *clk)
  238. {
  239. struct clk_main *main = to_clk_main(clk);
  240. void __iomem *reg = main->reg;
  241. while (!clk_sam9x5_main_ready(reg)) {
  242. debug("waiting for main...");
  243. cpu_relax();
  244. }
  245. return clk_main_probe_frequency(reg);
  246. }
  247. static int clk_sam9x5_main_set_parent(struct clk *clk, struct clk *parent)
  248. {
  249. struct clk_main *main = to_clk_main(clk);
  250. void __iomem *reg = main->reg;
  251. unsigned int tmp, index;
  252. index = at91_clk_mux_val_to_index(main->clk_mux_table,
  253. main->num_parents, AT91_CLK_ID_TO_DID(parent->id));
  254. if (index < 0)
  255. return index;
  256. pmc_read(reg, AT91_CKGR_MOR, &tmp);
  257. tmp &= ~MOR_KEY_MASK;
  258. tmp |= AT91_PMC_KEY;
  259. if (index && !(tmp & AT91_PMC_MOSCSEL))
  260. pmc_write(reg, AT91_CKGR_MOR, tmp | AT91_PMC_MOSCSEL);
  261. else if (!index && (tmp & AT91_PMC_MOSCSEL))
  262. pmc_write(reg, AT91_CKGR_MOR, tmp & ~AT91_PMC_MOSCSEL);
  263. while (!clk_sam9x5_main_ready(reg))
  264. cpu_relax();
  265. return 0;
  266. }
  267. static const struct clk_ops sam9x5_main_clk_ops = {
  268. .enable = clk_sam9x5_main_enable,
  269. .set_parent = clk_sam9x5_main_set_parent,
  270. .get_rate = clk_generic_get_rate,
  271. };
  272. struct clk *at91_clk_sam9x5_main(void __iomem *reg, const char *name,
  273. const char * const *parent_names,
  274. int num_parents, const u32 *clk_mux_table,
  275. int type)
  276. {
  277. struct clk *clk = ERR_PTR(-ENOMEM);
  278. struct clk_main *main = NULL;
  279. unsigned int val;
  280. int ret;
  281. if (!reg || !name || !parent_names || !num_parents || !clk_mux_table)
  282. return ERR_PTR(-EINVAL);
  283. main = kzalloc(sizeof(*main), GFP_KERNEL);
  284. if (!main)
  285. return ERR_PTR(-ENOMEM);
  286. main->reg = reg;
  287. main->parent_names = parent_names;
  288. main->num_parents = num_parents;
  289. main->clk_mux_table = clk_mux_table;
  290. main->type = type;
  291. clk = &main->clk;
  292. clk->flags = CLK_GET_RATE_NOCACHE;
  293. pmc_read(reg, AT91_CKGR_MOR, &val);
  294. ret = clk_register(clk, UBOOT_DM_CLK_AT91_SAM9X5_MAIN, name,
  295. main->parent_names[clk_main_parent_select(val)]);
  296. if (ret) {
  297. kfree(main);
  298. clk = ERR_PTR(ret);
  299. }
  300. return clk;
  301. }
  302. U_BOOT_DRIVER(at91_sam9x5_main_clk) = {
  303. .name = UBOOT_DM_CLK_AT91_SAM9X5_MAIN,
  304. .id = UCLASS_CLK,
  305. .ops = &sam9x5_main_clk_ops,
  306. .flags = DM_FLAG_PRE_RELOC,
  307. };