ravb_ptp.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. /* PTP 1588 clock using the Renesas Ethernet AVB
  2. *
  3. * Copyright (C) 2013-2015 Renesas Electronics Corporation
  4. * Copyright (C) 2015 Renesas Solutions Corp.
  5. * Copyright (C) 2015-2016 Cogent Embedded, Inc. <source@cogentembedded.com>
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. */
  12. #include "ravb.h"
  13. static int ravb_ptp_tcr_request(struct ravb_private *priv, u32 request)
  14. {
  15. struct net_device *ndev = priv->ndev;
  16. int error;
  17. error = ravb_wait(ndev, GCCR, GCCR_TCR, GCCR_TCR_NOREQ);
  18. if (error)
  19. return error;
  20. ravb_modify(ndev, GCCR, request, request);
  21. return ravb_wait(ndev, GCCR, GCCR_TCR, GCCR_TCR_NOREQ);
  22. }
  23. /* Caller must hold the lock */
  24. static int ravb_ptp_time_read(struct ravb_private *priv, struct timespec64 *ts)
  25. {
  26. struct net_device *ndev = priv->ndev;
  27. int error;
  28. error = ravb_ptp_tcr_request(priv, GCCR_TCR_CAPTURE);
  29. if (error)
  30. return error;
  31. ts->tv_nsec = ravb_read(ndev, GCT0);
  32. ts->tv_sec = ravb_read(ndev, GCT1) |
  33. ((s64)ravb_read(ndev, GCT2) << 32);
  34. return 0;
  35. }
  36. /* Caller must hold the lock */
  37. static int ravb_ptp_time_write(struct ravb_private *priv,
  38. const struct timespec64 *ts)
  39. {
  40. struct net_device *ndev = priv->ndev;
  41. int error;
  42. u32 gccr;
  43. error = ravb_ptp_tcr_request(priv, GCCR_TCR_RESET);
  44. if (error)
  45. return error;
  46. gccr = ravb_read(ndev, GCCR);
  47. if (gccr & GCCR_LTO)
  48. return -EBUSY;
  49. ravb_write(ndev, ts->tv_nsec, GTO0);
  50. ravb_write(ndev, ts->tv_sec, GTO1);
  51. ravb_write(ndev, (ts->tv_sec >> 32) & 0xffff, GTO2);
  52. ravb_write(ndev, gccr | GCCR_LTO, GCCR);
  53. return 0;
  54. }
  55. /* Caller must hold the lock */
  56. static int ravb_ptp_update_compare(struct ravb_private *priv, u32 ns)
  57. {
  58. struct net_device *ndev = priv->ndev;
  59. /* When the comparison value (GPTC.PTCV) is in range of
  60. * [x-1 to x+1] (x is the configured increment value in
  61. * GTI.TIV), it may happen that a comparison match is
  62. * not detected when the timer wraps around.
  63. */
  64. u32 gti_ns_plus_1 = (priv->ptp.current_addend >> 20) + 1;
  65. u32 gccr;
  66. if (ns < gti_ns_plus_1)
  67. ns = gti_ns_plus_1;
  68. else if (ns > 0 - gti_ns_plus_1)
  69. ns = 0 - gti_ns_plus_1;
  70. gccr = ravb_read(ndev, GCCR);
  71. if (gccr & GCCR_LPTC)
  72. return -EBUSY;
  73. ravb_write(ndev, ns, GPTC);
  74. ravb_write(ndev, gccr | GCCR_LPTC, GCCR);
  75. return 0;
  76. }
  77. /* PTP clock operations */
  78. static int ravb_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
  79. {
  80. struct ravb_private *priv = container_of(ptp, struct ravb_private,
  81. ptp.info);
  82. struct net_device *ndev = priv->ndev;
  83. unsigned long flags;
  84. u32 diff, addend;
  85. bool neg_adj = false;
  86. u32 gccr;
  87. if (ppb < 0) {
  88. neg_adj = true;
  89. ppb = -ppb;
  90. }
  91. addend = priv->ptp.default_addend;
  92. diff = div_u64((u64)addend * ppb, NSEC_PER_SEC);
  93. addend = neg_adj ? addend - diff : addend + diff;
  94. spin_lock_irqsave(&priv->lock, flags);
  95. priv->ptp.current_addend = addend;
  96. gccr = ravb_read(ndev, GCCR);
  97. if (gccr & GCCR_LTI) {
  98. spin_unlock_irqrestore(&priv->lock, flags);
  99. return -EBUSY;
  100. }
  101. ravb_write(ndev, addend & GTI_TIV, GTI);
  102. ravb_write(ndev, gccr | GCCR_LTI, GCCR);
  103. spin_unlock_irqrestore(&priv->lock, flags);
  104. return 0;
  105. }
  106. static int ravb_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
  107. {
  108. struct ravb_private *priv = container_of(ptp, struct ravb_private,
  109. ptp.info);
  110. struct timespec64 ts;
  111. unsigned long flags;
  112. int error;
  113. spin_lock_irqsave(&priv->lock, flags);
  114. error = ravb_ptp_time_read(priv, &ts);
  115. if (!error) {
  116. u64 now = ktime_to_ns(timespec64_to_ktime(ts));
  117. ts = ns_to_timespec64(now + delta);
  118. error = ravb_ptp_time_write(priv, &ts);
  119. }
  120. spin_unlock_irqrestore(&priv->lock, flags);
  121. return error;
  122. }
  123. static int ravb_ptp_gettime64(struct ptp_clock_info *ptp, struct timespec64 *ts)
  124. {
  125. struct ravb_private *priv = container_of(ptp, struct ravb_private,
  126. ptp.info);
  127. unsigned long flags;
  128. int error;
  129. spin_lock_irqsave(&priv->lock, flags);
  130. error = ravb_ptp_time_read(priv, ts);
  131. spin_unlock_irqrestore(&priv->lock, flags);
  132. return error;
  133. }
  134. static int ravb_ptp_settime64(struct ptp_clock_info *ptp,
  135. const struct timespec64 *ts)
  136. {
  137. struct ravb_private *priv = container_of(ptp, struct ravb_private,
  138. ptp.info);
  139. unsigned long flags;
  140. int error;
  141. spin_lock_irqsave(&priv->lock, flags);
  142. error = ravb_ptp_time_write(priv, ts);
  143. spin_unlock_irqrestore(&priv->lock, flags);
  144. return error;
  145. }
  146. static int ravb_ptp_extts(struct ptp_clock_info *ptp,
  147. struct ptp_extts_request *req, int on)
  148. {
  149. struct ravb_private *priv = container_of(ptp, struct ravb_private,
  150. ptp.info);
  151. struct net_device *ndev = priv->ndev;
  152. unsigned long flags;
  153. if (req->index)
  154. return -EINVAL;
  155. if (priv->ptp.extts[req->index] == on)
  156. return 0;
  157. priv->ptp.extts[req->index] = on;
  158. spin_lock_irqsave(&priv->lock, flags);
  159. if (priv->chip_id == RCAR_GEN2)
  160. ravb_modify(ndev, GIC, GIC_PTCE, on ? GIC_PTCE : 0);
  161. else if (on)
  162. ravb_write(ndev, GIE_PTCS, GIE);
  163. else
  164. ravb_write(ndev, GID_PTCD, GID);
  165. mmiowb();
  166. spin_unlock_irqrestore(&priv->lock, flags);
  167. return 0;
  168. }
  169. static int ravb_ptp_perout(struct ptp_clock_info *ptp,
  170. struct ptp_perout_request *req, int on)
  171. {
  172. struct ravb_private *priv = container_of(ptp, struct ravb_private,
  173. ptp.info);
  174. struct net_device *ndev = priv->ndev;
  175. struct ravb_ptp_perout *perout;
  176. unsigned long flags;
  177. int error = 0;
  178. if (req->index)
  179. return -EINVAL;
  180. if (on) {
  181. u64 start_ns;
  182. u64 period_ns;
  183. start_ns = req->start.sec * NSEC_PER_SEC + req->start.nsec;
  184. period_ns = req->period.sec * NSEC_PER_SEC + req->period.nsec;
  185. if (start_ns > U32_MAX) {
  186. netdev_warn(ndev,
  187. "ptp: start value (nsec) is over limit. Maximum size of start is only 32 bits\n");
  188. return -ERANGE;
  189. }
  190. if (period_ns > U32_MAX) {
  191. netdev_warn(ndev,
  192. "ptp: period value (nsec) is over limit. Maximum size of period is only 32 bits\n");
  193. return -ERANGE;
  194. }
  195. spin_lock_irqsave(&priv->lock, flags);
  196. perout = &priv->ptp.perout[req->index];
  197. perout->target = (u32)start_ns;
  198. perout->period = (u32)period_ns;
  199. error = ravb_ptp_update_compare(priv, (u32)start_ns);
  200. if (!error) {
  201. /* Unmask interrupt */
  202. if (priv->chip_id == RCAR_GEN2)
  203. ravb_modify(ndev, GIC, GIC_PTME, GIC_PTME);
  204. else
  205. ravb_write(ndev, GIE_PTMS0, GIE);
  206. }
  207. } else {
  208. spin_lock_irqsave(&priv->lock, flags);
  209. perout = &priv->ptp.perout[req->index];
  210. perout->period = 0;
  211. /* Mask interrupt */
  212. if (priv->chip_id == RCAR_GEN2)
  213. ravb_modify(ndev, GIC, GIC_PTME, 0);
  214. else
  215. ravb_write(ndev, GID_PTMD0, GID);
  216. }
  217. mmiowb();
  218. spin_unlock_irqrestore(&priv->lock, flags);
  219. return error;
  220. }
  221. static int ravb_ptp_enable(struct ptp_clock_info *ptp,
  222. struct ptp_clock_request *req, int on)
  223. {
  224. switch (req->type) {
  225. case PTP_CLK_REQ_EXTTS:
  226. return ravb_ptp_extts(ptp, &req->extts, on);
  227. case PTP_CLK_REQ_PEROUT:
  228. return ravb_ptp_perout(ptp, &req->perout, on);
  229. default:
  230. return -EOPNOTSUPP;
  231. }
  232. }
  233. static const struct ptp_clock_info ravb_ptp_info = {
  234. .owner = THIS_MODULE,
  235. .name = "ravb clock",
  236. .max_adj = 50000000,
  237. .n_ext_ts = N_EXT_TS,
  238. .n_per_out = N_PER_OUT,
  239. .adjfreq = ravb_ptp_adjfreq,
  240. .adjtime = ravb_ptp_adjtime,
  241. .gettime64 = ravb_ptp_gettime64,
  242. .settime64 = ravb_ptp_settime64,
  243. .enable = ravb_ptp_enable,
  244. };
  245. /* Caller must hold the lock */
  246. void ravb_ptp_interrupt(struct net_device *ndev)
  247. {
  248. struct ravb_private *priv = netdev_priv(ndev);
  249. u32 gis = ravb_read(ndev, GIS);
  250. gis &= ravb_read(ndev, GIC);
  251. if (gis & GIS_PTCF) {
  252. struct ptp_clock_event event;
  253. event.type = PTP_CLOCK_EXTTS;
  254. event.index = 0;
  255. event.timestamp = ravb_read(ndev, GCPT);
  256. ptp_clock_event(priv->ptp.clock, &event);
  257. }
  258. if (gis & GIS_PTMF) {
  259. struct ravb_ptp_perout *perout = priv->ptp.perout;
  260. if (perout->period) {
  261. perout->target += perout->period;
  262. ravb_ptp_update_compare(priv, perout->target);
  263. }
  264. }
  265. ravb_write(ndev, ~gis, GIS);
  266. }
  267. void ravb_ptp_init(struct net_device *ndev, struct platform_device *pdev)
  268. {
  269. struct ravb_private *priv = netdev_priv(ndev);
  270. unsigned long flags;
  271. priv->ptp.info = ravb_ptp_info;
  272. priv->ptp.default_addend = ravb_read(ndev, GTI);
  273. priv->ptp.current_addend = priv->ptp.default_addend;
  274. spin_lock_irqsave(&priv->lock, flags);
  275. ravb_wait(ndev, GCCR, GCCR_TCR, GCCR_TCR_NOREQ);
  276. ravb_modify(ndev, GCCR, GCCR_TCSS, GCCR_TCSS_ADJGPTP);
  277. mmiowb();
  278. spin_unlock_irqrestore(&priv->lock, flags);
  279. priv->ptp.clock = ptp_clock_register(&priv->ptp.info, &pdev->dev);
  280. }
  281. void ravb_ptp_stop(struct net_device *ndev)
  282. {
  283. struct ravb_private *priv = netdev_priv(ndev);
  284. ravb_write(ndev, 0, GIC);
  285. ravb_write(ndev, 0, GIS);
  286. ptp_clock_unregister(priv->ptp.clock);
  287. }