Lines Matching +full:no +full:- +full:read +full:- +full:rollover
1 // SPDX-License-Identifier: GPL-2.0-only
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()
48 spin_lock_irqsave(&bp->tsu_clk_lock, flags); in gem_tsu_get_time()
54 /* test for nsec rollover */ in gem_tsu_get_time()
56 /* if so, use later read & re-read seconds in gem_tsu_get_time()
59 ts->tv_nsec = gem_readl(bp, TN); in gem_tsu_get_time()
63 ts->tv_nsec = first; in gem_tsu_get_time()
66 spin_unlock_irqrestore(&bp->tsu_clk_lock, flags); in gem_tsu_get_time()
67 ts->tv_sec = (((u64)sech << GEM_TSL_SIZE) | secl) in gem_tsu_get_time()
79 secl = (u32)ts->tv_sec; in gem_tsu_set_time()
80 sech = (ts->tv_sec >> GEM_TSL_SIZE) & ((1 << GEM_TSH_SIZE) - 1); in gem_tsu_set_time()
81 ns = ts->tv_nsec; in gem_tsu_set_time()
83 spin_lock_irqsave(&bp->tsu_clk_lock, flags); in gem_tsu_set_time()
85 /* TSH doesn't latch the time and no atomicity! */ in gem_tsu_set_time()
92 spin_unlock_irqrestore(&bp->tsu_clk_lock, flags); in gem_tsu_set_time()
106 spin_lock_irqsave(&bp->tsu_clk_lock, flags); in gem_tsu_incr_set()
108 gem_writel(bp, TISUBN, GEM_BF(SUBNSINCRL, incr_spec->sub_ns) | in gem_tsu_incr_set()
109 GEM_BF(SUBNSINCRH, (incr_spec->sub_ns >> in gem_tsu_incr_set()
111 gem_writel(bp, TI, GEM_BF(NSINCR, incr_spec->ns)); in gem_tsu_incr_set()
112 spin_unlock_irqrestore(&bp->tsu_clk_lock, flags); in gem_tsu_incr_set()
127 scaled_ppm = -scaled_ppm; in gem_ptp_adjfine()
131 incr_spec.sub_ns = bp->tsu_incr.sub_ns; in gem_ptp_adjfine()
132 incr_spec.ns = bp->tsu_incr.ns; in gem_ptp_adjfine()
143 adj = neg_adj ? (word - adj) : (word + adj); in gem_ptp_adjfine()
146 & ((1 << GEM_NSINCR_SIZE) - 1); in gem_ptp_adjfine()
147 incr_spec.sub_ns = adj & ((1 << GEM_SUBNSINCR_SIZE) - 1); in gem_ptp_adjfine()
160 delta = -delta; in gem_ptp_adjtime()
164 gem_tsu_get_time(&bp->ptp_clock_info, &now); in gem_ptp_adjtime()
167 gem_tsu_set_time(&bp->ptp_clock_info, in gem_ptp_adjtime()
181 return -EOPNOTSUPP; in gem_ptp_enable()
205 bp->tsu_incr.ns = div_u64_rem(NSEC_PER_SEC, bp->tsu_rate, &rem); in gem_ptp_init_timer()
209 bp->tsu_incr.sub_ns = div_u64(adj, bp->tsu_rate); in gem_ptp_init_timer()
211 bp->tsu_incr.sub_ns = 0; in gem_ptp_init_timer()
223 gem_tsu_set_time(&bp->ptp_clock_info, &ts); in gem_ptp_init_tsu()
226 gem_tsu_incr_set(bp, &bp->tsu_incr); in gem_ptp_init_tsu()
233 bp->tsu_incr.sub_ns = 0; in gem_ptp_clear_timer()
234 bp->tsu_incr.ns = 0; in gem_ptp_clear_timer()
246 ts->tv_sec = (GEM_BFEXT(DMA_SECH, dma_desc_ts_2) << GEM_DMA_SECL_SIZE) | in gem_hw_timestamp()
248 ts->tv_nsec = GEM_BFEXT(DMA_NSEC, dma_desc_ts_1); in gem_hw_timestamp()
254 gem_tsu_get_time(&bp->ptp_clock_info, &tsu); in gem_hw_timestamp()
260 if ((ts->tv_sec & (GEM_DMA_SEC_TOP >> 1)) && in gem_hw_timestamp()
262 ts->tv_sec -= GEM_DMA_SEC_TOP; in gem_hw_timestamp()
264 ts->tv_sec += ((~GEM_DMA_SEC_MASK) & tsu.tv_sec); in gem_hw_timestamp()
276 if (GEM_BFEXT(DMA_RXVALID, desc->addr)) { in gem_ptp_rxstamp()
278 gem_hw_timestamp(bp, desc_ptp->ts_1, desc_ptp->ts_2, &ts); in gem_ptp_rxstamp()
280 shhwtstamps->hwtstamp = ktime_set(ts.tv_sec, ts.tv_nsec); in gem_ptp_rxstamp()
290 gem_hw_timestamp(bp, desc_ptp->ts_1, desc_ptp->ts_2, &ts); in gem_tstamp_tx()
299 unsigned long tail = READ_ONCE(queue->tx_ts_tail); in gem_ptp_txstamp()
300 unsigned long head = queue->tx_ts_head; in gem_ptp_txstamp()
304 if (!GEM_BFEXT(DMA_TXVALID, desc->ctrl)) in gem_ptp_txstamp()
305 return -EINVAL; in gem_ptp_txstamp()
308 return -ENOMEM; in gem_ptp_txstamp()
310 skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; in gem_ptp_txstamp()
311 desc_ptp = macb_ptp_desc(queue->bp, desc); in gem_ptp_txstamp()
312 tx_timestamp = &queue->tx_timestamps[head]; in gem_ptp_txstamp()
313 tx_timestamp->skb = skb; in gem_ptp_txstamp()
316 tx_timestamp->desc_ptp.ts_1 = desc_ptp->ts_1; in gem_ptp_txstamp()
317 tx_timestamp->desc_ptp.ts_2 = desc_ptp->ts_2; in gem_ptp_txstamp()
319 smp_store_release(&queue->tx_ts_head, in gem_ptp_txstamp()
320 (head + 1) & (PTP_TS_BUFFER_SIZE - 1)); in gem_ptp_txstamp()
322 schedule_work(&queue->tx_ts_task); in gem_ptp_txstamp()
334 head = smp_load_acquire(&queue->tx_ts_head); in gem_tx_timestamp_flush()
335 tail = queue->tx_ts_tail; in gem_tx_timestamp_flush()
338 tx_ts = &queue->tx_timestamps[tail]; in gem_tx_timestamp_flush()
339 gem_tstamp_tx(queue->bp, tx_ts->skb, &tx_ts->desc_ptp); in gem_tx_timestamp_flush()
341 dev_kfree_skb_any(tx_ts->skb); in gem_tx_timestamp_flush()
343 smp_store_release(&queue->tx_ts_tail, in gem_tx_timestamp_flush()
344 (tail + 1) & (PTP_TS_BUFFER_SIZE - 1)); in gem_tx_timestamp_flush()
345 tail = queue->tx_ts_tail; in gem_tx_timestamp_flush()
355 bp->ptp_clock_info = gem_ptp_caps_template; in gem_ptp_init()
358 bp->tsu_rate = bp->ptp_info->get_tsu_rate(bp); in gem_ptp_init()
359 bp->ptp_clock_info.max_adj = bp->ptp_info->get_ptp_max_adj(); in gem_ptp_init()
361 bp->ptp_clock = ptp_clock_register(&bp->ptp_clock_info, &dev->dev); in gem_ptp_init()
362 if (IS_ERR(bp->ptp_clock)) { in gem_ptp_init()
364 PTR_ERR(bp->ptp_clock)); in gem_ptp_init()
365 bp->ptp_clock = NULL; in gem_ptp_init()
367 } else if (bp->ptp_clock == NULL) { in gem_ptp_init()
372 spin_lock_init(&bp->tsu_clk_lock); in gem_ptp_init()
373 for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) { in gem_ptp_init()
374 queue->tx_ts_head = 0; in gem_ptp_init()
375 queue->tx_ts_tail = 0; in gem_ptp_init()
376 INIT_WORK(&queue->tx_ts_task, gem_tx_timestamp_flush); in gem_ptp_init()
381 dev_info(&bp->pdev->dev, "%s ptp clock registered.\n", in gem_ptp_init()
389 if (bp->ptp_clock) in gem_ptp_remove()
390 ptp_clock_unregister(bp->ptp_clock); in gem_ptp_remove()
394 dev_info(&bp->pdev->dev, "%s ptp clock unregistered.\n", in gem_ptp_remove()
413 tstamp_config = &bp->tstamp_config; in gem_get_hwtst()
414 if ((bp->hw_dma_cap & HW_DMA_CAP_PTP) == 0) in gem_get_hwtst()
415 return -EOPNOTSUPP; in gem_get_hwtst()
417 if (copy_to_user(rq->ifr_data, tstamp_config, sizeof(*tstamp_config))) in gem_get_hwtst()
418 return -EFAULT; in gem_get_hwtst()
445 tstamp_config = &bp->tstamp_config; in gem_set_hwtst()
446 if ((bp->hw_dma_cap & HW_DMA_CAP_PTP) == 0) in gem_set_hwtst()
447 return -EOPNOTSUPP; in gem_set_hwtst()
449 if (copy_from_user(tstamp_config, ifr->ifr_data, in gem_set_hwtst()
451 return -EFAULT; in gem_set_hwtst()
454 if (tstamp_config->flags) in gem_set_hwtst()
455 return -EINVAL; in gem_set_hwtst()
457 switch (tstamp_config->tx_type) { in gem_set_hwtst()
462 return -ERANGE; in gem_set_hwtst()
468 return -ERANGE; in gem_set_hwtst()
471 switch (tstamp_config->rx_filter) { in gem_set_hwtst()
488 tstamp_config->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; in gem_set_hwtst()
495 tstamp_config->rx_filter = HWTSTAMP_FILTER_ALL; in gem_set_hwtst()
498 tstamp_config->rx_filter = HWTSTAMP_FILTER_NONE; in gem_set_hwtst()
499 return -ERANGE; in gem_set_hwtst()
503 return -ERANGE; in gem_set_hwtst()
505 if (copy_to_user(ifr->ifr_data, tstamp_config, sizeof(*tstamp_config))) in gem_set_hwtst()
506 return -EFAULT; in gem_set_hwtst()