Lines Matching +full:ptp +full:- +full:timer
1 // SPDX-License-Identifier: GPL-2.0-only
3 * 1588 PTP support for Cadence GEM device.
5 * Copyright (C) 2017 Cadence Design Systems - https://www.cadence.com
26 #define GEM_PTP_TIMER_NAME "gem-ptp-timer"
31 if (bp->hw_dma_cap == HW_DMA_CAP_PTP) in macb_ptp_desc()
34 if (bp->hw_dma_cap == HW_DMA_CAP_64B_PTP) in macb_ptp_desc()
41 static int gem_tsu_get_time(struct ptp_clock_info *ptp, struct timespec64 *ts, in gem_tsu_get_time() argument
44 struct macb *bp = container_of(ptp, struct macb, ptp_clock_info); in gem_tsu_get_time()
49 spin_lock_irqsave(&bp->tsu_clk_lock, flags); in gem_tsu_get_time()
59 /* if so, use later read & re-read seconds in gem_tsu_get_time()
63 ts->tv_nsec = gem_readl(bp, TN); in gem_tsu_get_time()
68 ts->tv_nsec = first; in gem_tsu_get_time()
71 spin_unlock_irqrestore(&bp->tsu_clk_lock, flags); in gem_tsu_get_time()
72 ts->tv_sec = (((u64)sech << GEM_TSL_SIZE) | secl) in gem_tsu_get_time()
77 static int gem_tsu_set_time(struct ptp_clock_info *ptp, in gem_tsu_set_time() argument
80 struct macb *bp = container_of(ptp, struct macb, ptp_clock_info); in gem_tsu_set_time()
84 secl = (u32)ts->tv_sec; in gem_tsu_set_time()
85 sech = (ts->tv_sec >> GEM_TSL_SIZE) & ((1 << GEM_TSH_SIZE) - 1); in gem_tsu_set_time()
86 ns = ts->tv_nsec; in gem_tsu_set_time()
88 spin_lock_irqsave(&bp->tsu_clk_lock, flags); in gem_tsu_set_time()
97 spin_unlock_irqrestore(&bp->tsu_clk_lock, flags); in gem_tsu_set_time()
111 spin_lock_irqsave(&bp->tsu_clk_lock, flags); in gem_tsu_incr_set()
113 gem_writel(bp, TISUBN, GEM_BF(SUBNSINCRL, incr_spec->sub_ns) | in gem_tsu_incr_set()
114 GEM_BF(SUBNSINCRH, (incr_spec->sub_ns >> in gem_tsu_incr_set()
116 gem_writel(bp, TI, GEM_BF(NSINCR, incr_spec->ns)); in gem_tsu_incr_set()
117 spin_unlock_irqrestore(&bp->tsu_clk_lock, flags); in gem_tsu_incr_set()
122 static int gem_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm) in gem_ptp_adjfine() argument
124 struct macb *bp = container_of(ptp, struct macb, ptp_clock_info); in gem_ptp_adjfine()
132 scaled_ppm = -scaled_ppm; in gem_ptp_adjfine()
136 incr_spec.sub_ns = bp->tsu_incr.sub_ns; in gem_ptp_adjfine()
137 incr_spec.ns = bp->tsu_incr.ns; in gem_ptp_adjfine()
148 adj = neg_adj ? (word - adj) : (word + adj); in gem_ptp_adjfine()
151 & ((1 << GEM_NSINCR_SIZE) - 1); in gem_ptp_adjfine()
152 incr_spec.sub_ns = adj & ((1 << GEM_SUBNSINCR_SIZE) - 1); in gem_ptp_adjfine()
157 static int gem_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta) in gem_ptp_adjtime() argument
159 struct macb *bp = container_of(ptp, struct macb, ptp_clock_info); in gem_ptp_adjtime()
165 delta = -delta; in gem_ptp_adjtime()
169 gem_tsu_get_time(&bp->ptp_clock_info, &now, NULL); in gem_ptp_adjtime()
172 gem_tsu_set_time(&bp->ptp_clock_info, in gem_ptp_adjtime()
183 static int gem_ptp_enable(struct ptp_clock_info *ptp, in gem_ptp_enable() argument
186 return -EOPNOTSUPP; in gem_ptp_enable()
210 bp->tsu_incr.ns = div_u64_rem(NSEC_PER_SEC, bp->tsu_rate, &rem); in gem_ptp_init_timer()
214 bp->tsu_incr.sub_ns = div_u64(adj, bp->tsu_rate); in gem_ptp_init_timer()
216 bp->tsu_incr.sub_ns = 0; in gem_ptp_init_timer()
227 /* 2. set ptp timer */ in gem_ptp_init_tsu()
228 gem_tsu_set_time(&bp->ptp_clock_info, &ts); in gem_ptp_init_tsu()
230 /* 3. set PTP timer increment value to BASE_INCREMENT */ in gem_ptp_init_tsu()
231 gem_tsu_incr_set(bp, &bp->tsu_incr); in gem_ptp_init_tsu()
238 bp->tsu_incr.sub_ns = 0; in gem_ptp_clear_timer()
239 bp->tsu_incr.ns = 0; in gem_ptp_clear_timer()
251 ts->tv_sec = (GEM_BFEXT(DMA_SECH, dma_desc_ts_2) << GEM_DMA_SECL_SIZE) | in gem_hw_timestamp()
253 ts->tv_nsec = GEM_BFEXT(DMA_NSEC, dma_desc_ts_1); in gem_hw_timestamp()
257 * so add value from 1588 timer in gem_hw_timestamp()
259 gem_tsu_get_time(&bp->ptp_clock_info, &tsu, NULL); in gem_hw_timestamp()
261 ts->tv_sec |= ((~GEM_DMA_SEC_MASK) & tsu.tv_sec); in gem_hw_timestamp()
264 * but not in 1588 timer, it has rolled over, in gem_hw_timestamp()
267 if ((ts->tv_sec & (GEM_DMA_SEC_TOP >> 1)) && in gem_hw_timestamp()
269 ts->tv_sec -= GEM_DMA_SEC_TOP; in gem_hw_timestamp()
281 if (GEM_BFEXT(DMA_RXVALID, desc->addr)) { in gem_ptp_rxstamp()
285 dev_warn_ratelimited(&bp->pdev->dev, in gem_ptp_rxstamp()
289 gem_hw_timestamp(bp, desc_ptp->ts_1, desc_ptp->ts_2, &ts); in gem_ptp_rxstamp()
291 shhwtstamps->hwtstamp = ktime_set(ts.tv_sec, ts.tv_nsec); in gem_ptp_rxstamp()
302 if (!GEM_BFEXT(DMA_TXVALID, desc->ctrl)) { in gem_ptp_txstamp()
303 dev_warn_ratelimited(&bp->pdev->dev, in gem_ptp_txstamp()
311 dev_warn_ratelimited(&bp->pdev->dev, in gem_ptp_txstamp()
318 gem_hw_timestamp(bp, desc_ptp->ts_1, desc_ptp->ts_2, &ts); in gem_ptp_txstamp()
329 bp->ptp_clock_info = gem_ptp_caps_template; in gem_ptp_init()
332 bp->tsu_rate = bp->ptp_info->get_tsu_rate(bp); in gem_ptp_init()
333 bp->ptp_clock_info.max_adj = bp->ptp_info->get_ptp_max_adj(); in gem_ptp_init()
335 bp->ptp_clock = ptp_clock_register(&bp->ptp_clock_info, &dev->dev); in gem_ptp_init()
336 if (IS_ERR(bp->ptp_clock)) { in gem_ptp_init()
337 pr_err("ptp clock register failed: %ld\n", in gem_ptp_init()
338 PTR_ERR(bp->ptp_clock)); in gem_ptp_init()
339 bp->ptp_clock = NULL; in gem_ptp_init()
341 } else if (bp->ptp_clock == NULL) { in gem_ptp_init()
342 pr_err("ptp clock register failed\n"); in gem_ptp_init()
346 spin_lock_init(&bp->tsu_clk_lock); in gem_ptp_init()
350 dev_info(&bp->pdev->dev, "%s ptp clock registered.\n", in gem_ptp_init()
358 if (bp->ptp_clock) in gem_ptp_remove()
359 ptp_clock_unregister(bp->ptp_clock); in gem_ptp_remove()
363 dev_info(&bp->pdev->dev, "%s ptp clock unregistered.\n", in gem_ptp_remove()
382 *tstamp_config = bp->tstamp_config; in gem_get_hwtst()
383 if ((bp->hw_dma_cap & HW_DMA_CAP_PTP) == 0) in gem_get_hwtst()
384 return -EOPNOTSUPP; in gem_get_hwtst()
410 if ((bp->hw_dma_cap & HW_DMA_CAP_PTP) == 0) in gem_set_hwtst()
411 return -EOPNOTSUPP; in gem_set_hwtst()
413 switch (tstamp_config->tx_type) { in gem_set_hwtst()
425 return -ERANGE; in gem_set_hwtst()
428 switch (tstamp_config->rx_filter) { in gem_set_hwtst()
445 tstamp_config->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; in gem_set_hwtst()
452 tstamp_config->rx_filter = HWTSTAMP_FILTER_ALL; in gem_set_hwtst()
455 tstamp_config->rx_filter = HWTSTAMP_FILTER_NONE; in gem_set_hwtst()
456 return -ERANGE; in gem_set_hwtst()
459 bp->tstamp_config = *tstamp_config; in gem_set_hwtst()
462 return -ERANGE; in gem_set_hwtst()