clk-usb.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  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/of_address.h>
  15. #include <linux/io.h>
  16. #include "pmc.h"
  17. #define USB_SOURCE_MAX 2
  18. #define SAM9X5_USB_DIV_SHIFT 8
  19. #define SAM9X5_USB_MAX_DIV 0xf
  20. #define RM9200_USB_DIV_SHIFT 28
  21. #define RM9200_USB_DIV_TAB_SIZE 4
  22. struct at91sam9x5_clk_usb {
  23. struct clk_hw hw;
  24. struct at91_pmc *pmc;
  25. };
  26. #define to_at91sam9x5_clk_usb(hw) \
  27. container_of(hw, struct at91sam9x5_clk_usb, hw)
  28. struct at91rm9200_clk_usb {
  29. struct clk_hw hw;
  30. struct at91_pmc *pmc;
  31. u32 divisors[4];
  32. };
  33. #define to_at91rm9200_clk_usb(hw) \
  34. container_of(hw, struct at91rm9200_clk_usb, hw)
  35. static unsigned long at91sam9x5_clk_usb_recalc_rate(struct clk_hw *hw,
  36. unsigned long parent_rate)
  37. {
  38. u32 tmp;
  39. u8 usbdiv;
  40. struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw);
  41. struct at91_pmc *pmc = usb->pmc;
  42. tmp = pmc_read(pmc, AT91_PMC_USB);
  43. usbdiv = (tmp & AT91_PMC_OHCIUSBDIV) >> SAM9X5_USB_DIV_SHIFT;
  44. return DIV_ROUND_CLOSEST(parent_rate, (usbdiv + 1));
  45. }
  46. static int at91sam9x5_clk_usb_determine_rate(struct clk_hw *hw,
  47. struct clk_rate_request *req)
  48. {
  49. struct clk_hw *parent;
  50. long best_rate = -EINVAL;
  51. unsigned long tmp_rate;
  52. int best_diff = -1;
  53. int tmp_diff;
  54. int i;
  55. for (i = 0; i < clk_hw_get_num_parents(hw); i++) {
  56. int div;
  57. parent = clk_hw_get_parent_by_index(hw, i);
  58. if (!parent)
  59. continue;
  60. for (div = 1; div < SAM9X5_USB_MAX_DIV + 2; div++) {
  61. unsigned long tmp_parent_rate;
  62. tmp_parent_rate = req->rate * div;
  63. tmp_parent_rate = clk_hw_round_rate(parent,
  64. tmp_parent_rate);
  65. tmp_rate = DIV_ROUND_CLOSEST(tmp_parent_rate, div);
  66. if (tmp_rate < req->rate)
  67. tmp_diff = req->rate - tmp_rate;
  68. else
  69. tmp_diff = tmp_rate - req->rate;
  70. if (best_diff < 0 || best_diff > tmp_diff) {
  71. best_rate = tmp_rate;
  72. best_diff = tmp_diff;
  73. req->best_parent_rate = tmp_parent_rate;
  74. req->best_parent_hw = parent;
  75. }
  76. if (!best_diff || tmp_rate < req->rate)
  77. break;
  78. }
  79. if (!best_diff)
  80. break;
  81. }
  82. if (best_rate < 0)
  83. return best_rate;
  84. req->rate = best_rate;
  85. return 0;
  86. }
  87. static int at91sam9x5_clk_usb_set_parent(struct clk_hw *hw, u8 index)
  88. {
  89. u32 tmp;
  90. struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw);
  91. struct at91_pmc *pmc = usb->pmc;
  92. if (index > 1)
  93. return -EINVAL;
  94. tmp = pmc_read(pmc, AT91_PMC_USB) & ~AT91_PMC_USBS;
  95. if (index)
  96. tmp |= AT91_PMC_USBS;
  97. pmc_write(pmc, AT91_PMC_USB, tmp);
  98. return 0;
  99. }
  100. static u8 at91sam9x5_clk_usb_get_parent(struct clk_hw *hw)
  101. {
  102. struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw);
  103. struct at91_pmc *pmc = usb->pmc;
  104. return pmc_read(pmc, AT91_PMC_USB) & AT91_PMC_USBS;
  105. }
  106. static int at91sam9x5_clk_usb_set_rate(struct clk_hw *hw, unsigned long rate,
  107. unsigned long parent_rate)
  108. {
  109. u32 tmp;
  110. struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw);
  111. struct at91_pmc *pmc = usb->pmc;
  112. unsigned long div;
  113. if (!rate)
  114. return -EINVAL;
  115. div = DIV_ROUND_CLOSEST(parent_rate, rate);
  116. if (div > SAM9X5_USB_MAX_DIV + 1 || !div)
  117. return -EINVAL;
  118. tmp = pmc_read(pmc, AT91_PMC_USB) & ~AT91_PMC_OHCIUSBDIV;
  119. tmp |= (div - 1) << SAM9X5_USB_DIV_SHIFT;
  120. pmc_write(pmc, AT91_PMC_USB, tmp);
  121. return 0;
  122. }
  123. static const struct clk_ops at91sam9x5_usb_ops = {
  124. .recalc_rate = at91sam9x5_clk_usb_recalc_rate,
  125. .determine_rate = at91sam9x5_clk_usb_determine_rate,
  126. .get_parent = at91sam9x5_clk_usb_get_parent,
  127. .set_parent = at91sam9x5_clk_usb_set_parent,
  128. .set_rate = at91sam9x5_clk_usb_set_rate,
  129. };
  130. static int at91sam9n12_clk_usb_enable(struct clk_hw *hw)
  131. {
  132. struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw);
  133. struct at91_pmc *pmc = usb->pmc;
  134. pmc_write(pmc, AT91_PMC_USB,
  135. pmc_read(pmc, AT91_PMC_USB) | AT91_PMC_USBS);
  136. return 0;
  137. }
  138. static void at91sam9n12_clk_usb_disable(struct clk_hw *hw)
  139. {
  140. struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw);
  141. struct at91_pmc *pmc = usb->pmc;
  142. pmc_write(pmc, AT91_PMC_USB,
  143. pmc_read(pmc, AT91_PMC_USB) & ~AT91_PMC_USBS);
  144. }
  145. static int at91sam9n12_clk_usb_is_enabled(struct clk_hw *hw)
  146. {
  147. struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw);
  148. struct at91_pmc *pmc = usb->pmc;
  149. return !!(pmc_read(pmc, AT91_PMC_USB) & AT91_PMC_USBS);
  150. }
  151. static const struct clk_ops at91sam9n12_usb_ops = {
  152. .enable = at91sam9n12_clk_usb_enable,
  153. .disable = at91sam9n12_clk_usb_disable,
  154. .is_enabled = at91sam9n12_clk_usb_is_enabled,
  155. .recalc_rate = at91sam9x5_clk_usb_recalc_rate,
  156. .determine_rate = at91sam9x5_clk_usb_determine_rate,
  157. .set_rate = at91sam9x5_clk_usb_set_rate,
  158. };
  159. static struct clk * __init
  160. at91sam9x5_clk_register_usb(struct at91_pmc *pmc, const char *name,
  161. const char **parent_names, u8 num_parents)
  162. {
  163. struct at91sam9x5_clk_usb *usb;
  164. struct clk *clk = NULL;
  165. struct clk_init_data init;
  166. usb = kzalloc(sizeof(*usb), GFP_KERNEL);
  167. if (!usb)
  168. return ERR_PTR(-ENOMEM);
  169. init.name = name;
  170. init.ops = &at91sam9x5_usb_ops;
  171. init.parent_names = parent_names;
  172. init.num_parents = num_parents;
  173. init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
  174. CLK_SET_RATE_PARENT;
  175. usb->hw.init = &init;
  176. usb->pmc = pmc;
  177. clk = clk_register(NULL, &usb->hw);
  178. if (IS_ERR(clk))
  179. kfree(usb);
  180. return clk;
  181. }
  182. static struct clk * __init
  183. at91sam9n12_clk_register_usb(struct at91_pmc *pmc, const char *name,
  184. const char *parent_name)
  185. {
  186. struct at91sam9x5_clk_usb *usb;
  187. struct clk *clk = NULL;
  188. struct clk_init_data init;
  189. usb = kzalloc(sizeof(*usb), GFP_KERNEL);
  190. if (!usb)
  191. return ERR_PTR(-ENOMEM);
  192. init.name = name;
  193. init.ops = &at91sam9n12_usb_ops;
  194. init.parent_names = &parent_name;
  195. init.num_parents = 1;
  196. init.flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT;
  197. usb->hw.init = &init;
  198. usb->pmc = pmc;
  199. clk = clk_register(NULL, &usb->hw);
  200. if (IS_ERR(clk))
  201. kfree(usb);
  202. return clk;
  203. }
  204. static unsigned long at91rm9200_clk_usb_recalc_rate(struct clk_hw *hw,
  205. unsigned long parent_rate)
  206. {
  207. struct at91rm9200_clk_usb *usb = to_at91rm9200_clk_usb(hw);
  208. struct at91_pmc *pmc = usb->pmc;
  209. u32 tmp;
  210. u8 usbdiv;
  211. tmp = pmc_read(pmc, AT91_CKGR_PLLBR);
  212. usbdiv = (tmp & AT91_PMC_USBDIV) >> RM9200_USB_DIV_SHIFT;
  213. if (usb->divisors[usbdiv])
  214. return parent_rate / usb->divisors[usbdiv];
  215. return 0;
  216. }
  217. static long at91rm9200_clk_usb_round_rate(struct clk_hw *hw, unsigned long rate,
  218. unsigned long *parent_rate)
  219. {
  220. struct at91rm9200_clk_usb *usb = to_at91rm9200_clk_usb(hw);
  221. struct clk_hw *parent = clk_hw_get_parent(hw);
  222. unsigned long bestrate = 0;
  223. int bestdiff = -1;
  224. unsigned long tmprate;
  225. int tmpdiff;
  226. int i = 0;
  227. for (i = 0; i < RM9200_USB_DIV_TAB_SIZE; i++) {
  228. unsigned long tmp_parent_rate;
  229. if (!usb->divisors[i])
  230. continue;
  231. tmp_parent_rate = rate * usb->divisors[i];
  232. tmp_parent_rate = clk_hw_round_rate(parent, tmp_parent_rate);
  233. tmprate = DIV_ROUND_CLOSEST(tmp_parent_rate, usb->divisors[i]);
  234. if (tmprate < rate)
  235. tmpdiff = rate - tmprate;
  236. else
  237. tmpdiff = tmprate - rate;
  238. if (bestdiff < 0 || bestdiff > tmpdiff) {
  239. bestrate = tmprate;
  240. bestdiff = tmpdiff;
  241. *parent_rate = tmp_parent_rate;
  242. }
  243. if (!bestdiff)
  244. break;
  245. }
  246. return bestrate;
  247. }
  248. static int at91rm9200_clk_usb_set_rate(struct clk_hw *hw, unsigned long rate,
  249. unsigned long parent_rate)
  250. {
  251. u32 tmp;
  252. int i;
  253. struct at91rm9200_clk_usb *usb = to_at91rm9200_clk_usb(hw);
  254. struct at91_pmc *pmc = usb->pmc;
  255. unsigned long div;
  256. if (!rate)
  257. return -EINVAL;
  258. div = DIV_ROUND_CLOSEST(parent_rate, rate);
  259. for (i = 0; i < RM9200_USB_DIV_TAB_SIZE; i++) {
  260. if (usb->divisors[i] == div) {
  261. tmp = pmc_read(pmc, AT91_CKGR_PLLBR) &
  262. ~AT91_PMC_USBDIV;
  263. tmp |= i << RM9200_USB_DIV_SHIFT;
  264. pmc_write(pmc, AT91_CKGR_PLLBR, tmp);
  265. return 0;
  266. }
  267. }
  268. return -EINVAL;
  269. }
  270. static const struct clk_ops at91rm9200_usb_ops = {
  271. .recalc_rate = at91rm9200_clk_usb_recalc_rate,
  272. .round_rate = at91rm9200_clk_usb_round_rate,
  273. .set_rate = at91rm9200_clk_usb_set_rate,
  274. };
  275. static struct clk * __init
  276. at91rm9200_clk_register_usb(struct at91_pmc *pmc, const char *name,
  277. const char *parent_name, const u32 *divisors)
  278. {
  279. struct at91rm9200_clk_usb *usb;
  280. struct clk *clk = NULL;
  281. struct clk_init_data init;
  282. usb = kzalloc(sizeof(*usb), GFP_KERNEL);
  283. if (!usb)
  284. return ERR_PTR(-ENOMEM);
  285. init.name = name;
  286. init.ops = &at91rm9200_usb_ops;
  287. init.parent_names = &parent_name;
  288. init.num_parents = 1;
  289. init.flags = CLK_SET_RATE_PARENT;
  290. usb->hw.init = &init;
  291. usb->pmc = pmc;
  292. memcpy(usb->divisors, divisors, sizeof(usb->divisors));
  293. clk = clk_register(NULL, &usb->hw);
  294. if (IS_ERR(clk))
  295. kfree(usb);
  296. return clk;
  297. }
  298. void __init of_at91sam9x5_clk_usb_setup(struct device_node *np,
  299. struct at91_pmc *pmc)
  300. {
  301. struct clk *clk;
  302. int num_parents;
  303. const char *parent_names[USB_SOURCE_MAX];
  304. const char *name = np->name;
  305. num_parents = of_clk_get_parent_count(np);
  306. if (num_parents <= 0 || num_parents > USB_SOURCE_MAX)
  307. return;
  308. of_clk_parent_fill(np, parent_names, num_parents);
  309. of_property_read_string(np, "clock-output-names", &name);
  310. clk = at91sam9x5_clk_register_usb(pmc, name, parent_names, num_parents);
  311. if (IS_ERR(clk))
  312. return;
  313. of_clk_add_provider(np, of_clk_src_simple_get, clk);
  314. }
  315. void __init of_at91sam9n12_clk_usb_setup(struct device_node *np,
  316. struct at91_pmc *pmc)
  317. {
  318. struct clk *clk;
  319. const char *parent_name;
  320. const char *name = np->name;
  321. parent_name = of_clk_get_parent_name(np, 0);
  322. if (!parent_name)
  323. return;
  324. of_property_read_string(np, "clock-output-names", &name);
  325. clk = at91sam9n12_clk_register_usb(pmc, name, parent_name);
  326. if (IS_ERR(clk))
  327. return;
  328. of_clk_add_provider(np, of_clk_src_simple_get, clk);
  329. }
  330. void __init of_at91rm9200_clk_usb_setup(struct device_node *np,
  331. struct at91_pmc *pmc)
  332. {
  333. struct clk *clk;
  334. const char *parent_name;
  335. const char *name = np->name;
  336. u32 divisors[4] = {0, 0, 0, 0};
  337. parent_name = of_clk_get_parent_name(np, 0);
  338. if (!parent_name)
  339. return;
  340. of_property_read_u32_array(np, "atmel,clk-divisors", divisors, 4);
  341. if (!divisors[0])
  342. return;
  343. of_property_read_string(np, "clock-output-names", &name);
  344. clk = at91rm9200_clk_register_usb(pmc, name, parent_name, divisors);
  345. if (IS_ERR(clk))
  346. return;
  347. of_clk_add_provider(np, of_clk_src_simple_get, clk);
  348. }