ptp_dte.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. /*
  2. * Copyright 2017 Broadcom
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as
  6. * published by the Free Software Foundation version 2.
  7. *
  8. * This program is distributed "as is" WITHOUT ANY WARRANTY of any
  9. * kind, whether express or implied; without even the implied warranty
  10. * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. */
  13. #include <linux/err.h>
  14. #include <linux/io.h>
  15. #include <linux/module.h>
  16. #include <linux/mod_devicetable.h>
  17. #include <linux/platform_device.h>
  18. #include <linux/ptp_clock_kernel.h>
  19. #include <linux/types.h>
  20. #define DTE_NCO_LOW_TIME_REG 0x00
  21. #define DTE_NCO_TIME_REG 0x04
  22. #define DTE_NCO_OVERFLOW_REG 0x08
  23. #define DTE_NCO_INC_REG 0x0c
  24. #define DTE_NCO_SUM2_MASK 0xffffffff
  25. #define DTE_NCO_SUM2_SHIFT 4ULL
  26. #define DTE_NCO_SUM3_MASK 0xff
  27. #define DTE_NCO_SUM3_SHIFT 36ULL
  28. #define DTE_NCO_SUM3_WR_SHIFT 8
  29. #define DTE_NCO_TS_WRAP_MASK 0xfff
  30. #define DTE_NCO_TS_WRAP_LSHIFT 32
  31. #define DTE_NCO_INC_DEFAULT 0x80000000
  32. #define DTE_NUM_REGS_TO_RESTORE 4
  33. /* Full wrap around is 44bits in ns (~4.887 hrs) */
  34. #define DTE_WRAP_AROUND_NSEC_SHIFT 44
  35. /* 44 bits NCO */
  36. #define DTE_NCO_MAX_NS 0xFFFFFFFFFFFLL
  37. /* 125MHz with 3.29 reg cfg */
  38. #define DTE_PPB_ADJ(ppb) (u32)(div64_u64((((u64)abs(ppb) * BIT(28)) +\
  39. 62500000ULL), 125000000ULL))
  40. /* ptp dte priv structure */
  41. struct ptp_dte {
  42. void __iomem *regs;
  43. struct ptp_clock *ptp_clk;
  44. struct ptp_clock_info caps;
  45. struct device *dev;
  46. u32 ts_ovf_last;
  47. u32 ts_wrap_cnt;
  48. spinlock_t lock;
  49. u32 reg_val[DTE_NUM_REGS_TO_RESTORE];
  50. };
  51. static void dte_write_nco(void __iomem *regs, s64 ns)
  52. {
  53. u32 sum2, sum3;
  54. sum2 = (u32)((ns >> DTE_NCO_SUM2_SHIFT) & DTE_NCO_SUM2_MASK);
  55. /* compensate for ignoring sum1 */
  56. if (sum2 != DTE_NCO_SUM2_MASK)
  57. sum2++;
  58. /* to write sum3, bits [15:8] needs to be written */
  59. sum3 = (u32)(((ns >> DTE_NCO_SUM3_SHIFT) & DTE_NCO_SUM3_MASK) <<
  60. DTE_NCO_SUM3_WR_SHIFT);
  61. writel(0, (regs + DTE_NCO_LOW_TIME_REG));
  62. writel(sum2, (regs + DTE_NCO_TIME_REG));
  63. writel(sum3, (regs + DTE_NCO_OVERFLOW_REG));
  64. }
  65. static s64 dte_read_nco(void __iomem *regs)
  66. {
  67. u32 sum2, sum3;
  68. s64 ns;
  69. /*
  70. * ignoring sum1 (4 bits) gives a 16ns resolution, which
  71. * works due to the async register read.
  72. */
  73. sum3 = readl(regs + DTE_NCO_OVERFLOW_REG) & DTE_NCO_SUM3_MASK;
  74. sum2 = readl(regs + DTE_NCO_TIME_REG);
  75. ns = ((s64)sum3 << DTE_NCO_SUM3_SHIFT) |
  76. ((s64)sum2 << DTE_NCO_SUM2_SHIFT);
  77. return ns;
  78. }
  79. static void dte_write_nco_delta(struct ptp_dte *ptp_dte, s64 delta)
  80. {
  81. s64 ns;
  82. ns = dte_read_nco(ptp_dte->regs);
  83. /* handle wraparound conditions */
  84. if ((delta < 0) && (abs(delta) > ns)) {
  85. if (ptp_dte->ts_wrap_cnt) {
  86. ns += DTE_NCO_MAX_NS + delta;
  87. ptp_dte->ts_wrap_cnt--;
  88. } else {
  89. ns = 0;
  90. }
  91. } else {
  92. ns += delta;
  93. if (ns > DTE_NCO_MAX_NS) {
  94. ptp_dte->ts_wrap_cnt++;
  95. ns -= DTE_NCO_MAX_NS;
  96. }
  97. }
  98. dte_write_nco(ptp_dte->regs, ns);
  99. ptp_dte->ts_ovf_last = (ns >> DTE_NCO_TS_WRAP_LSHIFT) &
  100. DTE_NCO_TS_WRAP_MASK;
  101. }
  102. static s64 dte_read_nco_with_ovf(struct ptp_dte *ptp_dte)
  103. {
  104. u32 ts_ovf;
  105. s64 ns = 0;
  106. ns = dte_read_nco(ptp_dte->regs);
  107. /*Timestamp overflow: 8 LSB bits of sum3, 4 MSB bits of sum2 */
  108. ts_ovf = (ns >> DTE_NCO_TS_WRAP_LSHIFT) & DTE_NCO_TS_WRAP_MASK;
  109. /* Check for wrap around */
  110. if (ts_ovf < ptp_dte->ts_ovf_last)
  111. ptp_dte->ts_wrap_cnt++;
  112. ptp_dte->ts_ovf_last = ts_ovf;
  113. /* adjust for wraparounds */
  114. ns += (s64)(BIT_ULL(DTE_WRAP_AROUND_NSEC_SHIFT) * ptp_dte->ts_wrap_cnt);
  115. return ns;
  116. }
  117. static int ptp_dte_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
  118. {
  119. u32 nco_incr;
  120. unsigned long flags;
  121. struct ptp_dte *ptp_dte = container_of(ptp, struct ptp_dte, caps);
  122. if (abs(ppb) > ptp_dte->caps.max_adj) {
  123. dev_err(ptp_dte->dev, "ppb adj too big\n");
  124. return -EINVAL;
  125. }
  126. if (ppb < 0)
  127. nco_incr = DTE_NCO_INC_DEFAULT - DTE_PPB_ADJ(ppb);
  128. else
  129. nco_incr = DTE_NCO_INC_DEFAULT + DTE_PPB_ADJ(ppb);
  130. spin_lock_irqsave(&ptp_dte->lock, flags);
  131. writel(nco_incr, ptp_dte->regs + DTE_NCO_INC_REG);
  132. spin_unlock_irqrestore(&ptp_dte->lock, flags);
  133. return 0;
  134. }
  135. static int ptp_dte_adjtime(struct ptp_clock_info *ptp, s64 delta)
  136. {
  137. unsigned long flags;
  138. struct ptp_dte *ptp_dte = container_of(ptp, struct ptp_dte, caps);
  139. spin_lock_irqsave(&ptp_dte->lock, flags);
  140. dte_write_nco_delta(ptp_dte, delta);
  141. spin_unlock_irqrestore(&ptp_dte->lock, flags);
  142. return 0;
  143. }
  144. static int ptp_dte_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)
  145. {
  146. unsigned long flags;
  147. struct ptp_dte *ptp_dte = container_of(ptp, struct ptp_dte, caps);
  148. spin_lock_irqsave(&ptp_dte->lock, flags);
  149. *ts = ns_to_timespec64(dte_read_nco_with_ovf(ptp_dte));
  150. spin_unlock_irqrestore(&ptp_dte->lock, flags);
  151. return 0;
  152. }
  153. static int ptp_dte_settime(struct ptp_clock_info *ptp,
  154. const struct timespec64 *ts)
  155. {
  156. unsigned long flags;
  157. struct ptp_dte *ptp_dte = container_of(ptp, struct ptp_dte, caps);
  158. spin_lock_irqsave(&ptp_dte->lock, flags);
  159. /* Disable nco increment */
  160. writel(0, ptp_dte->regs + DTE_NCO_INC_REG);
  161. dte_write_nco(ptp_dte->regs, timespec64_to_ns(ts));
  162. /* reset overflow and wrap counter */
  163. ptp_dte->ts_ovf_last = 0;
  164. ptp_dte->ts_wrap_cnt = 0;
  165. /* Enable nco increment */
  166. writel(DTE_NCO_INC_DEFAULT, ptp_dte->regs + DTE_NCO_INC_REG);
  167. spin_unlock_irqrestore(&ptp_dte->lock, flags);
  168. return 0;
  169. }
  170. static int ptp_dte_enable(struct ptp_clock_info *ptp,
  171. struct ptp_clock_request *rq, int on)
  172. {
  173. return -EOPNOTSUPP;
  174. }
  175. static const struct ptp_clock_info ptp_dte_caps = {
  176. .owner = THIS_MODULE,
  177. .name = "DTE PTP timer",
  178. .max_adj = 50000000,
  179. .n_ext_ts = 0,
  180. .n_pins = 0,
  181. .pps = 0,
  182. .adjfreq = ptp_dte_adjfreq,
  183. .adjtime = ptp_dte_adjtime,
  184. .gettime64 = ptp_dte_gettime,
  185. .settime64 = ptp_dte_settime,
  186. .enable = ptp_dte_enable,
  187. };
  188. static int ptp_dte_probe(struct platform_device *pdev)
  189. {
  190. struct ptp_dte *ptp_dte;
  191. struct device *dev = &pdev->dev;
  192. struct resource *res;
  193. ptp_dte = devm_kzalloc(dev, sizeof(struct ptp_dte), GFP_KERNEL);
  194. if (!ptp_dte)
  195. return -ENOMEM;
  196. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  197. ptp_dte->regs = devm_ioremap_resource(dev, res);
  198. if (IS_ERR(ptp_dte->regs))
  199. return PTR_ERR(ptp_dte->regs);
  200. spin_lock_init(&ptp_dte->lock);
  201. ptp_dte->dev = dev;
  202. ptp_dte->caps = ptp_dte_caps;
  203. ptp_dte->ptp_clk = ptp_clock_register(&ptp_dte->caps, &pdev->dev);
  204. if (IS_ERR(ptp_dte->ptp_clk)) {
  205. dev_err(dev,
  206. "%s: Failed to register ptp clock\n", __func__);
  207. return PTR_ERR(ptp_dte->ptp_clk);
  208. }
  209. platform_set_drvdata(pdev, ptp_dte);
  210. dev_info(dev, "ptp clk probe done\n");
  211. return 0;
  212. }
  213. static int ptp_dte_remove(struct platform_device *pdev)
  214. {
  215. struct ptp_dte *ptp_dte = platform_get_drvdata(pdev);
  216. u8 i;
  217. ptp_clock_unregister(ptp_dte->ptp_clk);
  218. for (i = 0; i < DTE_NUM_REGS_TO_RESTORE; i++)
  219. writel(0, ptp_dte->regs + (i * sizeof(u32)));
  220. return 0;
  221. }
  222. #ifdef CONFIG_PM_SLEEP
  223. static int ptp_dte_suspend(struct device *dev)
  224. {
  225. struct ptp_dte *ptp_dte = dev_get_drvdata(dev);
  226. u8 i;
  227. for (i = 0; i < DTE_NUM_REGS_TO_RESTORE; i++) {
  228. ptp_dte->reg_val[i] =
  229. readl(ptp_dte->regs + (i * sizeof(u32)));
  230. }
  231. /* disable the nco */
  232. writel(0, ptp_dte->regs + DTE_NCO_INC_REG);
  233. return 0;
  234. }
  235. static int ptp_dte_resume(struct device *dev)
  236. {
  237. struct ptp_dte *ptp_dte = dev_get_drvdata(dev);
  238. u8 i;
  239. for (i = 0; i < DTE_NUM_REGS_TO_RESTORE; i++) {
  240. if ((i * sizeof(u32)) != DTE_NCO_OVERFLOW_REG)
  241. writel(ptp_dte->reg_val[i],
  242. (ptp_dte->regs + (i * sizeof(u32))));
  243. else
  244. writel(((ptp_dte->reg_val[i] &
  245. DTE_NCO_SUM3_MASK) << DTE_NCO_SUM3_WR_SHIFT),
  246. (ptp_dte->regs + (i * sizeof(u32))));
  247. }
  248. return 0;
  249. }
  250. static const struct dev_pm_ops ptp_dte_pm_ops = {
  251. .suspend = ptp_dte_suspend,
  252. .resume = ptp_dte_resume
  253. };
  254. #define PTP_DTE_PM_OPS (&ptp_dte_pm_ops)
  255. #else
  256. #define PTP_DTE_PM_OPS NULL
  257. #endif
  258. static const struct of_device_id ptp_dte_of_match[] = {
  259. { .compatible = "brcm,ptp-dte", },
  260. {},
  261. };
  262. MODULE_DEVICE_TABLE(of, ptp_dte_of_match);
  263. static struct platform_driver ptp_dte_driver = {
  264. .driver = {
  265. .name = "ptp-dte",
  266. .pm = PTP_DTE_PM_OPS,
  267. .of_match_table = ptp_dte_of_match,
  268. },
  269. .probe = ptp_dte_probe,
  270. .remove = ptp_dte_remove,
  271. };
  272. module_platform_driver(ptp_dte_driver);
  273. MODULE_AUTHOR("Broadcom");
  274. MODULE_DESCRIPTION("Broadcom DTE PTP Clock driver");
  275. MODULE_LICENSE("GPL v2");