pmc.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. /*
  2. * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. */
  10. #include <linux/clk-provider.h>
  11. #include <linux/clkdev.h>
  12. #include <linux/clk/at91_pmc.h>
  13. #include <linux/of.h>
  14. #include <linux/mfd/syscon.h>
  15. #include <linux/platform_device.h>
  16. #include <linux/regmap.h>
  17. #include <linux/syscore_ops.h>
  18. #include <asm/proc-fns.h>
  19. #include "pmc.h"
  20. #define PMC_MAX_IDS 128
  21. int of_at91_get_clk_range(struct device_node *np, const char *propname,
  22. struct clk_range *range)
  23. {
  24. u32 min, max;
  25. int ret;
  26. ret = of_property_read_u32_index(np, propname, 0, &min);
  27. if (ret)
  28. return ret;
  29. ret = of_property_read_u32_index(np, propname, 1, &max);
  30. if (ret)
  31. return ret;
  32. if (range) {
  33. range->min = min;
  34. range->max = max;
  35. }
  36. return 0;
  37. }
  38. EXPORT_SYMBOL_GPL(of_at91_get_clk_range);
  39. #ifdef CONFIG_PM
  40. static struct regmap *pmcreg;
  41. static u8 registered_ids[PMC_MAX_IDS];
  42. static struct
  43. {
  44. u32 scsr;
  45. u32 pcsr0;
  46. u32 uckr;
  47. u32 mor;
  48. u32 mcfr;
  49. u32 pllar;
  50. u32 mckr;
  51. u32 usb;
  52. u32 imr;
  53. u32 pcsr1;
  54. u32 pcr[PMC_MAX_IDS];
  55. u32 audio_pll0;
  56. u32 audio_pll1;
  57. } pmc_cache;
  58. void pmc_register_id(u8 id)
  59. {
  60. int i;
  61. for (i = 0; i < PMC_MAX_IDS; i++) {
  62. if (registered_ids[i] == 0) {
  63. registered_ids[i] = id;
  64. break;
  65. }
  66. if (registered_ids[i] == id)
  67. break;
  68. }
  69. }
  70. static int pmc_suspend(void)
  71. {
  72. int i;
  73. regmap_read(pmcreg, AT91_PMC_IMR, &pmc_cache.scsr);
  74. regmap_read(pmcreg, AT91_PMC_PCSR, &pmc_cache.pcsr0);
  75. regmap_read(pmcreg, AT91_CKGR_UCKR, &pmc_cache.uckr);
  76. regmap_read(pmcreg, AT91_CKGR_MOR, &pmc_cache.mor);
  77. regmap_read(pmcreg, AT91_CKGR_MCFR, &pmc_cache.mcfr);
  78. regmap_read(pmcreg, AT91_CKGR_PLLAR, &pmc_cache.pllar);
  79. regmap_read(pmcreg, AT91_PMC_MCKR, &pmc_cache.mckr);
  80. regmap_read(pmcreg, AT91_PMC_USB, &pmc_cache.usb);
  81. regmap_read(pmcreg, AT91_PMC_IMR, &pmc_cache.imr);
  82. regmap_read(pmcreg, AT91_PMC_PCSR1, &pmc_cache.pcsr1);
  83. for (i = 0; registered_ids[i]; i++) {
  84. regmap_write(pmcreg, AT91_PMC_PCR,
  85. (registered_ids[i] & AT91_PMC_PCR_PID_MASK));
  86. regmap_read(pmcreg, AT91_PMC_PCR,
  87. &pmc_cache.pcr[registered_ids[i]]);
  88. }
  89. return 0;
  90. }
  91. static void pmc_resume(void)
  92. {
  93. int i, ret = 0;
  94. u32 tmp;
  95. regmap_read(pmcreg, AT91_PMC_MCKR, &tmp);
  96. if (pmc_cache.mckr != tmp)
  97. pr_warn("MCKR was not configured properly by the firmware\n");
  98. regmap_read(pmcreg, AT91_CKGR_PLLAR, &tmp);
  99. if (pmc_cache.pllar != tmp)
  100. pr_warn("PLLAR was not configured properly by the firmware\n");
  101. regmap_write(pmcreg, AT91_PMC_IMR, pmc_cache.scsr);
  102. regmap_write(pmcreg, AT91_PMC_PCER, pmc_cache.pcsr0);
  103. regmap_write(pmcreg, AT91_CKGR_UCKR, pmc_cache.uckr);
  104. regmap_write(pmcreg, AT91_CKGR_MOR, pmc_cache.mor);
  105. regmap_write(pmcreg, AT91_CKGR_MCFR, pmc_cache.mcfr);
  106. regmap_write(pmcreg, AT91_PMC_USB, pmc_cache.usb);
  107. regmap_write(pmcreg, AT91_PMC_IMR, pmc_cache.imr);
  108. regmap_write(pmcreg, AT91_PMC_PCER1, pmc_cache.pcsr1);
  109. for (i = 0; registered_ids[i]; i++) {
  110. regmap_write(pmcreg, AT91_PMC_PCR,
  111. pmc_cache.pcr[registered_ids[i]] |
  112. AT91_PMC_PCR_CMD);
  113. }
  114. if (pmc_cache.uckr & AT91_PMC_UPLLEN) {
  115. ret = regmap_read_poll_timeout(pmcreg, AT91_PMC_SR, tmp,
  116. !(tmp & AT91_PMC_LOCKU),
  117. 10, 5000);
  118. if (ret)
  119. pr_crit("USB PLL didn't lock when resuming\n");
  120. }
  121. }
  122. static struct syscore_ops pmc_syscore_ops = {
  123. .suspend = pmc_suspend,
  124. .resume = pmc_resume,
  125. };
  126. static const struct of_device_id sama5d2_pmc_dt_ids[] = {
  127. { .compatible = "atmel,sama5d2-pmc" },
  128. { /* sentinel */ }
  129. };
  130. static int __init pmc_register_ops(void)
  131. {
  132. struct device_node *np;
  133. np = of_find_matching_node(NULL, sama5d2_pmc_dt_ids);
  134. pmcreg = syscon_node_to_regmap(np);
  135. if (IS_ERR(pmcreg))
  136. return PTR_ERR(pmcreg);
  137. register_syscore_ops(&pmc_syscore_ops);
  138. return 0;
  139. }
  140. /* This has to happen before arch_initcall because of the tcb_clksrc driver */
  141. postcore_initcall(pmc_register_ops);
  142. #endif