clk-plldig.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright 2019 NXP
  4. *
  5. * Clock driver for LS1028A Display output interfaces(LCD, DPHY).
  6. */
  7. #include <linux/clk-provider.h>
  8. #include <linux/device.h>
  9. #include <linux/module.h>
  10. #include <linux/err.h>
  11. #include <linux/io.h>
  12. #include <linux/iopoll.h>
  13. #include <linux/of.h>
  14. #include <linux/of_address.h>
  15. #include <linux/of_device.h>
  16. #include <linux/platform_device.h>
  17. #include <linux/slab.h>
  18. #include <linux/bitfield.h>
  19. /* PLLDIG register offsets and bit masks */
  20. #define PLLDIG_REG_PLLSR 0x24
  21. #define PLLDIG_LOCK_MASK BIT(2)
  22. #define PLLDIG_REG_PLLDV 0x28
  23. #define PLLDIG_MFD_MASK GENMASK(7, 0)
  24. #define PLLDIG_RFDPHI1_MASK GENMASK(30, 25)
  25. #define PLLDIG_REG_PLLFM 0x2c
  26. #define PLLDIG_SSCGBYP_ENABLE BIT(30)
  27. #define PLLDIG_REG_PLLFD 0x30
  28. #define PLLDIG_FDEN BIT(30)
  29. #define PLLDIG_FRAC_MASK GENMASK(15, 0)
  30. #define PLLDIG_REG_PLLCAL1 0x38
  31. #define PLLDIG_REG_PLLCAL2 0x3c
  32. /* Range of the VCO frequencies, in Hz */
  33. #define PLLDIG_MIN_VCO_FREQ 650000000
  34. #define PLLDIG_MAX_VCO_FREQ 1300000000
  35. /* Range of the output frequencies, in Hz */
  36. #define PHI1_MIN_FREQ 27000000UL
  37. #define PHI1_MAX_FREQ 600000000UL
  38. /* Maximum value of the reduced frequency divider */
  39. #define MAX_RFDPHI1 63UL
  40. /* Best value of multiplication factor divider */
  41. #define PLLDIG_DEFAULT_MFD 44
  42. /*
  43. * Denominator part of the fractional part of the
  44. * loop multiplication factor.
  45. */
  46. #define MFDEN 20480
  47. static const struct clk_parent_data parent_data[] = {
  48. { .index = 0 },
  49. };
  50. struct clk_plldig {
  51. struct clk_hw hw;
  52. void __iomem *regs;
  53. unsigned int vco_freq;
  54. };
  55. #define to_clk_plldig(_hw) container_of(_hw, struct clk_plldig, hw)
  56. static int plldig_enable(struct clk_hw *hw)
  57. {
  58. struct clk_plldig *data = to_clk_plldig(hw);
  59. u32 val;
  60. val = readl(data->regs + PLLDIG_REG_PLLFM);
  61. /*
  62. * Use Bypass mode with PLL off by default, the frequency overshoot
  63. * detector output was disable. SSCG Bypass mode should be enable.
  64. */
  65. val |= PLLDIG_SSCGBYP_ENABLE;
  66. writel(val, data->regs + PLLDIG_REG_PLLFM);
  67. return 0;
  68. }
  69. static void plldig_disable(struct clk_hw *hw)
  70. {
  71. struct clk_plldig *data = to_clk_plldig(hw);
  72. u32 val;
  73. val = readl(data->regs + PLLDIG_REG_PLLFM);
  74. val &= ~PLLDIG_SSCGBYP_ENABLE;
  75. val |= FIELD_PREP(PLLDIG_SSCGBYP_ENABLE, 0x0);
  76. writel(val, data->regs + PLLDIG_REG_PLLFM);
  77. }
  78. static int plldig_is_enabled(struct clk_hw *hw)
  79. {
  80. struct clk_plldig *data = to_clk_plldig(hw);
  81. return readl(data->regs + PLLDIG_REG_PLLFM) &
  82. PLLDIG_SSCGBYP_ENABLE;
  83. }
  84. static unsigned long plldig_recalc_rate(struct clk_hw *hw,
  85. unsigned long parent_rate)
  86. {
  87. struct clk_plldig *data = to_clk_plldig(hw);
  88. u32 val, rfdphi1;
  89. val = readl(data->regs + PLLDIG_REG_PLLDV);
  90. /* Check if PLL is bypassed */
  91. if (val & PLLDIG_SSCGBYP_ENABLE)
  92. return parent_rate;
  93. rfdphi1 = FIELD_GET(PLLDIG_RFDPHI1_MASK, val);
  94. /*
  95. * If RFDPHI1 has a value of 1 the VCO frequency is also divided by
  96. * one.
  97. */
  98. if (!rfdphi1)
  99. rfdphi1 = 1;
  100. return DIV_ROUND_UP(data->vco_freq, rfdphi1);
  101. }
  102. static unsigned long plldig_calc_target_div(unsigned long vco_freq,
  103. unsigned long target_rate)
  104. {
  105. unsigned long div;
  106. div = DIV_ROUND_CLOSEST(vco_freq, target_rate);
  107. div = clamp(div, 1UL, MAX_RFDPHI1);
  108. return div;
  109. }
  110. static int plldig_determine_rate(struct clk_hw *hw,
  111. struct clk_rate_request *req)
  112. {
  113. struct clk_plldig *data = to_clk_plldig(hw);
  114. unsigned int div;
  115. req->rate = clamp(req->rate, PHI1_MIN_FREQ, PHI1_MAX_FREQ);
  116. div = plldig_calc_target_div(data->vco_freq, req->rate);
  117. req->rate = DIV_ROUND_UP(data->vco_freq, div);
  118. return 0;
  119. }
  120. static int plldig_set_rate(struct clk_hw *hw, unsigned long rate,
  121. unsigned long parent_rate)
  122. {
  123. struct clk_plldig *data = to_clk_plldig(hw);
  124. unsigned int val, cond;
  125. unsigned int rfdphi1;
  126. rate = clamp(rate, PHI1_MIN_FREQ, PHI1_MAX_FREQ);
  127. rfdphi1 = plldig_calc_target_div(data->vco_freq, rate);
  128. /* update the divider value */
  129. val = readl(data->regs + PLLDIG_REG_PLLDV);
  130. val &= ~PLLDIG_RFDPHI1_MASK;
  131. val |= FIELD_PREP(PLLDIG_RFDPHI1_MASK, rfdphi1);
  132. writel(val, data->regs + PLLDIG_REG_PLLDV);
  133. /* waiting for old lock state to clear */
  134. udelay(200);
  135. /* Wait until PLL is locked or timeout */
  136. return readl_poll_timeout_atomic(data->regs + PLLDIG_REG_PLLSR, cond,
  137. cond & PLLDIG_LOCK_MASK, 0,
  138. USEC_PER_MSEC);
  139. }
  140. static const struct clk_ops plldig_clk_ops = {
  141. .enable = plldig_enable,
  142. .disable = plldig_disable,
  143. .is_enabled = plldig_is_enabled,
  144. .recalc_rate = plldig_recalc_rate,
  145. .determine_rate = plldig_determine_rate,
  146. .set_rate = plldig_set_rate,
  147. };
  148. static int plldig_init(struct clk_hw *hw)
  149. {
  150. struct clk_plldig *data = to_clk_plldig(hw);
  151. struct clk_hw *parent = clk_hw_get_parent(hw);
  152. unsigned long parent_rate;
  153. unsigned long val;
  154. unsigned long long lltmp;
  155. unsigned int mfd, fracdiv = 0;
  156. if (!parent)
  157. return -EINVAL;
  158. parent_rate = clk_hw_get_rate(parent);
  159. if (data->vco_freq) {
  160. mfd = data->vco_freq / parent_rate;
  161. lltmp = data->vco_freq % parent_rate;
  162. lltmp *= MFDEN;
  163. do_div(lltmp, parent_rate);
  164. fracdiv = lltmp;
  165. } else {
  166. mfd = PLLDIG_DEFAULT_MFD;
  167. data->vco_freq = parent_rate * mfd;
  168. }
  169. val = FIELD_PREP(PLLDIG_MFD_MASK, mfd);
  170. writel(val, data->regs + PLLDIG_REG_PLLDV);
  171. /* Enable fractional divider */
  172. if (fracdiv) {
  173. val = FIELD_PREP(PLLDIG_FRAC_MASK, fracdiv);
  174. val |= PLLDIG_FDEN;
  175. writel(val, data->regs + PLLDIG_REG_PLLFD);
  176. }
  177. return 0;
  178. }
  179. static int plldig_clk_probe(struct platform_device *pdev)
  180. {
  181. struct clk_plldig *data;
  182. struct device *dev = &pdev->dev;
  183. int ret;
  184. data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
  185. if (!data)
  186. return -ENOMEM;
  187. data->regs = devm_platform_ioremap_resource(pdev, 0);
  188. if (IS_ERR(data->regs))
  189. return PTR_ERR(data->regs);
  190. data->hw.init = CLK_HW_INIT_PARENTS_DATA("dpclk",
  191. parent_data,
  192. &plldig_clk_ops,
  193. 0);
  194. ret = devm_clk_hw_register(dev, &data->hw);
  195. if (ret) {
  196. dev_err(dev, "failed to register %s clock\n",
  197. dev->of_node->name);
  198. return ret;
  199. }
  200. ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get,
  201. &data->hw);
  202. if (ret) {
  203. dev_err(dev, "unable to add clk provider\n");
  204. return ret;
  205. }
  206. /*
  207. * The frequency of the VCO cannot be changed during runtime.
  208. * Therefore, let the user specify a desired frequency.
  209. */
  210. if (!of_property_read_u32(dev->of_node, "fsl,vco-hz",
  211. &data->vco_freq)) {
  212. if (data->vco_freq < PLLDIG_MIN_VCO_FREQ ||
  213. data->vco_freq > PLLDIG_MAX_VCO_FREQ)
  214. return -EINVAL;
  215. }
  216. return plldig_init(&data->hw);
  217. }
  218. static const struct of_device_id plldig_clk_id[] = {
  219. { .compatible = "fsl,ls1028a-plldig" },
  220. { }
  221. };
  222. MODULE_DEVICE_TABLE(of, plldig_clk_id);
  223. static struct platform_driver plldig_clk_driver = {
  224. .driver = {
  225. .name = "plldig-clock",
  226. .of_match_table = plldig_clk_id,
  227. },
  228. .probe = plldig_clk_probe,
  229. };
  230. module_platform_driver(plldig_clk_driver);
  231. MODULE_LICENSE("GPL v2");
  232. MODULE_AUTHOR("Wen He <[email protected]>");
  233. MODULE_DESCRIPTION("LS1028A Display output interface pixel clock driver");