microchip_rds_ptp.c 33 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330
  1. // SPDX-License-Identifier: GPL-2.0
  2. // Copyright (C) 2024 Microchip Technology
  3. #include "microchip_rds_ptp.h"
  4. static int mchp_rds_phy_read_mmd(struct mchp_rds_ptp_clock *clock,
  5. u32 offset, enum mchp_rds_ptp_base base)
  6. {
  7. struct phy_device *phydev = clock->phydev;
  8. u32 addr;
  9. addr = (offset + ((base == MCHP_RDS_PTP_PORT) ? BASE_PORT(clock) :
  10. BASE_CLK(clock)));
  11. return phy_read_mmd(phydev, PTP_MMD(clock), addr);
  12. }
  13. static int mchp_rds_phy_write_mmd(struct mchp_rds_ptp_clock *clock,
  14. u32 offset, enum mchp_rds_ptp_base base,
  15. u16 val)
  16. {
  17. struct phy_device *phydev = clock->phydev;
  18. u32 addr;
  19. addr = (offset + ((base == MCHP_RDS_PTP_PORT) ? BASE_PORT(clock) :
  20. BASE_CLK(clock)));
  21. return phy_write_mmd(phydev, PTP_MMD(clock), addr, val);
  22. }
  23. static int mchp_rds_phy_modify_mmd(struct mchp_rds_ptp_clock *clock,
  24. u32 offset, enum mchp_rds_ptp_base base,
  25. u16 mask, u16 val)
  26. {
  27. struct phy_device *phydev = clock->phydev;
  28. u32 addr;
  29. addr = (offset + ((base == MCHP_RDS_PTP_PORT) ? BASE_PORT(clock) :
  30. BASE_CLK(clock)));
  31. return phy_modify_mmd(phydev, PTP_MMD(clock), addr, mask, val);
  32. }
  33. static int mchp_rds_phy_set_bits_mmd(struct mchp_rds_ptp_clock *clock,
  34. u32 offset, enum mchp_rds_ptp_base base,
  35. u16 val)
  36. {
  37. struct phy_device *phydev = clock->phydev;
  38. u32 addr;
  39. addr = (offset + ((base == MCHP_RDS_PTP_PORT) ? BASE_PORT(clock) :
  40. BASE_CLK(clock)));
  41. return phy_set_bits_mmd(phydev, PTP_MMD(clock), addr, val);
  42. }
  43. static int mchp_get_pulsewidth(struct phy_device *phydev,
  44. struct ptp_perout_request *perout_request,
  45. int *pulse_width)
  46. {
  47. struct timespec64 ts_period;
  48. s64 ts_on_nsec, period_nsec;
  49. struct timespec64 ts_on;
  50. static const s64 sup_on_necs[] = {
  51. 100, /* 100ns */
  52. 500, /* 500ns */
  53. 1000, /* 1us */
  54. 5000, /* 5us */
  55. 10000, /* 10us */
  56. 50000, /* 50us */
  57. 100000, /* 100us */
  58. 500000, /* 500us */
  59. 1000000, /* 1ms */
  60. 5000000, /* 5ms */
  61. 10000000, /* 10ms */
  62. 50000000, /* 50ms */
  63. 100000000, /* 100ms */
  64. 200000000, /* 200ms */
  65. };
  66. ts_period.tv_sec = perout_request->period.sec;
  67. ts_period.tv_nsec = perout_request->period.nsec;
  68. ts_on.tv_sec = perout_request->on.sec;
  69. ts_on.tv_nsec = perout_request->on.nsec;
  70. ts_on_nsec = timespec64_to_ns(&ts_on);
  71. period_nsec = timespec64_to_ns(&ts_period);
  72. if (period_nsec < 200) {
  73. phydev_warn(phydev, "perout period small, minimum is 200ns\n");
  74. return -EOPNOTSUPP;
  75. }
  76. for (int i = 0; i < ARRAY_SIZE(sup_on_necs); i++) {
  77. if (ts_on_nsec <= sup_on_necs[i]) {
  78. *pulse_width = i;
  79. break;
  80. }
  81. }
  82. phydev_info(phydev, "pulse width is %d\n", *pulse_width);
  83. return 0;
  84. }
  85. static int mchp_general_event_config(struct mchp_rds_ptp_clock *clock,
  86. int pulse_width)
  87. {
  88. int general_config;
  89. general_config = mchp_rds_phy_read_mmd(clock, MCHP_RDS_PTP_GEN_CFG,
  90. MCHP_RDS_PTP_CLOCK);
  91. if (general_config < 0)
  92. return general_config;
  93. general_config &= ~MCHP_RDS_PTP_GEN_CFG_LTC_EVT_MASK;
  94. general_config |= MCHP_RDS_PTP_GEN_CFG_LTC_EVT_SET(pulse_width);
  95. general_config &= ~MCHP_RDS_PTP_GEN_CFG_RELOAD_ADD;
  96. general_config |= MCHP_RDS_PTP_GEN_CFG_POLARITY;
  97. return mchp_rds_phy_write_mmd(clock, MCHP_RDS_PTP_GEN_CFG,
  98. MCHP_RDS_PTP_CLOCK, general_config);
  99. }
  100. static int mchp_set_clock_reload(struct mchp_rds_ptp_clock *clock,
  101. s64 period_sec, u32 period_nsec)
  102. {
  103. int rc;
  104. rc = mchp_rds_phy_write_mmd(clock,
  105. MCHP_RDS_PTP_CLK_TRGT_RELOAD_SEC_LO,
  106. MCHP_RDS_PTP_CLOCK,
  107. lower_16_bits(period_sec));
  108. if (rc < 0)
  109. return rc;
  110. rc = mchp_rds_phy_write_mmd(clock,
  111. MCHP_RDS_PTP_CLK_TRGT_RELOAD_SEC_HI,
  112. MCHP_RDS_PTP_CLOCK,
  113. upper_16_bits(period_sec));
  114. if (rc < 0)
  115. return rc;
  116. rc = mchp_rds_phy_write_mmd(clock,
  117. MCHP_RDS_PTP_CLK_TRGT_RELOAD_NS_LO,
  118. MCHP_RDS_PTP_CLOCK,
  119. lower_16_bits(period_nsec));
  120. if (rc < 0)
  121. return rc;
  122. return mchp_rds_phy_write_mmd(clock,
  123. MCHP_RDS_PTP_CLK_TRGT_RELOAD_NS_HI,
  124. MCHP_RDS_PTP_CLOCK,
  125. upper_16_bits(period_nsec) & 0x3fff);
  126. }
  127. static int mchp_set_clock_target(struct mchp_rds_ptp_clock *clock,
  128. s64 start_sec, u32 start_nsec)
  129. {
  130. int rc;
  131. /* Set the start time */
  132. rc = mchp_rds_phy_write_mmd(clock, MCHP_RDS_PTP_CLK_TRGT_SEC_LO,
  133. MCHP_RDS_PTP_CLOCK,
  134. lower_16_bits(start_sec));
  135. if (rc < 0)
  136. return rc;
  137. rc = mchp_rds_phy_write_mmd(clock, MCHP_RDS_PTP_CLK_TRGT_SEC_HI,
  138. MCHP_RDS_PTP_CLOCK,
  139. upper_16_bits(start_sec));
  140. if (rc < 0)
  141. return rc;
  142. rc = mchp_rds_phy_write_mmd(clock, MCHP_RDS_PTP_CLK_TRGT_NS_LO,
  143. MCHP_RDS_PTP_CLOCK,
  144. lower_16_bits(start_nsec));
  145. if (rc < 0)
  146. return rc;
  147. return mchp_rds_phy_write_mmd(clock, MCHP_RDS_PTP_CLK_TRGT_NS_HI,
  148. MCHP_RDS_PTP_CLOCK,
  149. upper_16_bits(start_nsec) & 0x3fff);
  150. }
  151. static int mchp_rds_ptp_perout_off(struct mchp_rds_ptp_clock *clock)
  152. {
  153. u16 general_config;
  154. int rc;
  155. /* Set target to too far in the future, effectively disabling it */
  156. rc = mchp_set_clock_target(clock, 0xFFFFFFFF, 0);
  157. if (rc < 0)
  158. return rc;
  159. general_config = mchp_rds_phy_read_mmd(clock, MCHP_RDS_PTP_GEN_CFG,
  160. MCHP_RDS_PTP_CLOCK);
  161. general_config |= MCHP_RDS_PTP_GEN_CFG_RELOAD_ADD;
  162. rc = mchp_rds_phy_write_mmd(clock, MCHP_RDS_PTP_GEN_CFG,
  163. MCHP_RDS_PTP_CLOCK, general_config);
  164. if (rc < 0)
  165. return rc;
  166. clock->mchp_rds_ptp_event = -1;
  167. return 0;
  168. }
  169. static bool mchp_get_event(struct mchp_rds_ptp_clock *clock, int pin)
  170. {
  171. if (clock->mchp_rds_ptp_event < 0 && pin == clock->event_pin) {
  172. clock->mchp_rds_ptp_event = pin;
  173. return true;
  174. }
  175. return false;
  176. }
  177. static int mchp_rds_ptp_perout(struct ptp_clock_info *ptpci,
  178. struct ptp_perout_request *perout, int on)
  179. {
  180. struct mchp_rds_ptp_clock *clock = container_of(ptpci,
  181. struct mchp_rds_ptp_clock,
  182. caps);
  183. struct phy_device *phydev = clock->phydev;
  184. int ret, event_pin, pulsewidth;
  185. event_pin = ptp_find_pin(clock->ptp_clock, PTP_PF_PEROUT,
  186. perout->index);
  187. if (event_pin != clock->event_pin)
  188. return -EINVAL;
  189. if (!on) {
  190. ret = mchp_rds_ptp_perout_off(clock);
  191. return ret;
  192. }
  193. if (!mchp_get_event(clock, event_pin))
  194. return -EINVAL;
  195. ret = mchp_get_pulsewidth(phydev, perout, &pulsewidth);
  196. if (ret < 0)
  197. return ret;
  198. /* Configure to pulse every period */
  199. ret = mchp_general_event_config(clock, pulsewidth);
  200. if (ret < 0)
  201. return ret;
  202. ret = mchp_set_clock_target(clock, perout->start.sec,
  203. perout->start.nsec);
  204. if (ret < 0)
  205. return ret;
  206. return mchp_set_clock_reload(clock, perout->period.sec,
  207. perout->period.nsec);
  208. }
  209. static int mchp_rds_ptpci_enable(struct ptp_clock_info *ptpci,
  210. struct ptp_clock_request *request, int on)
  211. {
  212. switch (request->type) {
  213. case PTP_CLK_REQ_PEROUT:
  214. return mchp_rds_ptp_perout(ptpci, &request->perout, on);
  215. default:
  216. return -EINVAL;
  217. }
  218. }
  219. static int mchp_rds_ptpci_verify(struct ptp_clock_info *ptpci, unsigned int pin,
  220. enum ptp_pin_function func, unsigned int chan)
  221. {
  222. struct mchp_rds_ptp_clock *clock = container_of(ptpci,
  223. struct mchp_rds_ptp_clock,
  224. caps);
  225. if (!(pin == clock->event_pin && chan == 0))
  226. return -1;
  227. switch (func) {
  228. case PTP_PF_NONE:
  229. case PTP_PF_PEROUT:
  230. break;
  231. default:
  232. return -1;
  233. }
  234. return 0;
  235. }
  236. static int mchp_rds_ptp_flush_fifo(struct mchp_rds_ptp_clock *clock,
  237. enum mchp_rds_ptp_fifo_dir dir)
  238. {
  239. int rc;
  240. if (dir == MCHP_RDS_PTP_EGRESS_FIFO)
  241. skb_queue_purge(&clock->tx_queue);
  242. else
  243. skb_queue_purge(&clock->rx_queue);
  244. for (int i = 0; i < MCHP_RDS_PTP_FIFO_SIZE; ++i) {
  245. rc = mchp_rds_phy_read_mmd(clock,
  246. dir == MCHP_RDS_PTP_EGRESS_FIFO ?
  247. MCHP_RDS_PTP_TX_MSG_HDR2 :
  248. MCHP_RDS_PTP_RX_MSG_HDR2,
  249. MCHP_RDS_PTP_PORT);
  250. if (rc < 0)
  251. return rc;
  252. }
  253. return mchp_rds_phy_read_mmd(clock, MCHP_RDS_PTP_INT_STS,
  254. MCHP_RDS_PTP_PORT);
  255. }
  256. static int mchp_rds_ptp_config_intr(struct mchp_rds_ptp_clock *clock,
  257. bool enable)
  258. {
  259. /* Enable or disable ptp interrupts */
  260. return mchp_rds_phy_write_mmd(clock, MCHP_RDS_PTP_INT_EN,
  261. MCHP_RDS_PTP_PORT,
  262. enable ? MCHP_RDS_PTP_INT_ALL_MSK : 0);
  263. }
  264. static void mchp_rds_ptp_txtstamp(struct mii_timestamper *mii_ts,
  265. struct sk_buff *skb, int type)
  266. {
  267. struct mchp_rds_ptp_clock *clock = container_of(mii_ts,
  268. struct mchp_rds_ptp_clock,
  269. mii_ts);
  270. switch (clock->hwts_tx_type) {
  271. case HWTSTAMP_TX_ONESTEP_SYNC:
  272. if (ptp_msg_is_sync(skb, type)) {
  273. kfree_skb(skb);
  274. return;
  275. }
  276. fallthrough;
  277. case HWTSTAMP_TX_ON:
  278. skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
  279. skb_queue_tail(&clock->tx_queue, skb);
  280. break;
  281. case HWTSTAMP_TX_OFF:
  282. default:
  283. kfree_skb(skb);
  284. break;
  285. }
  286. }
  287. static bool mchp_rds_ptp_get_sig_rx(struct sk_buff *skb, u16 *sig)
  288. {
  289. struct ptp_header *ptp_header;
  290. int type;
  291. skb_push(skb, ETH_HLEN);
  292. type = ptp_classify_raw(skb);
  293. if (type == PTP_CLASS_NONE)
  294. return false;
  295. ptp_header = ptp_parse_header(skb, type);
  296. if (!ptp_header)
  297. return false;
  298. skb_pull_inline(skb, ETH_HLEN);
  299. *sig = (__force u16)(ntohs(ptp_header->sequence_id));
  300. return true;
  301. }
  302. static bool mchp_rds_ptp_match_skb(struct mchp_rds_ptp_clock *clock,
  303. struct mchp_rds_ptp_rx_ts *rx_ts)
  304. {
  305. struct skb_shared_hwtstamps *shhwtstamps;
  306. struct sk_buff *skb, *skb_tmp;
  307. unsigned long flags;
  308. bool rc = false;
  309. u16 skb_sig;
  310. spin_lock_irqsave(&clock->rx_queue.lock, flags);
  311. skb_queue_walk_safe(&clock->rx_queue, skb, skb_tmp) {
  312. if (!mchp_rds_ptp_get_sig_rx(skb, &skb_sig))
  313. continue;
  314. if (skb_sig != rx_ts->seq_id)
  315. continue;
  316. __skb_unlink(skb, &clock->rx_queue);
  317. rc = true;
  318. break;
  319. }
  320. spin_unlock_irqrestore(&clock->rx_queue.lock, flags);
  321. if (rc) {
  322. shhwtstamps = skb_hwtstamps(skb);
  323. shhwtstamps->hwtstamp = ktime_set(rx_ts->seconds, rx_ts->nsec);
  324. netif_rx(skb);
  325. }
  326. return rc;
  327. }
  328. static void mchp_rds_ptp_match_rx_ts(struct mchp_rds_ptp_clock *clock,
  329. struct mchp_rds_ptp_rx_ts *rx_ts)
  330. {
  331. unsigned long flags;
  332. /* If we failed to match the skb add it to the queue for when
  333. * the frame will come
  334. */
  335. if (!mchp_rds_ptp_match_skb(clock, rx_ts)) {
  336. spin_lock_irqsave(&clock->rx_ts_lock, flags);
  337. list_add(&rx_ts->list, &clock->rx_ts_list);
  338. spin_unlock_irqrestore(&clock->rx_ts_lock, flags);
  339. } else {
  340. kfree(rx_ts);
  341. }
  342. }
  343. static void mchp_rds_ptp_match_rx_skb(struct mchp_rds_ptp_clock *clock,
  344. struct sk_buff *skb)
  345. {
  346. struct mchp_rds_ptp_rx_ts *rx_ts, *tmp, *rx_ts_var = NULL;
  347. struct skb_shared_hwtstamps *shhwtstamps;
  348. unsigned long flags;
  349. u16 skb_sig;
  350. if (!mchp_rds_ptp_get_sig_rx(skb, &skb_sig))
  351. return;
  352. /* Iterate over all RX timestamps and match it with the received skbs */
  353. spin_lock_irqsave(&clock->rx_ts_lock, flags);
  354. list_for_each_entry_safe(rx_ts, tmp, &clock->rx_ts_list, list) {
  355. /* Check if we found the signature we were looking for. */
  356. if (skb_sig != rx_ts->seq_id)
  357. continue;
  358. shhwtstamps = skb_hwtstamps(skb);
  359. shhwtstamps->hwtstamp = ktime_set(rx_ts->seconds, rx_ts->nsec);
  360. netif_rx(skb);
  361. rx_ts_var = rx_ts;
  362. break;
  363. }
  364. spin_unlock_irqrestore(&clock->rx_ts_lock, flags);
  365. if (rx_ts_var) {
  366. list_del(&rx_ts_var->list);
  367. kfree(rx_ts_var);
  368. } else {
  369. skb_queue_tail(&clock->rx_queue, skb);
  370. }
  371. }
  372. static bool mchp_rds_ptp_rxtstamp(struct mii_timestamper *mii_ts,
  373. struct sk_buff *skb, int type)
  374. {
  375. struct mchp_rds_ptp_clock *clock = container_of(mii_ts,
  376. struct mchp_rds_ptp_clock,
  377. mii_ts);
  378. if (clock->rx_filter == HWTSTAMP_FILTER_NONE ||
  379. type == PTP_CLASS_NONE)
  380. return false;
  381. if ((type & clock->version) == 0 || (type & clock->layer) == 0)
  382. return false;
  383. /* Here if match occurs skb is sent to application, If not skb is added
  384. * to queue and sending skb to application will get handled when
  385. * interrupt occurs i.e., it get handles in interrupt handler. By
  386. * any means skb will reach the application so we should not return
  387. * false here if skb doesn't matches.
  388. */
  389. mchp_rds_ptp_match_rx_skb(clock, skb);
  390. return true;
  391. }
  392. static int mchp_rds_ptp_hwtstamp_get(struct mii_timestamper *mii_ts,
  393. struct kernel_hwtstamp_config *config)
  394. {
  395. struct mchp_rds_ptp_clock *clock =
  396. container_of(mii_ts, struct mchp_rds_ptp_clock,
  397. mii_ts);
  398. config->tx_type = clock->hwts_tx_type;
  399. config->rx_filter = clock->rx_filter;
  400. return 0;
  401. }
  402. static int mchp_rds_ptp_hwtstamp_set(struct mii_timestamper *mii_ts,
  403. struct kernel_hwtstamp_config *config,
  404. struct netlink_ext_ack *extack)
  405. {
  406. struct mchp_rds_ptp_clock *clock =
  407. container_of(mii_ts, struct mchp_rds_ptp_clock,
  408. mii_ts);
  409. struct mchp_rds_ptp_rx_ts *rx_ts, *tmp;
  410. int txcfg = 0, rxcfg = 0;
  411. unsigned long flags;
  412. int rc;
  413. switch (config->rx_filter) {
  414. case HWTSTAMP_FILTER_NONE:
  415. clock->layer = 0;
  416. clock->version = 0;
  417. break;
  418. case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
  419. case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
  420. case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
  421. clock->layer = PTP_CLASS_L4;
  422. clock->version = PTP_CLASS_V2;
  423. break;
  424. case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
  425. case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
  426. case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
  427. clock->layer = PTP_CLASS_L2;
  428. clock->version = PTP_CLASS_V2;
  429. break;
  430. case HWTSTAMP_FILTER_PTP_V2_EVENT:
  431. case HWTSTAMP_FILTER_PTP_V2_SYNC:
  432. case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
  433. clock->layer = PTP_CLASS_L4 | PTP_CLASS_L2;
  434. clock->version = PTP_CLASS_V2;
  435. break;
  436. default:
  437. return -ERANGE;
  438. }
  439. switch (config->tx_type) {
  440. case HWTSTAMP_TX_ONESTEP_SYNC:
  441. case HWTSTAMP_TX_ON:
  442. case HWTSTAMP_TX_OFF:
  443. break;
  444. default:
  445. return -ERANGE;
  446. }
  447. /* Setup parsing of the frames and enable the timestamping for ptp
  448. * frames
  449. */
  450. if (clock->layer & PTP_CLASS_L2) {
  451. rxcfg = MCHP_RDS_PTP_PARSE_CONFIG_LAYER2_EN;
  452. txcfg = MCHP_RDS_PTP_PARSE_CONFIG_LAYER2_EN;
  453. }
  454. if (clock->layer & PTP_CLASS_L4) {
  455. rxcfg |= MCHP_RDS_PTP_PARSE_CONFIG_IPV4_EN |
  456. MCHP_RDS_PTP_PARSE_CONFIG_IPV6_EN;
  457. txcfg |= MCHP_RDS_PTP_PARSE_CONFIG_IPV4_EN |
  458. MCHP_RDS_PTP_PARSE_CONFIG_IPV6_EN;
  459. }
  460. rc = mchp_rds_phy_write_mmd(clock, MCHP_RDS_PTP_RX_PARSE_CONFIG,
  461. MCHP_RDS_PTP_PORT, rxcfg);
  462. if (rc < 0)
  463. return rc;
  464. rc = mchp_rds_phy_write_mmd(clock, MCHP_RDS_PTP_TX_PARSE_CONFIG,
  465. MCHP_RDS_PTP_PORT, txcfg);
  466. if (rc < 0)
  467. return rc;
  468. rc = mchp_rds_phy_write_mmd(clock, MCHP_RDS_PTP_RX_TIMESTAMP_EN,
  469. MCHP_RDS_PTP_PORT,
  470. MCHP_RDS_PTP_TIMESTAMP_EN_ALL);
  471. if (rc < 0)
  472. return rc;
  473. rc = mchp_rds_phy_write_mmd(clock, MCHP_RDS_PTP_TX_TIMESTAMP_EN,
  474. MCHP_RDS_PTP_PORT,
  475. MCHP_RDS_PTP_TIMESTAMP_EN_ALL);
  476. if (rc < 0)
  477. return rc;
  478. if (config->tx_type == HWTSTAMP_TX_ONESTEP_SYNC)
  479. /* Enable / disable of the TX timestamp in the SYNC frames */
  480. rc = mchp_rds_phy_modify_mmd(clock, MCHP_RDS_PTP_TX_MOD,
  481. MCHP_RDS_PTP_PORT,
  482. MCHP_RDS_TX_MOD_PTP_SYNC_TS_INSERT,
  483. MCHP_RDS_TX_MOD_PTP_SYNC_TS_INSERT);
  484. else
  485. rc = mchp_rds_phy_modify_mmd(clock, MCHP_RDS_PTP_TX_MOD,
  486. MCHP_RDS_PTP_PORT,
  487. MCHP_RDS_TX_MOD_PTP_SYNC_TS_INSERT,
  488. (u16)~MCHP_RDS_TX_MOD_PTP_SYNC_TS_INSERT);
  489. if (rc < 0)
  490. return rc;
  491. /* In case of multiple starts and stops, these needs to be cleared */
  492. spin_lock_irqsave(&clock->rx_ts_lock, flags);
  493. list_for_each_entry_safe(rx_ts, tmp, &clock->rx_ts_list, list) {
  494. list_del(&rx_ts->list);
  495. kfree(rx_ts);
  496. }
  497. spin_unlock_irqrestore(&clock->rx_ts_lock, flags);
  498. rc = mchp_rds_ptp_flush_fifo(clock, MCHP_RDS_PTP_INGRESS_FIFO);
  499. if (rc < 0)
  500. return rc;
  501. rc = mchp_rds_ptp_flush_fifo(clock, MCHP_RDS_PTP_EGRESS_FIFO);
  502. if (rc < 0)
  503. return rc;
  504. /* Now enable the timestamping interrupts */
  505. rc = mchp_rds_ptp_config_intr(clock,
  506. config->rx_filter != HWTSTAMP_FILTER_NONE);
  507. if (rc < 0)
  508. return rc;
  509. clock->hwts_tx_type = config->tx_type;
  510. clock->rx_filter = config->rx_filter;
  511. return 0;
  512. }
  513. static int mchp_rds_ptp_ts_info(struct mii_timestamper *mii_ts,
  514. struct kernel_ethtool_ts_info *info)
  515. {
  516. struct mchp_rds_ptp_clock *clock = container_of(mii_ts,
  517. struct mchp_rds_ptp_clock,
  518. mii_ts);
  519. info->phc_index = ptp_clock_index(clock->ptp_clock);
  520. info->so_timestamping = SOF_TIMESTAMPING_TX_HARDWARE |
  521. SOF_TIMESTAMPING_RX_HARDWARE |
  522. SOF_TIMESTAMPING_RAW_HARDWARE;
  523. info->tx_types = BIT(HWTSTAMP_TX_OFF) | BIT(HWTSTAMP_TX_ON) |
  524. BIT(HWTSTAMP_TX_ONESTEP_SYNC);
  525. info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) |
  526. BIT(HWTSTAMP_FILTER_PTP_V2_L4_EVENT) |
  527. BIT(HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
  528. BIT(HWTSTAMP_FILTER_PTP_V2_EVENT);
  529. return 0;
  530. }
  531. static int mchp_rds_ptp_ltc_adjtime(struct ptp_clock_info *info, s64 delta)
  532. {
  533. struct mchp_rds_ptp_clock *clock = container_of(info,
  534. struct mchp_rds_ptp_clock,
  535. caps);
  536. struct timespec64 ts;
  537. bool add = true;
  538. int rc = 0;
  539. u32 nsec;
  540. s32 sec;
  541. /* The HW allows up to 15 sec to adjust the time, but here we limit to
  542. * 10 sec the adjustment. The reason is, in case the adjustment is 14
  543. * sec and 999999999 nsec, then we add 8ns to compensate the actual
  544. * increment so the value can be bigger than 15 sec. Therefore limit the
  545. * possible adjustments so we will not have these corner cases
  546. */
  547. if (delta > 10000000000LL || delta < -10000000000LL) {
  548. /* The timeadjustment is too big, so fall back using set time */
  549. u64 now;
  550. info->gettime64(info, &ts);
  551. now = ktime_to_ns(timespec64_to_ktime(ts));
  552. ts = ns_to_timespec64(now + delta);
  553. info->settime64(info, &ts);
  554. return 0;
  555. }
  556. sec = div_u64_rem(abs(delta), NSEC_PER_SEC, &nsec);
  557. if (delta < 0 && nsec != 0) {
  558. /* It is not allowed to adjust low the nsec part, therefore
  559. * subtract more from second part and add to nanosecond such
  560. * that would roll over, so the second part will increase
  561. */
  562. sec--;
  563. nsec = NSEC_PER_SEC - nsec;
  564. }
  565. /* Calculate the adjustments and the direction */
  566. if (delta < 0)
  567. add = false;
  568. if (nsec > 0) {
  569. /* add 8 ns to cover the likely normal increment */
  570. nsec += 8;
  571. if (nsec >= NSEC_PER_SEC) {
  572. /* carry into seconds */
  573. sec++;
  574. nsec -= NSEC_PER_SEC;
  575. }
  576. }
  577. mutex_lock(&clock->ptp_lock);
  578. if (sec) {
  579. sec = abs(sec);
  580. rc = mchp_rds_phy_write_mmd(clock, MCHP_RDS_PTP_STEP_ADJ_LO,
  581. MCHP_RDS_PTP_CLOCK, sec);
  582. if (rc < 0)
  583. goto out_unlock;
  584. rc = mchp_rds_phy_set_bits_mmd(clock, MCHP_RDS_PTP_STEP_ADJ_HI,
  585. MCHP_RDS_PTP_CLOCK,
  586. ((add ?
  587. MCHP_RDS_PTP_STEP_ADJ_HI_DIR :
  588. 0) | ((sec >> 16) &
  589. GENMASK(13, 0))));
  590. if (rc < 0)
  591. goto out_unlock;
  592. rc = mchp_rds_phy_set_bits_mmd(clock, MCHP_RDS_PTP_CMD_CTL,
  593. MCHP_RDS_PTP_CLOCK,
  594. MCHP_RDS_PTP_CMD_CTL_LTC_STEP_SEC);
  595. if (rc < 0)
  596. goto out_unlock;
  597. }
  598. if (nsec) {
  599. rc = mchp_rds_phy_write_mmd(clock, MCHP_RDS_PTP_STEP_ADJ_LO,
  600. MCHP_RDS_PTP_CLOCK,
  601. nsec & GENMASK(15, 0));
  602. if (rc < 0)
  603. goto out_unlock;
  604. rc = mchp_rds_phy_write_mmd(clock, MCHP_RDS_PTP_STEP_ADJ_HI,
  605. MCHP_RDS_PTP_CLOCK,
  606. (nsec >> 16) & GENMASK(13, 0));
  607. if (rc < 0)
  608. goto out_unlock;
  609. rc = mchp_rds_phy_set_bits_mmd(clock, MCHP_RDS_PTP_CMD_CTL,
  610. MCHP_RDS_PTP_CLOCK,
  611. MCHP_RDS_PTP_CMD_CTL_LTC_STEP_NSEC);
  612. }
  613. mutex_unlock(&clock->ptp_lock);
  614. info->gettime64(info, &ts);
  615. mutex_lock(&clock->ptp_lock);
  616. /* Target update is required for pulse generation on events that
  617. * are enabled
  618. */
  619. if (clock->mchp_rds_ptp_event >= 0)
  620. mchp_set_clock_target(clock,
  621. ts.tv_sec + MCHP_RDS_PTP_BUFFER_TIME, 0);
  622. out_unlock:
  623. mutex_unlock(&clock->ptp_lock);
  624. return rc;
  625. }
  626. static int mchp_rds_ptp_ltc_adjfine(struct ptp_clock_info *info,
  627. long scaled_ppm)
  628. {
  629. struct mchp_rds_ptp_clock *clock = container_of(info,
  630. struct mchp_rds_ptp_clock,
  631. caps);
  632. u16 rate_lo, rate_hi;
  633. bool faster = true;
  634. u32 rate;
  635. int rc;
  636. if (!scaled_ppm)
  637. return 0;
  638. if (scaled_ppm < 0) {
  639. scaled_ppm = -scaled_ppm;
  640. faster = false;
  641. }
  642. rate = MCHP_RDS_PTP_1PPM_FORMAT * (upper_16_bits(scaled_ppm));
  643. rate += (MCHP_RDS_PTP_1PPM_FORMAT * (lower_16_bits(scaled_ppm))) >> 16;
  644. rate_lo = rate & GENMASK(15, 0);
  645. rate_hi = (rate >> 16) & GENMASK(13, 0);
  646. if (faster)
  647. rate_hi |= MCHP_RDS_PTP_LTC_RATE_ADJ_HI_DIR;
  648. mutex_lock(&clock->ptp_lock);
  649. rc = mchp_rds_phy_write_mmd(clock, MCHP_RDS_PTP_LTC_RATE_ADJ_HI,
  650. MCHP_RDS_PTP_CLOCK, rate_hi);
  651. if (rc < 0)
  652. goto error;
  653. rc = mchp_rds_phy_write_mmd(clock, MCHP_RDS_PTP_LTC_RATE_ADJ_LO,
  654. MCHP_RDS_PTP_CLOCK, rate_lo);
  655. if (rc > 0)
  656. rc = 0;
  657. error:
  658. mutex_unlock(&clock->ptp_lock);
  659. return rc;
  660. }
  661. static int mchp_rds_ptp_ltc_gettime64(struct ptp_clock_info *info,
  662. struct timespec64 *ts)
  663. {
  664. struct mchp_rds_ptp_clock *clock = container_of(info,
  665. struct mchp_rds_ptp_clock,
  666. caps);
  667. time64_t secs;
  668. int rc = 0;
  669. s64 nsecs;
  670. mutex_lock(&clock->ptp_lock);
  671. /* Set read bit to 1 to save current values of 1588 local time counter
  672. * into PTP LTC seconds and nanoseconds registers.
  673. */
  674. rc = mchp_rds_phy_set_bits_mmd(clock, MCHP_RDS_PTP_CMD_CTL,
  675. MCHP_RDS_PTP_CLOCK,
  676. MCHP_RDS_PTP_CMD_CTL_CLOCK_READ);
  677. if (rc < 0)
  678. goto out_unlock;
  679. /* Get LTC clock values */
  680. rc = mchp_rds_phy_read_mmd(clock, MCHP_RDS_PTP_LTC_READ_SEC_HI,
  681. MCHP_RDS_PTP_CLOCK);
  682. if (rc < 0)
  683. goto out_unlock;
  684. secs = rc << 16;
  685. rc = mchp_rds_phy_read_mmd(clock, MCHP_RDS_PTP_LTC_READ_SEC_MID,
  686. MCHP_RDS_PTP_CLOCK);
  687. if (rc < 0)
  688. goto out_unlock;
  689. secs |= rc;
  690. secs <<= 16;
  691. rc = mchp_rds_phy_read_mmd(clock, MCHP_RDS_PTP_LTC_READ_SEC_LO,
  692. MCHP_RDS_PTP_CLOCK);
  693. if (rc < 0)
  694. goto out_unlock;
  695. secs |= rc;
  696. rc = mchp_rds_phy_read_mmd(clock, MCHP_RDS_PTP_LTC_READ_NS_HI,
  697. MCHP_RDS_PTP_CLOCK);
  698. if (rc < 0)
  699. goto out_unlock;
  700. nsecs = (rc & GENMASK(13, 0));
  701. nsecs <<= 16;
  702. rc = mchp_rds_phy_read_mmd(clock, MCHP_RDS_PTP_LTC_READ_NS_LO,
  703. MCHP_RDS_PTP_CLOCK);
  704. if (rc < 0)
  705. goto out_unlock;
  706. nsecs |= rc;
  707. set_normalized_timespec64(ts, secs, nsecs);
  708. if (rc > 0)
  709. rc = 0;
  710. out_unlock:
  711. mutex_unlock(&clock->ptp_lock);
  712. return rc;
  713. }
  714. static int mchp_rds_ptp_ltc_settime64(struct ptp_clock_info *info,
  715. const struct timespec64 *ts)
  716. {
  717. struct mchp_rds_ptp_clock *clock = container_of(info,
  718. struct mchp_rds_ptp_clock,
  719. caps);
  720. int rc;
  721. mutex_lock(&clock->ptp_lock);
  722. rc = mchp_rds_phy_write_mmd(clock, MCHP_RDS_PTP_LTC_SEC_LO,
  723. MCHP_RDS_PTP_CLOCK,
  724. lower_16_bits(ts->tv_sec));
  725. if (rc < 0)
  726. goto out_unlock;
  727. rc = mchp_rds_phy_write_mmd(clock, MCHP_RDS_PTP_LTC_SEC_MID,
  728. MCHP_RDS_PTP_CLOCK,
  729. upper_16_bits(ts->tv_sec));
  730. if (rc < 0)
  731. goto out_unlock;
  732. rc = mchp_rds_phy_write_mmd(clock, MCHP_RDS_PTP_LTC_SEC_HI,
  733. MCHP_RDS_PTP_CLOCK,
  734. upper_32_bits(ts->tv_sec) & GENMASK(15, 0));
  735. if (rc < 0)
  736. goto out_unlock;
  737. rc = mchp_rds_phy_write_mmd(clock, MCHP_RDS_PTP_LTC_NS_LO,
  738. MCHP_RDS_PTP_CLOCK,
  739. lower_16_bits(ts->tv_nsec));
  740. if (rc < 0)
  741. goto out_unlock;
  742. rc = mchp_rds_phy_write_mmd(clock, MCHP_RDS_PTP_LTC_NS_HI,
  743. MCHP_RDS_PTP_CLOCK,
  744. upper_16_bits(ts->tv_nsec) & GENMASK(13, 0));
  745. if (rc < 0)
  746. goto out_unlock;
  747. /* Set load bit to 1 to write PTP LTC seconds and nanoseconds
  748. * registers to 1588 local time counter.
  749. */
  750. rc = mchp_rds_phy_set_bits_mmd(clock, MCHP_RDS_PTP_CMD_CTL,
  751. MCHP_RDS_PTP_CLOCK,
  752. MCHP_RDS_PTP_CMD_CTL_CLOCK_LOAD);
  753. if (rc > 0)
  754. rc = 0;
  755. out_unlock:
  756. mutex_unlock(&clock->ptp_lock);
  757. return rc;
  758. }
  759. static bool mchp_rds_ptp_get_sig_tx(struct sk_buff *skb, u16 *sig)
  760. {
  761. struct ptp_header *ptp_header;
  762. int type;
  763. type = ptp_classify_raw(skb);
  764. if (type == PTP_CLASS_NONE)
  765. return false;
  766. ptp_header = ptp_parse_header(skb, type);
  767. if (!ptp_header)
  768. return false;
  769. *sig = (__force u16)(ntohs(ptp_header->sequence_id));
  770. return true;
  771. }
  772. static void mchp_rds_ptp_match_tx_skb(struct mchp_rds_ptp_clock *clock,
  773. u32 seconds, u32 nsec, u16 seq_id)
  774. {
  775. struct skb_shared_hwtstamps shhwtstamps;
  776. struct sk_buff *skb, *skb_tmp;
  777. unsigned long flags;
  778. bool rc = false;
  779. u16 skb_sig;
  780. spin_lock_irqsave(&clock->tx_queue.lock, flags);
  781. skb_queue_walk_safe(&clock->tx_queue, skb, skb_tmp) {
  782. if (!mchp_rds_ptp_get_sig_tx(skb, &skb_sig))
  783. continue;
  784. if (skb_sig != seq_id)
  785. continue;
  786. __skb_unlink(skb, &clock->tx_queue);
  787. rc = true;
  788. break;
  789. }
  790. spin_unlock_irqrestore(&clock->tx_queue.lock, flags);
  791. if (rc) {
  792. shhwtstamps.hwtstamp = ktime_set(seconds, nsec);
  793. skb_complete_tx_timestamp(skb, &shhwtstamps);
  794. }
  795. }
  796. static struct mchp_rds_ptp_rx_ts
  797. *mchp_rds_ptp_get_rx_ts(struct mchp_rds_ptp_clock *clock)
  798. {
  799. struct phy_device *phydev = clock->phydev;
  800. struct mchp_rds_ptp_rx_ts *rx_ts = NULL;
  801. u32 sec, nsec;
  802. int rc;
  803. rc = mchp_rds_phy_read_mmd(clock, MCHP_RDS_PTP_RX_INGRESS_NS_HI,
  804. MCHP_RDS_PTP_PORT);
  805. if (rc < 0)
  806. goto error;
  807. if (!(rc & MCHP_RDS_PTP_RX_INGRESS_NS_HI_TS_VALID)) {
  808. phydev_err(phydev, "RX Timestamp is not valid!\n");
  809. goto error;
  810. }
  811. nsec = (rc & GENMASK(13, 0)) << 16;
  812. rc = mchp_rds_phy_read_mmd(clock, MCHP_RDS_PTP_RX_INGRESS_NS_LO,
  813. MCHP_RDS_PTP_PORT);
  814. if (rc < 0)
  815. goto error;
  816. nsec |= rc;
  817. rc = mchp_rds_phy_read_mmd(clock, MCHP_RDS_PTP_RX_INGRESS_SEC_HI,
  818. MCHP_RDS_PTP_PORT);
  819. if (rc < 0)
  820. goto error;
  821. sec = rc << 16;
  822. rc = mchp_rds_phy_read_mmd(clock, MCHP_RDS_PTP_RX_INGRESS_SEC_LO,
  823. MCHP_RDS_PTP_PORT);
  824. if (rc < 0)
  825. goto error;
  826. sec |= rc;
  827. rc = mchp_rds_phy_read_mmd(clock, MCHP_RDS_PTP_RX_MSG_HDR2,
  828. MCHP_RDS_PTP_PORT);
  829. if (rc < 0)
  830. goto error;
  831. rx_ts = kmalloc_obj(*rx_ts);
  832. if (!rx_ts)
  833. return NULL;
  834. rx_ts->seconds = sec;
  835. rx_ts->nsec = nsec;
  836. rx_ts->seq_id = rc;
  837. error:
  838. return rx_ts;
  839. }
  840. static void mchp_rds_ptp_process_rx_ts(struct mchp_rds_ptp_clock *clock)
  841. {
  842. int caps;
  843. do {
  844. struct mchp_rds_ptp_rx_ts *rx_ts;
  845. rx_ts = mchp_rds_ptp_get_rx_ts(clock);
  846. if (rx_ts)
  847. mchp_rds_ptp_match_rx_ts(clock, rx_ts);
  848. caps = mchp_rds_phy_read_mmd(clock, MCHP_RDS_PTP_CAP_INFO,
  849. MCHP_RDS_PTP_PORT);
  850. if (caps < 0)
  851. return;
  852. } while (MCHP_RDS_PTP_RX_TS_CNT(caps) > 0);
  853. }
  854. static bool mchp_rds_ptp_get_tx_ts(struct mchp_rds_ptp_clock *clock,
  855. u32 *sec, u32 *nsec, u16 *seq)
  856. {
  857. int rc;
  858. rc = mchp_rds_phy_read_mmd(clock, MCHP_RDS_PTP_TX_EGRESS_NS_HI,
  859. MCHP_RDS_PTP_PORT);
  860. if (rc < 0)
  861. return false;
  862. if (!(rc & MCHP_RDS_PTP_TX_EGRESS_NS_HI_TS_VALID))
  863. return false;
  864. *nsec = (rc & GENMASK(13, 0)) << 16;
  865. rc = mchp_rds_phy_read_mmd(clock, MCHP_RDS_PTP_TX_EGRESS_NS_LO,
  866. MCHP_RDS_PTP_PORT);
  867. if (rc < 0)
  868. return false;
  869. *nsec = *nsec | rc;
  870. rc = mchp_rds_phy_read_mmd(clock, MCHP_RDS_PTP_TX_EGRESS_SEC_HI,
  871. MCHP_RDS_PTP_PORT);
  872. if (rc < 0)
  873. return false;
  874. *sec = rc << 16;
  875. rc = mchp_rds_phy_read_mmd(clock, MCHP_RDS_PTP_TX_EGRESS_SEC_LO,
  876. MCHP_RDS_PTP_PORT);
  877. if (rc < 0)
  878. return false;
  879. *sec = *sec | rc;
  880. rc = mchp_rds_phy_read_mmd(clock, MCHP_RDS_PTP_TX_MSG_HDR2,
  881. MCHP_RDS_PTP_PORT);
  882. if (rc < 0)
  883. return false;
  884. *seq = rc;
  885. return true;
  886. }
  887. static void mchp_rds_ptp_process_tx_ts(struct mchp_rds_ptp_clock *clock)
  888. {
  889. int caps;
  890. do {
  891. u32 sec, nsec;
  892. u16 seq;
  893. if (mchp_rds_ptp_get_tx_ts(clock, &sec, &nsec, &seq))
  894. mchp_rds_ptp_match_tx_skb(clock, sec, nsec, seq);
  895. caps = mchp_rds_phy_read_mmd(clock, MCHP_RDS_PTP_CAP_INFO,
  896. MCHP_RDS_PTP_PORT);
  897. if (caps < 0)
  898. return;
  899. } while (MCHP_RDS_PTP_TX_TS_CNT(caps) > 0);
  900. }
  901. int mchp_rds_ptp_top_config_intr(struct mchp_rds_ptp_clock *clock,
  902. u16 reg, u16 val, bool clear)
  903. {
  904. if (clear)
  905. return phy_clear_bits_mmd(clock->phydev, PTP_MMD(clock), reg,
  906. val);
  907. else
  908. return phy_set_bits_mmd(clock->phydev, PTP_MMD(clock), reg,
  909. val);
  910. }
  911. EXPORT_SYMBOL_GPL(mchp_rds_ptp_top_config_intr);
  912. irqreturn_t mchp_rds_ptp_handle_interrupt(struct mchp_rds_ptp_clock *clock)
  913. {
  914. int irq_sts;
  915. /* To handle rogue interrupt scenarios */
  916. if (!clock)
  917. return IRQ_NONE;
  918. do {
  919. irq_sts = mchp_rds_phy_read_mmd(clock, MCHP_RDS_PTP_INT_STS,
  920. MCHP_RDS_PTP_PORT);
  921. if (irq_sts < 0)
  922. return IRQ_NONE;
  923. if (irq_sts & MCHP_RDS_PTP_INT_RX_TS_EN)
  924. mchp_rds_ptp_process_rx_ts(clock);
  925. if (irq_sts & MCHP_RDS_PTP_INT_TX_TS_EN)
  926. mchp_rds_ptp_process_tx_ts(clock);
  927. if (irq_sts & MCHP_RDS_PTP_INT_TX_TS_OVRFL_EN)
  928. mchp_rds_ptp_flush_fifo(clock,
  929. MCHP_RDS_PTP_EGRESS_FIFO);
  930. if (irq_sts & MCHP_RDS_PTP_INT_RX_TS_OVRFL_EN)
  931. mchp_rds_ptp_flush_fifo(clock,
  932. MCHP_RDS_PTP_INGRESS_FIFO);
  933. } while (irq_sts & (MCHP_RDS_PTP_INT_RX_TS_EN |
  934. MCHP_RDS_PTP_INT_TX_TS_EN |
  935. MCHP_RDS_PTP_INT_TX_TS_OVRFL_EN |
  936. MCHP_RDS_PTP_INT_RX_TS_OVRFL_EN));
  937. return IRQ_HANDLED;
  938. }
  939. EXPORT_SYMBOL_GPL(mchp_rds_ptp_handle_interrupt);
  940. static int mchp_rds_ptp_init(struct mchp_rds_ptp_clock *clock)
  941. {
  942. int rc;
  943. /* Disable PTP */
  944. rc = mchp_rds_phy_write_mmd(clock, MCHP_RDS_PTP_CMD_CTL,
  945. MCHP_RDS_PTP_CLOCK,
  946. MCHP_RDS_PTP_CMD_CTL_DIS);
  947. if (rc < 0)
  948. return rc;
  949. /* Disable TSU */
  950. rc = mchp_rds_phy_write_mmd(clock, MCHP_RDS_PTP_TSU_GEN_CONFIG,
  951. MCHP_RDS_PTP_PORT, 0);
  952. if (rc < 0)
  953. return rc;
  954. /* Clear PTP interrupt status registers */
  955. rc = mchp_rds_phy_write_mmd(clock, MCHP_RDS_PTP_TSU_HARD_RESET,
  956. MCHP_RDS_PTP_PORT,
  957. MCHP_RDS_PTP_TSU_HARDRESET);
  958. if (rc < 0)
  959. return rc;
  960. /* Predictor enable */
  961. rc = mchp_rds_phy_write_mmd(clock, MCHP_RDS_PTP_LATENCY_CORRECTION_CTL,
  962. MCHP_RDS_PTP_CLOCK,
  963. MCHP_RDS_PTP_LATENCY_SETTING);
  964. if (rc < 0)
  965. return rc;
  966. /* Configure PTP operational mode */
  967. rc = mchp_rds_phy_write_mmd(clock, MCHP_RDS_PTP_OP_MODE,
  968. MCHP_RDS_PTP_CLOCK,
  969. MCHP_RDS_PTP_OP_MODE_STANDALONE);
  970. if (rc < 0)
  971. return rc;
  972. /* Reference clock configuration */
  973. rc = mchp_rds_phy_write_mmd(clock, MCHP_RDS_PTP_REF_CLK_CFG,
  974. MCHP_RDS_PTP_CLOCK,
  975. MCHP_RDS_PTP_REF_CLK_CFG_SET);
  976. if (rc < 0)
  977. return rc;
  978. /* Classifier configurations */
  979. rc = mchp_rds_phy_write_mmd(clock, MCHP_RDS_PTP_RX_PARSE_CONFIG,
  980. MCHP_RDS_PTP_PORT, 0);
  981. if (rc < 0)
  982. return rc;
  983. rc = mchp_rds_phy_write_mmd(clock, MCHP_RDS_PTP_TX_PARSE_CONFIG,
  984. MCHP_RDS_PTP_PORT, 0);
  985. if (rc < 0)
  986. return rc;
  987. rc = mchp_rds_phy_write_mmd(clock, MCHP_RDS_PTP_TX_PARSE_L2_ADDR_EN,
  988. MCHP_RDS_PTP_PORT, 0);
  989. if (rc < 0)
  990. return rc;
  991. rc = mchp_rds_phy_write_mmd(clock, MCHP_RDS_PTP_RX_PARSE_L2_ADDR_EN,
  992. MCHP_RDS_PTP_PORT, 0);
  993. if (rc < 0)
  994. return rc;
  995. rc = mchp_rds_phy_write_mmd(clock, MCHP_RDS_PTP_RX_PARSE_IPV4_ADDR_EN,
  996. MCHP_RDS_PTP_PORT, 0);
  997. if (rc < 0)
  998. return rc;
  999. rc = mchp_rds_phy_write_mmd(clock, MCHP_RDS_PTP_TX_PARSE_IPV4_ADDR_EN,
  1000. MCHP_RDS_PTP_PORT, 0);
  1001. if (rc < 0)
  1002. return rc;
  1003. rc = mchp_rds_phy_write_mmd(clock, MCHP_RDS_PTP_RX_VERSION,
  1004. MCHP_RDS_PTP_PORT,
  1005. MCHP_RDS_PTP_MAX_VERSION(0xff) |
  1006. MCHP_RDS_PTP_MIN_VERSION(0x0));
  1007. if (rc < 0)
  1008. return rc;
  1009. rc = mchp_rds_phy_write_mmd(clock, MCHP_RDS_PTP_TX_VERSION,
  1010. MCHP_RDS_PTP_PORT,
  1011. MCHP_RDS_PTP_MAX_VERSION(0xff) |
  1012. MCHP_RDS_PTP_MIN_VERSION(0x0));
  1013. if (rc < 0)
  1014. return rc;
  1015. /* Enable TSU */
  1016. rc = mchp_rds_phy_write_mmd(clock, MCHP_RDS_PTP_TSU_GEN_CONFIG,
  1017. MCHP_RDS_PTP_PORT,
  1018. MCHP_RDS_PTP_TSU_GEN_CFG_TSU_EN);
  1019. if (rc < 0)
  1020. return rc;
  1021. /* Enable PTP */
  1022. return mchp_rds_phy_write_mmd(clock, MCHP_RDS_PTP_CMD_CTL,
  1023. MCHP_RDS_PTP_CLOCK,
  1024. MCHP_RDS_PTP_CMD_CTL_EN);
  1025. }
  1026. struct mchp_rds_ptp_clock *mchp_rds_ptp_probe(struct phy_device *phydev, u8 mmd,
  1027. u16 clk_base_addr,
  1028. u16 port_base_addr)
  1029. {
  1030. struct mchp_rds_ptp_clock *clock;
  1031. int rc;
  1032. clock = devm_kzalloc(&phydev->mdio.dev, sizeof(*clock), GFP_KERNEL);
  1033. if (!clock)
  1034. return ERR_PTR(-ENOMEM);
  1035. clock->port_base_addr = port_base_addr;
  1036. clock->clk_base_addr = clk_base_addr;
  1037. clock->mmd = mmd;
  1038. mutex_init(&clock->ptp_lock);
  1039. clock->pin_config = devm_kmalloc_array(&phydev->mdio.dev,
  1040. MCHP_RDS_PTP_N_PIN,
  1041. sizeof(*clock->pin_config),
  1042. GFP_KERNEL);
  1043. if (!clock->pin_config)
  1044. return ERR_PTR(-ENOMEM);
  1045. for (int i = 0; i < MCHP_RDS_PTP_N_PIN; ++i) {
  1046. struct ptp_pin_desc *p = &clock->pin_config[i];
  1047. memset(p, 0, sizeof(*p));
  1048. snprintf(p->name, sizeof(p->name), "pin%d", i);
  1049. p->index = i;
  1050. p->func = PTP_PF_NONE;
  1051. }
  1052. /* Register PTP clock */
  1053. clock->caps.owner = THIS_MODULE;
  1054. snprintf(clock->caps.name, 30, "%s", phydev->drv->name);
  1055. clock->caps.max_adj = MCHP_RDS_PTP_MAX_ADJ;
  1056. clock->caps.n_ext_ts = 0;
  1057. clock->caps.pps = 0;
  1058. clock->caps.n_pins = MCHP_RDS_PTP_N_PIN;
  1059. clock->caps.n_per_out = MCHP_RDS_PTP_N_PEROUT;
  1060. clock->caps.supported_perout_flags = PTP_PEROUT_DUTY_CYCLE;
  1061. clock->caps.pin_config = clock->pin_config;
  1062. clock->caps.adjfine = mchp_rds_ptp_ltc_adjfine;
  1063. clock->caps.adjtime = mchp_rds_ptp_ltc_adjtime;
  1064. clock->caps.gettime64 = mchp_rds_ptp_ltc_gettime64;
  1065. clock->caps.settime64 = mchp_rds_ptp_ltc_settime64;
  1066. clock->caps.enable = mchp_rds_ptpci_enable;
  1067. clock->caps.verify = mchp_rds_ptpci_verify;
  1068. clock->caps.getcrosststamp = NULL;
  1069. clock->ptp_clock = ptp_clock_register(&clock->caps,
  1070. &phydev->mdio.dev);
  1071. if (IS_ERR(clock->ptp_clock))
  1072. return ERR_PTR(-EINVAL);
  1073. /* Check if PHC support is missing at the configuration level */
  1074. if (!clock->ptp_clock)
  1075. return NULL;
  1076. /* Initialize the SW */
  1077. skb_queue_head_init(&clock->tx_queue);
  1078. skb_queue_head_init(&clock->rx_queue);
  1079. INIT_LIST_HEAD(&clock->rx_ts_list);
  1080. spin_lock_init(&clock->rx_ts_lock);
  1081. clock->mii_ts.rxtstamp = mchp_rds_ptp_rxtstamp;
  1082. clock->mii_ts.txtstamp = mchp_rds_ptp_txtstamp;
  1083. clock->mii_ts.hwtstamp_set = mchp_rds_ptp_hwtstamp_set;
  1084. clock->mii_ts.hwtstamp_get = mchp_rds_ptp_hwtstamp_get;
  1085. clock->mii_ts.ts_info = mchp_rds_ptp_ts_info;
  1086. phydev->mii_ts = &clock->mii_ts;
  1087. clock->mchp_rds_ptp_event = -1;
  1088. /* Timestamp selected by default to keep legacy API */
  1089. phydev->default_timestamp = true;
  1090. clock->phydev = phydev;
  1091. rc = mchp_rds_ptp_init(clock);
  1092. if (rc < 0)
  1093. return ERR_PTR(rc);
  1094. return clock;
  1095. }
  1096. EXPORT_SYMBOL_GPL(mchp_rds_ptp_probe);
  1097. MODULE_LICENSE("GPL");
  1098. MODULE_DESCRIPTION("MICROCHIP PHY RDS PTP driver");
  1099. MODULE_AUTHOR("Divya Koppera");