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()
49 spin_lock_irqsave(&bp->tsu_clk_lock, flags); in gem_tsu_get_time()
57 /* test for nsec rollover */ 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()
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()
90 /* TSH doesn't latch the time and no atomicity! */ 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()
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()
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()
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()
228 gem_tsu_set_time(&bp->ptp_clock_info, &ts); 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()
259 gem_tsu_get_time(&bp->ptp_clock_info, &tsu, NULL); in gem_hw_timestamp()
265 if ((ts->tv_sec & (GEM_DMA_SEC_TOP >> 1)) && in gem_hw_timestamp()
267 ts->tv_sec -= GEM_DMA_SEC_TOP; in gem_hw_timestamp()
269 ts->tv_sec += ((~GEM_DMA_SEC_MASK) & tsu.tv_sec); 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()
301 gem_hw_timestamp(bp, desc_ptp->ts_1, desc_ptp->ts_2, &ts); in gem_tstamp_tx()
310 unsigned long tail = READ_ONCE(queue->tx_ts_tail); in gem_ptp_txstamp()
311 unsigned long head = queue->tx_ts_head; in gem_ptp_txstamp()
315 if (!GEM_BFEXT(DMA_TXVALID, desc->ctrl)) in gem_ptp_txstamp()
316 return -EINVAL; in gem_ptp_txstamp()
319 return -ENOMEM; in gem_ptp_txstamp()
321 desc_ptp = macb_ptp_desc(queue->bp, desc); in gem_ptp_txstamp()
324 return -EINVAL; in gem_ptp_txstamp()
325 skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; in gem_ptp_txstamp()
326 tx_timestamp = &queue->tx_timestamps[head]; in gem_ptp_txstamp()
327 tx_timestamp->skb = skb; in gem_ptp_txstamp()
330 tx_timestamp->desc_ptp.ts_1 = desc_ptp->ts_1; in gem_ptp_txstamp()
331 tx_timestamp->desc_ptp.ts_2 = desc_ptp->ts_2; in gem_ptp_txstamp()
333 smp_store_release(&queue->tx_ts_head, in gem_ptp_txstamp()
334 (head + 1) & (PTP_TS_BUFFER_SIZE - 1)); in gem_ptp_txstamp()
336 schedule_work(&queue->tx_ts_task); in gem_ptp_txstamp()
348 head = smp_load_acquire(&queue->tx_ts_head); in gem_tx_timestamp_flush()
349 tail = queue->tx_ts_tail; in gem_tx_timestamp_flush()
352 tx_ts = &queue->tx_timestamps[tail]; in gem_tx_timestamp_flush()
353 gem_tstamp_tx(queue->bp, tx_ts->skb, &tx_ts->desc_ptp); in gem_tx_timestamp_flush()
355 dev_kfree_skb_any(tx_ts->skb); in gem_tx_timestamp_flush()
357 smp_store_release(&queue->tx_ts_tail, in gem_tx_timestamp_flush()
358 (tail + 1) & (PTP_TS_BUFFER_SIZE - 1)); in gem_tx_timestamp_flush()
359 tail = queue->tx_ts_tail; in gem_tx_timestamp_flush()
369 bp->ptp_clock_info = gem_ptp_caps_template; in gem_ptp_init()
372 bp->tsu_rate = bp->ptp_info->get_tsu_rate(bp); in gem_ptp_init()
373 bp->ptp_clock_info.max_adj = bp->ptp_info->get_ptp_max_adj(); in gem_ptp_init()
375 bp->ptp_clock = ptp_clock_register(&bp->ptp_clock_info, &dev->dev); in gem_ptp_init()
376 if (IS_ERR(bp->ptp_clock)) { in gem_ptp_init()
378 PTR_ERR(bp->ptp_clock)); in gem_ptp_init()
379 bp->ptp_clock = NULL; in gem_ptp_init()
381 } else if (bp->ptp_clock == NULL) { in gem_ptp_init()
386 spin_lock_init(&bp->tsu_clk_lock); in gem_ptp_init()
387 for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) { in gem_ptp_init()
388 queue->tx_ts_head = 0; in gem_ptp_init()
389 queue->tx_ts_tail = 0; in gem_ptp_init()
390 INIT_WORK(&queue->tx_ts_task, gem_tx_timestamp_flush); in gem_ptp_init()
395 dev_info(&bp->pdev->dev, "%s ptp clock registered.\n", in gem_ptp_init()
403 if (bp->ptp_clock) in gem_ptp_remove()
404 ptp_clock_unregister(bp->ptp_clock); in gem_ptp_remove()
408 dev_info(&bp->pdev->dev, "%s ptp clock unregistered.\n", in gem_ptp_remove()
427 tstamp_config = &bp->tstamp_config; in gem_get_hwtst()
428 if ((bp->hw_dma_cap & HW_DMA_CAP_PTP) == 0) in gem_get_hwtst()
429 return -EOPNOTSUPP; in gem_get_hwtst()
431 if (copy_to_user(rq->ifr_data, tstamp_config, sizeof(*tstamp_config))) in gem_get_hwtst()
432 return -EFAULT; in gem_get_hwtst()
457 tstamp_config = &bp->tstamp_config; in gem_set_hwtst()
458 if ((bp->hw_dma_cap & HW_DMA_CAP_PTP) == 0) in gem_set_hwtst()
459 return -EOPNOTSUPP; in gem_set_hwtst()
461 if (copy_from_user(tstamp_config, ifr->ifr_data, in gem_set_hwtst()
463 return -EFAULT; in gem_set_hwtst()
465 switch (tstamp_config->tx_type) { in gem_set_hwtst()
477 return -ERANGE; in gem_set_hwtst()
480 switch (tstamp_config->rx_filter) { in gem_set_hwtst()
497 tstamp_config->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; in gem_set_hwtst()
504 tstamp_config->rx_filter = HWTSTAMP_FILTER_ALL; in gem_set_hwtst()
507 tstamp_config->rx_filter = HWTSTAMP_FILTER_NONE; in gem_set_hwtst()
508 return -ERANGE; in gem_set_hwtst()
512 return -ERANGE; in gem_set_hwtst()
514 if (copy_to_user(ifr->ifr_data, tstamp_config, sizeof(*tstamp_config))) in gem_set_hwtst()
515 return -EFAULT; in gem_set_hwtst()