ptp.c 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
  1. /*
  2. * Marvell 88E6xxx Switch PTP support
  3. *
  4. * Copyright (c) 2008 Marvell Semiconductor
  5. *
  6. * Copyright (c) 2017 National Instruments
  7. * Erik Hons <erik.hons@ni.com>
  8. * Brandon Streiff <brandon.streiff@ni.com>
  9. * Dane Wagner <dane.wagner@ni.com>
  10. *
  11. * This program is free software; you can redistribute it and/or modify
  12. * it under the terms of the GNU General Public License as published by
  13. * the Free Software Foundation; either version 2 of the License, or
  14. * (at your option) any later version.
  15. */
  16. #include "chip.h"
  17. #include "global2.h"
  18. #include "ptp.h"
  19. /* Raw timestamps are in units of 8-ns clock periods. */
  20. #define CC_SHIFT 28
  21. #define CC_MULT (8 << CC_SHIFT)
  22. #define CC_MULT_NUM (1 << 9)
  23. #define CC_MULT_DEM 15625ULL
  24. #define TAI_EVENT_WORK_INTERVAL msecs_to_jiffies(100)
  25. #define cc_to_chip(cc) container_of(cc, struct mv88e6xxx_chip, tstamp_cc)
  26. #define dw_overflow_to_chip(dw) container_of(dw, struct mv88e6xxx_chip, \
  27. overflow_work)
  28. #define dw_tai_event_to_chip(dw) container_of(dw, struct mv88e6xxx_chip, \
  29. tai_event_work)
  30. static int mv88e6xxx_tai_read(struct mv88e6xxx_chip *chip, int addr,
  31. u16 *data, int len)
  32. {
  33. if (!chip->info->ops->avb_ops->tai_read)
  34. return -EOPNOTSUPP;
  35. return chip->info->ops->avb_ops->tai_read(chip, addr, data, len);
  36. }
  37. static int mv88e6xxx_tai_write(struct mv88e6xxx_chip *chip, int addr, u16 data)
  38. {
  39. if (!chip->info->ops->avb_ops->tai_write)
  40. return -EOPNOTSUPP;
  41. return chip->info->ops->avb_ops->tai_write(chip, addr, data);
  42. }
  43. /* TODO: places where this are called should be using pinctrl */
  44. static int mv88e6xxx_set_gpio_func(struct mv88e6xxx_chip *chip, int pin,
  45. int func, int input)
  46. {
  47. int err;
  48. if (!chip->info->ops->gpio_ops)
  49. return -EOPNOTSUPP;
  50. err = chip->info->ops->gpio_ops->set_dir(chip, pin, input);
  51. if (err)
  52. return err;
  53. return chip->info->ops->gpio_ops->set_pctl(chip, pin, func);
  54. }
  55. static u64 mv88e6xxx_ptp_clock_read(const struct cyclecounter *cc)
  56. {
  57. struct mv88e6xxx_chip *chip = cc_to_chip(cc);
  58. u16 phc_time[2];
  59. int err;
  60. err = mv88e6xxx_tai_read(chip, MV88E6XXX_TAI_TIME_LO, phc_time,
  61. ARRAY_SIZE(phc_time));
  62. if (err)
  63. return 0;
  64. else
  65. return ((u32)phc_time[1] << 16) | phc_time[0];
  66. }
  67. /* mv88e6xxx_config_eventcap - configure TAI event capture
  68. * @event: PTP_CLOCK_PPS (internal) or PTP_CLOCK_EXTTS (external)
  69. * @rising: zero for falling-edge trigger, else rising-edge trigger
  70. *
  71. * This will also reset the capture sequence counter.
  72. */
  73. static int mv88e6xxx_config_eventcap(struct mv88e6xxx_chip *chip, int event,
  74. int rising)
  75. {
  76. u16 global_config;
  77. u16 cap_config;
  78. int err;
  79. chip->evcap_config = MV88E6XXX_TAI_CFG_CAP_OVERWRITE |
  80. MV88E6XXX_TAI_CFG_CAP_CTR_START;
  81. if (!rising)
  82. chip->evcap_config |= MV88E6XXX_TAI_CFG_EVREQ_FALLING;
  83. global_config = (chip->evcap_config | chip->trig_config);
  84. err = mv88e6xxx_tai_write(chip, MV88E6XXX_TAI_CFG, global_config);
  85. if (err)
  86. return err;
  87. if (event == PTP_CLOCK_PPS) {
  88. cap_config = MV88E6XXX_TAI_EVENT_STATUS_CAP_TRIG;
  89. } else if (event == PTP_CLOCK_EXTTS) {
  90. /* if STATUS_CAP_TRIG is unset we capture PTP_EVREQ events */
  91. cap_config = 0;
  92. } else {
  93. return -EINVAL;
  94. }
  95. /* Write the capture config; this also clears the capture counter */
  96. err = mv88e6xxx_tai_write(chip, MV88E6XXX_TAI_EVENT_STATUS,
  97. cap_config);
  98. return err;
  99. }
  100. static void mv88e6xxx_tai_event_work(struct work_struct *ugly)
  101. {
  102. struct delayed_work *dw = to_delayed_work(ugly);
  103. struct mv88e6xxx_chip *chip = dw_tai_event_to_chip(dw);
  104. struct ptp_clock_event ev;
  105. u16 status[4];
  106. u32 raw_ts;
  107. int err;
  108. mutex_lock(&chip->reg_lock);
  109. err = mv88e6xxx_tai_read(chip, MV88E6XXX_TAI_EVENT_STATUS,
  110. status, ARRAY_SIZE(status));
  111. mutex_unlock(&chip->reg_lock);
  112. if (err) {
  113. dev_err(chip->dev, "failed to read TAI status register\n");
  114. return;
  115. }
  116. if (status[0] & MV88E6XXX_TAI_EVENT_STATUS_ERROR) {
  117. dev_warn(chip->dev, "missed event capture\n");
  118. return;
  119. }
  120. if (!(status[0] & MV88E6XXX_TAI_EVENT_STATUS_VALID))
  121. goto out;
  122. raw_ts = ((u32)status[2] << 16) | status[1];
  123. /* Clear the valid bit so the next timestamp can come in */
  124. status[0] &= ~MV88E6XXX_TAI_EVENT_STATUS_VALID;
  125. mutex_lock(&chip->reg_lock);
  126. err = mv88e6xxx_tai_write(chip, MV88E6XXX_TAI_EVENT_STATUS, status[0]);
  127. mutex_unlock(&chip->reg_lock);
  128. /* This is an external timestamp */
  129. ev.type = PTP_CLOCK_EXTTS;
  130. /* We only have one timestamping channel. */
  131. ev.index = 0;
  132. mutex_lock(&chip->reg_lock);
  133. ev.timestamp = timecounter_cyc2time(&chip->tstamp_tc, raw_ts);
  134. mutex_unlock(&chip->reg_lock);
  135. ptp_clock_event(chip->ptp_clock, &ev);
  136. out:
  137. schedule_delayed_work(&chip->tai_event_work, TAI_EVENT_WORK_INTERVAL);
  138. }
  139. static int mv88e6xxx_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
  140. {
  141. struct mv88e6xxx_chip *chip = ptp_to_chip(ptp);
  142. int neg_adj = 0;
  143. u32 diff, mult;
  144. u64 adj;
  145. if (scaled_ppm < 0) {
  146. neg_adj = 1;
  147. scaled_ppm = -scaled_ppm;
  148. }
  149. mult = CC_MULT;
  150. adj = CC_MULT_NUM;
  151. adj *= scaled_ppm;
  152. diff = div_u64(adj, CC_MULT_DEM);
  153. mutex_lock(&chip->reg_lock);
  154. timecounter_read(&chip->tstamp_tc);
  155. chip->tstamp_cc.mult = neg_adj ? mult - diff : mult + diff;
  156. mutex_unlock(&chip->reg_lock);
  157. return 0;
  158. }
  159. static int mv88e6xxx_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
  160. {
  161. struct mv88e6xxx_chip *chip = ptp_to_chip(ptp);
  162. mutex_lock(&chip->reg_lock);
  163. timecounter_adjtime(&chip->tstamp_tc, delta);
  164. mutex_unlock(&chip->reg_lock);
  165. return 0;
  166. }
  167. static int mv88e6xxx_ptp_gettime(struct ptp_clock_info *ptp,
  168. struct timespec64 *ts)
  169. {
  170. struct mv88e6xxx_chip *chip = ptp_to_chip(ptp);
  171. u64 ns;
  172. mutex_lock(&chip->reg_lock);
  173. ns = timecounter_read(&chip->tstamp_tc);
  174. mutex_unlock(&chip->reg_lock);
  175. *ts = ns_to_timespec64(ns);
  176. return 0;
  177. }
  178. static int mv88e6xxx_ptp_settime(struct ptp_clock_info *ptp,
  179. const struct timespec64 *ts)
  180. {
  181. struct mv88e6xxx_chip *chip = ptp_to_chip(ptp);
  182. u64 ns;
  183. ns = timespec64_to_ns(ts);
  184. mutex_lock(&chip->reg_lock);
  185. timecounter_init(&chip->tstamp_tc, &chip->tstamp_cc, ns);
  186. mutex_unlock(&chip->reg_lock);
  187. return 0;
  188. }
  189. static int mv88e6xxx_ptp_enable_extts(struct mv88e6xxx_chip *chip,
  190. struct ptp_clock_request *rq, int on)
  191. {
  192. int rising = (rq->extts.flags & PTP_RISING_EDGE);
  193. int func;
  194. int pin;
  195. int err;
  196. pin = ptp_find_pin(chip->ptp_clock, PTP_PF_EXTTS, rq->extts.index);
  197. if (pin < 0)
  198. return -EBUSY;
  199. mutex_lock(&chip->reg_lock);
  200. if (on) {
  201. func = MV88E6352_G2_SCRATCH_GPIO_PCTL_EVREQ;
  202. err = mv88e6xxx_set_gpio_func(chip, pin, func, true);
  203. if (err)
  204. goto out;
  205. schedule_delayed_work(&chip->tai_event_work,
  206. TAI_EVENT_WORK_INTERVAL);
  207. err = mv88e6xxx_config_eventcap(chip, PTP_CLOCK_EXTTS, rising);
  208. } else {
  209. func = MV88E6352_G2_SCRATCH_GPIO_PCTL_GPIO;
  210. err = mv88e6xxx_set_gpio_func(chip, pin, func, true);
  211. cancel_delayed_work_sync(&chip->tai_event_work);
  212. }
  213. out:
  214. mutex_unlock(&chip->reg_lock);
  215. return err;
  216. }
  217. static int mv88e6xxx_ptp_enable(struct ptp_clock_info *ptp,
  218. struct ptp_clock_request *rq, int on)
  219. {
  220. struct mv88e6xxx_chip *chip = ptp_to_chip(ptp);
  221. switch (rq->type) {
  222. case PTP_CLK_REQ_EXTTS:
  223. return mv88e6xxx_ptp_enable_extts(chip, rq, on);
  224. default:
  225. return -EOPNOTSUPP;
  226. }
  227. }
  228. static int mv88e6xxx_ptp_verify(struct ptp_clock_info *ptp, unsigned int pin,
  229. enum ptp_pin_function func, unsigned int chan)
  230. {
  231. switch (func) {
  232. case PTP_PF_NONE:
  233. case PTP_PF_EXTTS:
  234. break;
  235. case PTP_PF_PEROUT:
  236. case PTP_PF_PHYSYNC:
  237. return -EOPNOTSUPP;
  238. }
  239. return 0;
  240. }
  241. /* With a 125MHz input clock, the 32-bit timestamp counter overflows in ~34.3
  242. * seconds; this task forces periodic reads so that we don't miss any.
  243. */
  244. #define MV88E6XXX_TAI_OVERFLOW_PERIOD (HZ * 16)
  245. static void mv88e6xxx_ptp_overflow_check(struct work_struct *work)
  246. {
  247. struct delayed_work *dw = to_delayed_work(work);
  248. struct mv88e6xxx_chip *chip = dw_overflow_to_chip(dw);
  249. struct timespec64 ts;
  250. mv88e6xxx_ptp_gettime(&chip->ptp_clock_info, &ts);
  251. schedule_delayed_work(&chip->overflow_work,
  252. MV88E6XXX_TAI_OVERFLOW_PERIOD);
  253. }
  254. int mv88e6xxx_ptp_setup(struct mv88e6xxx_chip *chip)
  255. {
  256. int i;
  257. /* Set up the cycle counter */
  258. memset(&chip->tstamp_cc, 0, sizeof(chip->tstamp_cc));
  259. chip->tstamp_cc.read = mv88e6xxx_ptp_clock_read;
  260. chip->tstamp_cc.mask = CYCLECOUNTER_MASK(32);
  261. chip->tstamp_cc.mult = CC_MULT;
  262. chip->tstamp_cc.shift = CC_SHIFT;
  263. timecounter_init(&chip->tstamp_tc, &chip->tstamp_cc,
  264. ktime_to_ns(ktime_get_real()));
  265. INIT_DELAYED_WORK(&chip->overflow_work, mv88e6xxx_ptp_overflow_check);
  266. INIT_DELAYED_WORK(&chip->tai_event_work, mv88e6xxx_tai_event_work);
  267. chip->ptp_clock_info.owner = THIS_MODULE;
  268. snprintf(chip->ptp_clock_info.name, sizeof(chip->ptp_clock_info.name),
  269. dev_name(chip->dev));
  270. chip->ptp_clock_info.max_adj = 1000000;
  271. chip->ptp_clock_info.n_ext_ts = 1;
  272. chip->ptp_clock_info.n_per_out = 0;
  273. chip->ptp_clock_info.n_pins = mv88e6xxx_num_gpio(chip);
  274. chip->ptp_clock_info.pps = 0;
  275. for (i = 0; i < chip->ptp_clock_info.n_pins; ++i) {
  276. struct ptp_pin_desc *ppd = &chip->pin_config[i];
  277. snprintf(ppd->name, sizeof(ppd->name), "mv88e6xxx_gpio%d", i);
  278. ppd->index = i;
  279. ppd->func = PTP_PF_NONE;
  280. }
  281. chip->ptp_clock_info.pin_config = chip->pin_config;
  282. chip->ptp_clock_info.adjfine = mv88e6xxx_ptp_adjfine;
  283. chip->ptp_clock_info.adjtime = mv88e6xxx_ptp_adjtime;
  284. chip->ptp_clock_info.gettime64 = mv88e6xxx_ptp_gettime;
  285. chip->ptp_clock_info.settime64 = mv88e6xxx_ptp_settime;
  286. chip->ptp_clock_info.enable = mv88e6xxx_ptp_enable;
  287. chip->ptp_clock_info.verify = mv88e6xxx_ptp_verify;
  288. chip->ptp_clock_info.do_aux_work = mv88e6xxx_hwtstamp_work;
  289. chip->ptp_clock = ptp_clock_register(&chip->ptp_clock_info, chip->dev);
  290. if (IS_ERR(chip->ptp_clock))
  291. return PTR_ERR(chip->ptp_clock);
  292. schedule_delayed_work(&chip->overflow_work,
  293. MV88E6XXX_TAI_OVERFLOW_PERIOD);
  294. return 0;
  295. }
  296. void mv88e6xxx_ptp_free(struct mv88e6xxx_chip *chip)
  297. {
  298. if (chip->ptp_clock) {
  299. cancel_delayed_work_sync(&chip->overflow_work);
  300. cancel_delayed_work_sync(&chip->tai_event_work);
  301. ptp_clock_unregister(chip->ptp_clock);
  302. chip->ptp_clock = NULL;
  303. }
  304. }