clk-utmi.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  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/regmap.h>
  16. #include <soc/at91/atmel-sfr.h>
  17. #include "pmc.h"
  18. /*
  19. * The purpose of this clock is to generate a 480 MHz signal. A different
  20. * rate can't be configured.
  21. */
  22. #define UTMI_RATE 480000000
  23. struct clk_utmi {
  24. struct clk_hw hw;
  25. struct regmap *regmap_pmc;
  26. struct regmap *regmap_sfr;
  27. };
  28. #define to_clk_utmi(hw) container_of(hw, struct clk_utmi, hw)
  29. static inline bool clk_utmi_ready(struct regmap *regmap)
  30. {
  31. unsigned int status;
  32. regmap_read(regmap, AT91_PMC_SR, &status);
  33. return status & AT91_PMC_LOCKU;
  34. }
  35. static int clk_utmi_prepare(struct clk_hw *hw)
  36. {
  37. struct clk_hw *hw_parent;
  38. struct clk_utmi *utmi = to_clk_utmi(hw);
  39. unsigned int uckr = AT91_PMC_UPLLEN | AT91_PMC_UPLLCOUNT |
  40. AT91_PMC_BIASEN;
  41. unsigned int utmi_ref_clk_freq;
  42. unsigned long parent_rate;
  43. /*
  44. * If mainck rate is different from 12 MHz, we have to configure the
  45. * FREQ field of the SFR_UTMICKTRIM register to generate properly
  46. * the utmi clock.
  47. */
  48. hw_parent = clk_hw_get_parent(hw);
  49. parent_rate = clk_hw_get_rate(hw_parent);
  50. switch (parent_rate) {
  51. case 12000000:
  52. utmi_ref_clk_freq = 0;
  53. break;
  54. case 16000000:
  55. utmi_ref_clk_freq = 1;
  56. break;
  57. case 24000000:
  58. utmi_ref_clk_freq = 2;
  59. break;
  60. /*
  61. * Not supported on SAMA5D2 but it's not an issue since MAINCK
  62. * maximum value is 24 MHz.
  63. */
  64. case 48000000:
  65. utmi_ref_clk_freq = 3;
  66. break;
  67. default:
  68. pr_err("UTMICK: unsupported mainck rate\n");
  69. return -EINVAL;
  70. }
  71. if (utmi->regmap_sfr) {
  72. regmap_update_bits(utmi->regmap_sfr, AT91_SFR_UTMICKTRIM,
  73. AT91_UTMICKTRIM_FREQ, utmi_ref_clk_freq);
  74. } else if (utmi_ref_clk_freq) {
  75. pr_err("UTMICK: sfr node required\n");
  76. return -EINVAL;
  77. }
  78. regmap_update_bits(utmi->regmap_pmc, AT91_CKGR_UCKR, uckr, uckr);
  79. while (!clk_utmi_ready(utmi->regmap_pmc))
  80. cpu_relax();
  81. return 0;
  82. }
  83. static int clk_utmi_is_prepared(struct clk_hw *hw)
  84. {
  85. struct clk_utmi *utmi = to_clk_utmi(hw);
  86. return clk_utmi_ready(utmi->regmap_pmc);
  87. }
  88. static void clk_utmi_unprepare(struct clk_hw *hw)
  89. {
  90. struct clk_utmi *utmi = to_clk_utmi(hw);
  91. regmap_update_bits(utmi->regmap_pmc, AT91_CKGR_UCKR,
  92. AT91_PMC_UPLLEN, 0);
  93. }
  94. static unsigned long clk_utmi_recalc_rate(struct clk_hw *hw,
  95. unsigned long parent_rate)
  96. {
  97. /* UTMI clk rate is fixed. */
  98. return UTMI_RATE;
  99. }
  100. static const struct clk_ops utmi_ops = {
  101. .prepare = clk_utmi_prepare,
  102. .unprepare = clk_utmi_unprepare,
  103. .is_prepared = clk_utmi_is_prepared,
  104. .recalc_rate = clk_utmi_recalc_rate,
  105. };
  106. static struct clk_hw * __init
  107. at91_clk_register_utmi(struct regmap *regmap_pmc, struct regmap *regmap_sfr,
  108. const char *name, const char *parent_name)
  109. {
  110. struct clk_utmi *utmi;
  111. struct clk_hw *hw;
  112. struct clk_init_data init;
  113. int ret;
  114. utmi = kzalloc(sizeof(*utmi), GFP_KERNEL);
  115. if (!utmi)
  116. return ERR_PTR(-ENOMEM);
  117. init.name = name;
  118. init.ops = &utmi_ops;
  119. init.parent_names = parent_name ? &parent_name : NULL;
  120. init.num_parents = parent_name ? 1 : 0;
  121. init.flags = CLK_SET_RATE_GATE;
  122. utmi->hw.init = &init;
  123. utmi->regmap_pmc = regmap_pmc;
  124. utmi->regmap_sfr = regmap_sfr;
  125. hw = &utmi->hw;
  126. ret = clk_hw_register(NULL, &utmi->hw);
  127. if (ret) {
  128. kfree(utmi);
  129. hw = ERR_PTR(ret);
  130. }
  131. return hw;
  132. }
  133. static void __init of_at91sam9x5_clk_utmi_setup(struct device_node *np)
  134. {
  135. struct clk_hw *hw;
  136. const char *parent_name;
  137. const char *name = np->name;
  138. struct regmap *regmap_pmc, *regmap_sfr;
  139. parent_name = of_clk_get_parent_name(np, 0);
  140. of_property_read_string(np, "clock-output-names", &name);
  141. regmap_pmc = syscon_node_to_regmap(of_get_parent(np));
  142. if (IS_ERR(regmap_pmc))
  143. return;
  144. /*
  145. * If the device supports different mainck rates, this value has to be
  146. * set in the UTMI Clock Trimming register.
  147. * - 9x5: mainck supports several rates but it is indicated that a
  148. * 12 MHz is needed in case of USB.
  149. * - sama5d3 and sama5d2: mainck supports several rates. Configuring
  150. * the FREQ field of the UTMI Clock Trimming register is mandatory.
  151. * - sama5d4: mainck is at 12 MHz.
  152. *
  153. * We only need to retrieve sama5d3 or sama5d2 sfr regmap.
  154. */
  155. regmap_sfr = syscon_regmap_lookup_by_compatible("atmel,sama5d3-sfr");
  156. if (IS_ERR(regmap_sfr)) {
  157. regmap_sfr = syscon_regmap_lookup_by_compatible("atmel,sama5d2-sfr");
  158. if (IS_ERR(regmap_sfr))
  159. regmap_sfr = NULL;
  160. }
  161. hw = at91_clk_register_utmi(regmap_pmc, regmap_sfr, name, parent_name);
  162. if (IS_ERR(hw))
  163. return;
  164. of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
  165. return;
  166. }
  167. CLK_OF_DECLARE(at91sam9x5_clk_utmi, "atmel,at91sam9x5-clk-utmi",
  168. of_at91sam9x5_clk_utmi_setup);