ptp_qcom_tsc.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
  4. *
  5. * QCOM TSC PTP : Linux driver for Time Stamp Counter Hardware.
  6. *
  7. */
  8. #define pr_fmt(fmt) "qcom_tsc: %s: " fmt, __func__
  9. #include <linux/delay.h>
  10. #include <linux/clk.h>
  11. #include <linux/err.h>
  12. #include <linux/gpio.h>
  13. #include <linux/init.h>
  14. #include <linux/kernel.h>
  15. #include <linux/module.h>
  16. #include <linux/ptp_clock_kernel.h>
  17. #include <linux/platform_device.h>
  18. #include <linux/of_irq.h>
  19. /* Register offset definitions */
  20. #define TSCSS_TSC_CONTROL_CNTCR 0x0
  21. #define TSCSS_TSC_CONTROL_CNTCV_LO 0x8
  22. #define TSCSS_TSC_CONTROL_CNTCV_HI 0xC
  23. #define TSCSS_TSC_CONTROL_CNTCV_FRAC 0x10
  24. #define TSCSS_TSC_SLEEP_INCR_VAL_LO 0x24
  25. #define TSCSS_TSC_SLEEP_INCR_VAL_HI 0x28
  26. #define TSCSS_TSC_DRIFT_CORRECT_INCR_VAL 0x2C
  27. #define TSCSS_TSC_DRIFT_CORRECT_DURATION 0x30
  28. #define TSCSS_TSC_DRIFT_CORRECT_CMD 0x34
  29. #define TSCSS_TSC_ROLLOVER_VAL 0x3C
  30. #define TSCSS_TSC_SPARE 0x40
  31. #define TSCSS_TSC_OFFSET_LO 0x50
  32. #define TSCSS_TSC_OFFSET_HI 0x54
  33. #define TSCSS_TSC_FUSA_CFG_STAT 0xF54
  34. #define TSCSS_TSC_READ_CNTCV_LO 0x1000
  35. #define TSCSS_TSC_READ_CNTCV_HI 0x1004
  36. #define TSCSS_TSC_HW_PRELOAD_VAL_LO 0x0060
  37. #define TSCSS_TSC_HW_PRELOAD_VAL_HI 0x0064
  38. #define TSCSS_TSC_SLICE_ETU_CFG 0x0
  39. #define TSCSS_TSC_SLICE_ETU_STATUS 0x4
  40. #define TSCSS_ETU_SLICE_TSC_TS_LO 0x8
  41. #define TSCSS_ETU_SLICE_TSC_TS_HI 0xC
  42. #define TSCSS_ETU_SLICE_TS_EVENT_TYPE 0x10
  43. #define TSCSS_ETU_SLICE_GCTR_TS_LO 0x20
  44. #define TSCSS_ETU_SLICE_GCTR_TS_HI 0x24
  45. #define TSCSS_ETU_SLICE_FIFO_CLR 0x30
  46. #define TSCSS_ETU_SLICE_SW_TRIG_CFG 0x34
  47. #define TSCSS_ETU_SLICE_TIMER_TRIG_PERIOD 0x38
  48. #define MAX_ETU_SLICE 16
  49. #define TSC_PRELOAD_POLLING_DELAY_MS 100
  50. #define NSEC_SHFT 32
  51. #define NSEC 1000000000ULL
  52. #define XO_MHZ 19200000
  53. #define TSCSS_TSC_ETU_SLICE_BASE(reg_base, num, offset) \
  54. (reg_base + num * 0x1000 + offset)
  55. struct qcom_etu_slice {
  56. char name[10];
  57. struct ptp_clock *ptp_clock;
  58. void __iomem *etu_baseaddr;
  59. u64 etu_tsc_timestamp;
  60. u64 last_sec;
  61. u64 global_qtimer;
  62. int extts_enable;
  63. int extts_irq;
  64. int extts_index;
  65. int extts_event_sel;
  66. int extts_slice_num;
  67. int extts_event_type;
  68. u32 etu_tsc_sec;
  69. u32 etu_tsc_nsec;
  70. u32 etu_gctr_sec;
  71. u32 etu_gctr_nsec;
  72. bool extts_present;
  73. };
  74. struct qcom_ptp_tsc {
  75. struct device *dev;
  76. void __iomem *baseaddr;
  77. void __iomem *etu_baseaddr;
  78. struct clk *tsc_cfg_ahb_clk;
  79. struct clk *tsc_cntr_clk;
  80. struct clk *tsc_etu_clk;
  81. struct ptp_clock *ptp_clock;
  82. struct ptp_clock_info ptp_clock_info;
  83. struct qcom_etu_slice etu_slice[MAX_ETU_SLICE];
  84. int pps_enable;
  85. int total_etu_cnt;
  86. u32 incval;
  87. bool tsc_nsec_update;
  88. bool tsc_hw_preload;
  89. spinlock_t reg_lock;
  90. struct delayed_work tsc_preload_poll_work;
  91. };
  92. static void tsc_preload_poll(struct work_struct *work)
  93. {
  94. struct qcom_ptp_tsc *timer = container_of(work, struct qcom_ptp_tsc,
  95. tsc_preload_poll_work.work);
  96. u32 regval;
  97. regval = readl_relaxed(timer->baseaddr + TSCSS_TSC_CONTROL_CNTCR);
  98. /* Check for the HW_PRELOAD_STATUS and disable HW_PRELOAD */
  99. if (!(regval & BIT(14))) {
  100. regval &= ~BIT(2);
  101. writel_relaxed(regval, timer->baseaddr + TSCSS_TSC_CONTROL_CNTCR);
  102. pr_info("TSC CNTCR: 0x%x HW_PRELOAD is disabled\n",
  103. readl_relaxed(timer->baseaddr + TSCSS_TSC_CONTROL_CNTCR));
  104. return;
  105. }
  106. pr_debug("TSC CNTCR: 0x%x HW_PRELOAD_STATUS is not cleared\n", regval);
  107. mod_delayed_work(system_highpri_wq, &timer->tsc_preload_poll_work,
  108. msecs_to_jiffies(TSC_PRELOAD_POLLING_DELAY_MS));
  109. }
  110. static int qcom_ptp_tsc_is_enabled(void __iomem *addr)
  111. {
  112. return readl_relaxed(addr + TSCSS_TSC_CONTROL_CNTCR) & BIT(0);
  113. }
  114. static void qcom_tod_read(struct qcom_ptp_tsc *timer, struct timespec64 *ts)
  115. {
  116. u64 temp, final;
  117. u32 sec, nsec;
  118. if (!qcom_ptp_tsc_is_enabled(timer->baseaddr)) {
  119. pr_debug("TSC is not enabled\n");
  120. return;
  121. }
  122. sec = readl_relaxed(timer->baseaddr + TSCSS_TSC_READ_CNTCV_HI);
  123. nsec = readl_relaxed(timer->baseaddr + TSCSS_TSC_READ_CNTCV_LO);
  124. pr_debug("CNTR_HI: 0x%x, sec %lld\n",
  125. readl_relaxed(timer->baseaddr + TSCSS_TSC_CONTROL_CNTCV_HI), sec);
  126. pr_debug("CNTR_LO: 0x%x nsec %ld\n",
  127. readl_relaxed(timer->baseaddr + TSCSS_TSC_CONTROL_CNTCV_LO), nsec);
  128. if (timer->tsc_nsec_update) {
  129. temp = sec;
  130. final = (temp << NSEC_SHFT) | nsec;
  131. sec = div_u64_rem(final, NSEC, &nsec);
  132. pr_debug("tsc_nsec_update: %d, sec %lld, nsec %ld\n",
  133. timer->tsc_nsec_update, sec, nsec);
  134. }
  135. ts->tv_sec = sec;
  136. ts->tv_nsec = nsec;
  137. }
  138. static void qcom_ptp_enable_tsc_hw_preload(struct qcom_ptp_tsc *timer, struct timespec64 ts)
  139. {
  140. u32 regval;
  141. int timeout = 500;
  142. /* Enable HW_PRELOAD */
  143. regval = readl_relaxed(timer->baseaddr + TSCSS_TSC_CONTROL_CNTCR);
  144. regval |= BIT(2);
  145. writel_relaxed(regval, timer->baseaddr + TSCSS_TSC_CONTROL_CNTCR);
  146. /* Program PRELOAD registers */
  147. writel_relaxed(ts.tv_sec, timer->baseaddr + TSCSS_TSC_HW_PRELOAD_VAL_HI);
  148. writel_relaxed(ts.tv_nsec, timer->baseaddr + TSCSS_TSC_HW_PRELOAD_VAL_LO);
  149. pr_debug("HW_PRELOAD_VAL_HI: 0x%x\n",
  150. readl_relaxed(timer->baseaddr + TSCSS_TSC_HW_PRELOAD_VAL_HI));
  151. pr_debug("HW_PRELOAD_VAL_LO: 0x%x\n",
  152. readl_relaxed(timer->baseaddr + TSCSS_TSC_HW_PRELOAD_VAL_LO));
  153. /* Check for the HW_PRELOAD_STATUS and start poll thread */
  154. while (timeout-- > 0) {
  155. regval = readl_relaxed(timer->baseaddr + TSCSS_TSC_CONTROL_CNTCR);
  156. if (regval & BIT(14)) {
  157. pr_debug("TSC CNTR: 0x%x HW_PRELOAD is enabled\n", regval);
  158. mod_delayed_work(system_highpri_wq, &timer->tsc_preload_poll_work,
  159. msecs_to_jiffies(TSC_PRELOAD_POLLING_DELAY_MS));
  160. return;
  161. }
  162. udelay(1);
  163. }
  164. pr_warn("TSC CNTR: 0x%x HW_PRELOAD enable failed\n",
  165. readl_relaxed(timer->baseaddr + TSCSS_TSC_CONTROL_CNTCR));
  166. }
  167. static int qcom_ptp_update_tsc_cntr(struct qcom_ptp_tsc *timer,
  168. struct timespec64 offset)
  169. {
  170. u64 timestamp = 0;
  171. u32 regval, mask = 0xFFFFFFFF;
  172. /* Update to 1ns resolution */
  173. if (timer->tsc_nsec_update) {
  174. timestamp = offset.tv_sec * NSEC + offset.tv_nsec;
  175. writel_relaxed((timestamp >> NSEC_SHFT),
  176. timer->baseaddr + TSCSS_TSC_CONTROL_CNTCV_HI);
  177. writel_relaxed(timestamp & mask, timer->baseaddr + TSCSS_TSC_CONTROL_CNTCV_LO);
  178. }
  179. pr_debug("Timestamp %llu: sec: %lld, nsec: %ld\n", timestamp,
  180. offset.tv_sec, offset.tv_nsec);
  181. writel_relaxed(offset.tv_sec, timer->baseaddr + TSCSS_TSC_CONTROL_CNTCV_HI);
  182. writel_relaxed(offset.tv_nsec, timer->baseaddr + TSCSS_TSC_CONTROL_CNTCV_LO);
  183. pr_debug("CNTR_HI: 0x%x\n", readl_relaxed(timer->baseaddr + TSCSS_TSC_CONTROL_CNTCV_HI));
  184. pr_debug("CNTR_LO: 0x%x\n", readl_relaxed(timer->baseaddr + TSCSS_TSC_CONTROL_CNTCV_LO));
  185. /* Enable the counter */
  186. regval = readl_relaxed(timer->baseaddr + TSCSS_TSC_CONTROL_CNTCR);
  187. regval |= BIT(0);
  188. writel_relaxed(regval, timer->baseaddr + TSCSS_TSC_CONTROL_CNTCR);
  189. return 0;
  190. }
  191. static void qcom_ptp_update_tsc_offset(struct qcom_ptp_tsc *timer,
  192. struct timespec64 offset)
  193. {
  194. if (timer->tsc_nsec_update)
  195. return;
  196. writel_relaxed(offset.tv_nsec, timer->baseaddr + TSCSS_TSC_OFFSET_LO);
  197. writel_relaxed(offset.tv_sec, timer->baseaddr + TSCSS_TSC_OFFSET_HI);
  198. pr_debug("CNTR_HI: 0x%x\n", readl_relaxed(timer->baseaddr + TSCSS_TSC_CONTROL_CNTCV_HI));
  199. pr_debug("CNTR_LO: 0x%x\n", readl_relaxed(timer->baseaddr + TSCSS_TSC_CONTROL_CNTCV_LO));
  200. }
  201. /*
  202. * PTP clock operations
  203. */
  204. static int qcom_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
  205. {
  206. struct qcom_ptp_tsc *timer = container_of(ptp, struct qcom_ptp_tsc,
  207. ptp_clock_info);
  208. int neg_adj = 0;
  209. u64 freq;
  210. u32 diff, incval = timer->incval;
  211. if (ppb < 0) {
  212. neg_adj = 1;
  213. ppb = -ppb;
  214. }
  215. freq = incval;
  216. freq *= ppb;
  217. diff = div_u64(freq, NSEC);
  218. incval = neg_adj ? (incval - diff) : (incval + diff);
  219. return 0;
  220. }
  221. static int qcom_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
  222. {
  223. unsigned long flags;
  224. struct qcom_ptp_tsc *timer = container_of(ptp, struct qcom_ptp_tsc,
  225. ptp_clock_info);
  226. struct timespec64 offset;
  227. spin_lock_irqsave(&timer->reg_lock, flags);
  228. offset = ns_to_timespec64(delta);
  229. pr_debug("sec: %lld, nsec: %ld\n", offset.tv_sec, offset.tv_nsec);
  230. qcom_ptp_update_tsc_offset(timer, offset);
  231. spin_unlock_irqrestore(&timer->reg_lock, flags);
  232. return 0;
  233. }
  234. static int qcom_ptp_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)
  235. {
  236. unsigned long flags;
  237. struct qcom_ptp_tsc *timer = container_of(ptp, struct qcom_ptp_tsc,
  238. ptp_clock_info);
  239. spin_lock_irqsave(&timer->reg_lock, flags);
  240. qcom_tod_read(timer, ts);
  241. spin_unlock_irqrestore(&timer->reg_lock, flags);
  242. return 0;
  243. }
  244. /**
  245. * qcom_ptp_settime - Set the current time on the hardware clock
  246. * @ptp: ptp clock structure
  247. * @ts: timespec64 containing the new time for the cycle counter
  248. */
  249. static int qcom_ptp_settime(struct ptp_clock_info *ptp, const struct timespec64 *ts)
  250. {
  251. struct qcom_ptp_tsc *timer = container_of(ptp, struct qcom_ptp_tsc, ptp_clock_info);
  252. struct timespec64 delta, tod;
  253. struct timespec64 offset;
  254. unsigned long flags;
  255. int ret;
  256. spin_lock_irqsave(&timer->reg_lock, flags);
  257. pr_debug("TS.sec %lld TS.tv_nsec %ld\n", ts->tv_sec, ts->tv_nsec);
  258. if (!qcom_ptp_tsc_is_enabled(timer->baseaddr)) {
  259. /* Update the Counter */
  260. offset.tv_sec = ts->tv_sec;
  261. offset.tv_nsec = ts->tv_nsec;
  262. ret = qcom_ptp_update_tsc_cntr(timer, offset);
  263. spin_unlock_irqrestore(&timer->reg_lock, flags);
  264. return ret;
  265. }
  266. /* Get the current timer value */
  267. qcom_tod_read(timer, &tod);
  268. /* Subtract the current reported time from our desired time */
  269. delta = timespec64_sub((struct timespec64)*ts, tod);
  270. pr_debug("Delta.sec %lld delta.tv_nsec %ld\n", delta.tv_sec, delta.tv_nsec);
  271. /* Update the Counter */
  272. qcom_ptp_update_tsc_offset(timer, delta);
  273. spin_unlock_irqrestore(&timer->reg_lock, flags);
  274. return 0;
  275. }
  276. static irqreturn_t qcom_etu_irq_handler(int irq, void *data)
  277. {
  278. struct qcom_etu_slice *etu = (struct qcom_etu_slice *)data;
  279. struct ptp_clock_event extts_event;
  280. u32 regval, status;
  281. status = readl_relaxed(TSCSS_TSC_ETU_SLICE_BASE(etu->etu_baseaddr,
  282. etu->extts_slice_num, TSCSS_TSC_SLICE_ETU_STATUS));
  283. pr_debug("Slice %d extts_enable %d status 0%x\n",
  284. etu->extts_slice_num, etu->extts_enable, status);
  285. if (etu->extts_enable && (status & GENMASK(5, 0))) {
  286. u64 ts;
  287. etu->etu_tsc_sec = readl_relaxed(TSCSS_TSC_ETU_SLICE_BASE(etu->etu_baseaddr,
  288. etu->extts_slice_num, TSCSS_ETU_SLICE_TSC_TS_HI));
  289. etu->etu_tsc_nsec = readl_relaxed(TSCSS_TSC_ETU_SLICE_BASE(etu->etu_baseaddr,
  290. etu->extts_slice_num, TSCSS_ETU_SLICE_TSC_TS_LO));
  291. ts = etu->etu_tsc_sec * NSEC + etu->etu_tsc_nsec;
  292. pr_debug("ts:%llu etu->etu_tsc_timestamp:%llu\n", ts, etu->etu_tsc_timestamp);
  293. if (ts != etu->etu_tsc_timestamp) {
  294. extts_event.type = PTP_CLOCK_EXTTS;
  295. extts_event.index = etu->extts_index;
  296. extts_event.timestamp = ts;
  297. pr_debug("type:%d index:%d timestamp:%llu\n", extts_event.type,
  298. extts_event.index, extts_event.timestamp);
  299. ptp_clock_event(etu->ptp_clock, &extts_event);
  300. }
  301. etu->etu_tsc_timestamp = ts;
  302. pr_debug("etu_tsc_sec:%u etu_tsc_nsec:%u etu_tsc_timestamp:%llu\n",
  303. etu->etu_tsc_sec, etu->etu_tsc_nsec, etu->etu_tsc_timestamp);
  304. etu->etu_gctr_sec = readl_relaxed(TSCSS_TSC_ETU_SLICE_BASE(etu->etu_baseaddr,
  305. etu->extts_slice_num, TSCSS_ETU_SLICE_GCTR_TS_HI));
  306. etu->etu_gctr_nsec = readl_relaxed(TSCSS_TSC_ETU_SLICE_BASE(etu->etu_baseaddr,
  307. etu->extts_slice_num, TSCSS_ETU_SLICE_GCTR_TS_LO));
  308. etu->extts_event_type = readl_relaxed(TSCSS_TSC_ETU_SLICE_BASE(etu->etu_baseaddr,
  309. etu->extts_slice_num, TSCSS_ETU_SLICE_TS_EVENT_TYPE));
  310. /* Concatenate GCTR_TS_HI(31:0) & GCTR_TS_LO(31:8) and divide with 19.2MHz */
  311. etu->global_qtimer = (((u64)etu->etu_gctr_sec << 24) |
  312. (etu->etu_gctr_nsec >> 8)) / XO_MHZ;
  313. pr_debug("etu_gctr_sec:%u etu_gctr_nsec:%u global_qtimer:%x extts_event_type %d\n",
  314. etu->etu_gctr_sec, etu->etu_gctr_nsec,
  315. etu->global_qtimer, etu->extts_event_type);
  316. regval = readl_relaxed(TSCSS_TSC_ETU_SLICE_BASE(etu->etu_baseaddr,
  317. etu->extts_slice_num, TSCSS_TSC_SLICE_ETU_CFG));
  318. regval &= ~BIT(17);
  319. regval &= ~BIT(16);
  320. writel_relaxed(regval, TSCSS_TSC_ETU_SLICE_BASE(etu->etu_baseaddr,
  321. etu->extts_slice_num, TSCSS_TSC_SLICE_ETU_CFG));
  322. /* FIFO CLR */
  323. writel_relaxed(0x7, TSCSS_TSC_ETU_SLICE_BASE(etu->etu_baseaddr,
  324. etu->extts_slice_num, TSCSS_ETU_SLICE_FIFO_CLR));
  325. pr_debug("Status %x, sec: %u\n",
  326. readl_relaxed(TSCSS_TSC_ETU_SLICE_BASE(etu->etu_baseaddr,
  327. etu->extts_slice_num, TSCSS_TSC_SLICE_ETU_STATUS)),
  328. readl_relaxed(TSCSS_TSC_ETU_SLICE_BASE(etu->etu_baseaddr,
  329. etu->extts_slice_num, TSCSS_ETU_SLICE_TSC_TS_HI)));
  330. /* Enable GCTR_TS_EN & TSCTR_TS_EN*/
  331. regval |= BIT(16) | BIT(17);
  332. writel_relaxed(regval, TSCSS_TSC_ETU_SLICE_BASE(etu->etu_baseaddr,
  333. etu->extts_slice_num, TSCSS_TSC_SLICE_ETU_CFG));
  334. }
  335. return IRQ_HANDLED;
  336. }
  337. static void qcom_tsc_configure_etu(struct qcom_ptp_tsc *timer, int slice)
  338. {
  339. void __iomem *base = timer->etu_baseaddr;
  340. u32 regval;
  341. /* Register for the IRQ */
  342. regval = readl_relaxed(TSCSS_TSC_ETU_SLICE_BASE(base, slice, TSCSS_TSC_SLICE_ETU_CFG));
  343. regval |= (timer->etu_slice[slice].extts_event_sel << 4) & GENMASK(9, 4);
  344. writel_relaxed(regval, TSCSS_TSC_ETU_SLICE_BASE(base, slice, TSCSS_TSC_SLICE_ETU_CFG));
  345. regval = readl_relaxed(TSCSS_TSC_ETU_SLICE_BASE(base, slice, TSCSS_TSC_SLICE_ETU_CFG));
  346. /* Enable GCTR_TS_EN & TSCTR_TS_EN*/
  347. regval |= BIT(16) | BIT(17);
  348. /* Interrupt MASK enable */
  349. regval |= BIT(31);
  350. /* Enable rising edge config */
  351. regval |= BIT(0);
  352. writel_relaxed(regval, TSCSS_TSC_ETU_SLICE_BASE(base, slice, TSCSS_TSC_SLICE_ETU_CFG));
  353. pr_debug("ETU_SLICE#%d: 0x%x\n", slice,
  354. readl_relaxed(TSCSS_TSC_ETU_SLICE_BASE(base, slice, TSCSS_TSC_SLICE_ETU_CFG)));
  355. }
  356. static int qcom_ptp_enable(struct ptp_clock_info *ptp,
  357. struct ptp_clock_request *rq, int on)
  358. {
  359. struct qcom_ptp_tsc *timer = container_of(ptp, struct qcom_ptp_tsc,
  360. ptp_clock_info);
  361. struct timespec64 ts;
  362. int slice;
  363. pr_debug("Request Type %d\n", rq->type);
  364. switch (rq->type) {
  365. case PTP_CLK_REQ_PPS:
  366. timer->pps_enable = 1;
  367. return 0;
  368. case PTP_CLK_REQ_EXTTS:
  369. pr_debug("PTP_CLK_REQ_EXTTS: Request external Index %d\n", rq->extts.index);
  370. if (rq->extts.index > timer->total_etu_cnt)
  371. return -EINVAL;
  372. else if (!on)
  373. return 0;
  374. for (slice = 0; slice < MAX_ETU_SLICE; slice++) {
  375. if (!timer->etu_slice[slice].extts_present)
  376. continue;
  377. if (rq->extts.index == timer->etu_slice[slice].extts_index) {
  378. pr_debug("slice %d, index %d, etu_index %d\n", slice,
  379. rq->extts.index, timer->etu_slice[slice].extts_index);
  380. qcom_tsc_configure_etu(timer,
  381. timer->etu_slice[slice].extts_slice_num);
  382. timer->etu_slice[slice].extts_enable = true;
  383. }
  384. }
  385. return 0;
  386. case PTP_CLK_REQ_PEROUT:
  387. if (timer->tsc_hw_preload) {
  388. if (!rq->perout.period.sec) {
  389. /* Get the current timer value */
  390. qcom_tod_read(timer, &ts);
  391. } else {
  392. pr_debug("PTP_CLK_REQ_PEROUT: sec:%u nsec:%u\n",
  393. rq->perout.period.sec, rq->perout.period.nsec);
  394. ts.tv_sec = rq->perout.period.sec;
  395. ts.tv_nsec = rq->perout.period.nsec;
  396. }
  397. /* Preload TSC with tv_sec += 1 and tv_nsec = 0 values */
  398. ts.tv_sec += 1;
  399. ts.tv_nsec = 0;
  400. qcom_ptp_enable_tsc_hw_preload(timer, ts);
  401. }
  402. return 0;
  403. default:
  404. break;
  405. }
  406. return -EOPNOTSUPP;
  407. }
  408. static struct ptp_clock_info qcom_ptp_clock_info = {
  409. .owner = THIS_MODULE,
  410. .name = "QCOM TSC",
  411. .max_adj = 999999999,
  412. /* The number of external time stamp channels. */
  413. .n_ext_ts = 1,
  414. .n_per_out = 1,
  415. .pps = 1,
  416. .adjfreq = qcom_ptp_adjfreq,
  417. .adjtime = qcom_ptp_adjtime,
  418. .gettime64 = qcom_ptp_gettime,
  419. .settime64 = qcom_ptp_settime,
  420. .enable = qcom_ptp_enable,
  421. };
  422. /* module operations */
  423. static int qcom_ptp_tsc_remove(struct platform_device *pdev)
  424. {
  425. struct qcom_ptp_tsc *timer = platform_get_drvdata(pdev);
  426. if (timer->ptp_clock) {
  427. ptp_clock_unregister(timer->ptp_clock);
  428. timer->ptp_clock = NULL;
  429. }
  430. return 0;
  431. }
  432. static int qcom_tsc_etu_get_data(struct platform_device *pdev,
  433. struct qcom_ptp_tsc *timer)
  434. {
  435. struct device *dev = &pdev->dev;
  436. struct resource *r_mem;
  437. struct pinctrl *pinctrl;
  438. int ret, cnt, i;
  439. r_mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
  440. if (!r_mem) {
  441. dev_err(&pdev->dev, "No ETU resource defined\n");
  442. return 0;
  443. }
  444. timer->etu_baseaddr = devm_ioremap_resource(&pdev->dev, r_mem);
  445. if (IS_ERR(timer->etu_baseaddr))
  446. return PTR_ERR(timer->etu_baseaddr);
  447. cnt = of_property_count_elems_of_size(dev->of_node, "qcom,etu-event-sel",
  448. sizeof(u32));
  449. pr_debug("Number of event-sel %d\n", cnt);
  450. for (i = 0; i < cnt; i++) {
  451. const char *name;
  452. u32 sel, slice;
  453. ret = of_property_read_u32_index(dev->of_node, "qcom,etu-event-sel", i, &sel);
  454. if (ret)
  455. break;
  456. ret = of_property_read_u32_index(dev->of_node, "qcom,etu-slice", i, &slice);
  457. if (ret) {
  458. pr_debug("etu-slice property does not exist, configure using sel value\n");
  459. slice = sel;
  460. }
  461. timer->etu_slice[slice].etu_baseaddr = timer->etu_baseaddr;
  462. timer->etu_slice[slice].extts_index = i;
  463. timer->etu_slice[slice].extts_event_sel = sel;
  464. timer->etu_slice[slice].extts_slice_num = slice;
  465. of_property_read_string_index(dev->of_node,
  466. "qcom,etu-event-names", i, &name);
  467. strscpy(timer->etu_slice[slice].name, name, sizeof(timer->etu_slice[slice].name));
  468. timer->etu_slice[slice].extts_irq = platform_get_irq_byname(pdev, name);
  469. pr_debug("sel: %d, index: %d, slice-num:%d slice-name: %s, IRQ: %d\n", sel,
  470. timer->etu_slice[slice].extts_index, slice,
  471. timer->etu_slice[slice].name, timer->etu_slice[slice].extts_irq);
  472. if (timer->etu_slice[slice].extts_irq > 0) {
  473. ret = devm_request_irq(dev, timer->etu_slice[slice].extts_irq,
  474. qcom_etu_irq_handler, IRQF_TRIGGER_RISING,
  475. timer->etu_slice[slice].name,
  476. (void *)&timer->etu_slice[slice]);
  477. if (ret)
  478. pr_debug("Failed to request IRQ\n");
  479. else
  480. pr_debug("IRQ registered ret%d\n", ret);
  481. }
  482. timer->etu_slice[slice].extts_present = true;
  483. timer->etu_slice[slice].ptp_clock = timer->ptp_clock;
  484. }
  485. timer->total_etu_cnt = cnt;
  486. timer->ptp_clock_info.n_ext_ts = cnt;
  487. pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
  488. if (IS_ERR(pinctrl))
  489. dev_info(&pdev->dev, "No default pinctrl found\n");
  490. return 0;
  491. }
  492. static int qcom_ptp_tsc_probe(struct platform_device *pdev)
  493. {
  494. struct qcom_ptp_tsc *timer;
  495. struct resource *r_mem;
  496. u32 cntr_val;
  497. int ret;
  498. timer = devm_kzalloc(&pdev->dev, sizeof(*timer), GFP_KERNEL);
  499. if (!timer)
  500. return -ENOMEM;
  501. timer->dev = &pdev->dev;
  502. r_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  503. if (!r_mem) {
  504. dev_err(&pdev->dev, "no IO resource defined\n");
  505. return -ENXIO;
  506. }
  507. timer->baseaddr = devm_ioremap_resource(&pdev->dev, r_mem);
  508. if (IS_ERR(timer->baseaddr))
  509. return PTR_ERR(timer->baseaddr);
  510. spin_lock_init(&timer->reg_lock);
  511. timer->tsc_cfg_ahb_clk = devm_clk_get(&pdev->dev, "cfg_ahb");
  512. if (IS_ERR(timer->tsc_cfg_ahb_clk)) {
  513. if (PTR_ERR(timer->tsc_cfg_ahb_clk) != -EPROBE_DEFER)
  514. dev_err(&pdev->dev, "Unable to get CFG AHB clock\n");
  515. return PTR_ERR(timer->tsc_cfg_ahb_clk);
  516. }
  517. timer->tsc_cntr_clk = devm_clk_get(&pdev->dev, "cntr");
  518. if (IS_ERR(timer->tsc_cntr_clk)) {
  519. if (PTR_ERR(timer->tsc_cntr_clk) != -EPROBE_DEFER)
  520. dev_err(&pdev->dev, "Unable to get Counter clock\n");
  521. return PTR_ERR(timer->tsc_cntr_clk);
  522. }
  523. timer->tsc_etu_clk = devm_clk_get(&pdev->dev, "etu");
  524. if (IS_ERR(timer->tsc_etu_clk)) {
  525. if (PTR_ERR(timer->tsc_etu_clk) != -EPROBE_DEFER)
  526. dev_err(&pdev->dev, "Unable to get ETU clock\n");
  527. return PTR_ERR(timer->tsc_etu_clk);
  528. }
  529. ret = clk_prepare_enable(timer->tsc_cfg_ahb_clk);
  530. if (ret) {
  531. pr_debug("Failed to enable AHB clock\n");
  532. return ret;
  533. }
  534. ret = clk_prepare_enable(timer->tsc_cntr_clk);
  535. if (ret) {
  536. pr_debug("Failed to enable counter clock\n");
  537. return ret;
  538. }
  539. ret = clk_prepare_enable(timer->tsc_etu_clk);
  540. if (ret) {
  541. pr_debug("Failed to enable etu clock\n");
  542. return ret;
  543. }
  544. timer->tsc_nsec_update = of_property_read_bool(pdev->dev.of_node,
  545. "qcom,tsc-nsec-update");
  546. timer->tsc_hw_preload = of_property_read_bool(pdev->dev.of_node,
  547. "qcom,tsc-hw-preload");
  548. if (timer->tsc_hw_preload)
  549. INIT_DEFERRABLE_WORK(&timer->tsc_preload_poll_work, tsc_preload_poll);
  550. timer->ptp_clock_info = qcom_ptp_clock_info;
  551. timer->ptp_clock = ptp_clock_register(&timer->ptp_clock_info, &pdev->dev);
  552. if (IS_ERR(timer->ptp_clock)) {
  553. ret = PTR_ERR(timer->ptp_clock);
  554. dev_err(&pdev->dev, "Failed to register ptp clock\n");
  555. goto out;
  556. }
  557. qcom_tsc_etu_get_data(pdev, timer);
  558. if (!timer->tsc_nsec_update) {
  559. cntr_val = (timer->tsc_hw_preload ? 0x1D8 : 0x1CC);
  560. writel_relaxed(0x3B9AC9FF, timer->baseaddr + TSCSS_TSC_ROLLOVER_VAL);
  561. } else {
  562. cntr_val = 0x18C;
  563. }
  564. writel_relaxed(cntr_val, timer->baseaddr + TSCSS_TSC_CONTROL_CNTCR);
  565. pr_info("TSC CNTR 0x%x tsc-nsec-update %d tsc-hw-preload %d\n",
  566. readl_relaxed(timer->baseaddr), timer->tsc_nsec_update, timer->tsc_hw_preload);
  567. platform_set_drvdata(pdev, timer);
  568. return 0;
  569. out:
  570. timer->ptp_clock = NULL;
  571. return ret;
  572. }
  573. static const struct of_device_id tsc_of_match[] = {
  574. { .compatible = "qcom,tsc", },
  575. { /* end of table */ }
  576. };
  577. MODULE_DEVICE_TABLE(of, timer_tsc_of_match);
  578. static struct platform_driver qcom_ptp_tsc_driver = {
  579. .probe = qcom_ptp_tsc_probe,
  580. .remove = qcom_ptp_tsc_remove,
  581. .driver = {
  582. .name = "qcom_ptp_tsc",
  583. .of_match_table = tsc_of_match,
  584. },
  585. };
  586. module_platform_driver(qcom_ptp_tsc_driver);
  587. MODULE_DESCRIPTION("PTP QCOM TSC driver");
  588. MODULE_LICENSE("GPL");