.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /******************************************************************************* |
---|
2 | 3 | Copyright (C) 2013 Vayavya Labs Pvt Ltd |
---|
3 | 4 | |
---|
4 | 5 | This implements all the API for managing HW timestamp & PTP. |
---|
5 | 6 | |
---|
6 | | - This program is free software; you can redistribute it and/or modify it |
---|
7 | | - under the terms and conditions of the GNU General Public License, |
---|
8 | | - version 2, as published by the Free Software Foundation. |
---|
9 | | - |
---|
10 | | - This program is distributed in the hope it will be useful, but WITHOUT |
---|
11 | | - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
---|
12 | | - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
---|
13 | | - more details. |
---|
14 | | - |
---|
15 | | - The full GNU General Public License is included in this distribution in |
---|
16 | | - the file called "COPYING". |
---|
17 | 7 | |
---|
18 | 8 | Author: Rayagond Kokatanur <rayagond@vayavyalabs.com> |
---|
19 | 9 | Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> |
---|
20 | 10 | *******************************************************************************/ |
---|
21 | 11 | |
---|
22 | 12 | #include <linux/io.h> |
---|
| 13 | +#include <linux/iopoll.h> |
---|
23 | 14 | #include <linux/delay.h> |
---|
24 | 15 | #include "common.h" |
---|
25 | 16 | #include "stmmac_ptp.h" |
---|
.. | .. |
---|
53 | 44 | if (!(value & PTP_TCR_TSCTRLSSR)) |
---|
54 | 45 | data = (data * 1000) / 465; |
---|
55 | 46 | |
---|
56 | | - data &= PTP_SSIR_SSINC_MASK; |
---|
| 47 | + if (data > PTP_SSIR_SSINC_MAX) |
---|
| 48 | + data = PTP_SSIR_SSINC_MAX; |
---|
57 | 49 | |
---|
58 | 50 | reg_value = data; |
---|
59 | 51 | if (gmac4) |
---|
.. | .. |
---|
67 | 59 | |
---|
68 | 60 | static int init_systime(void __iomem *ioaddr, u32 sec, u32 nsec) |
---|
69 | 61 | { |
---|
70 | | - int limit; |
---|
71 | 62 | u32 value; |
---|
72 | 63 | |
---|
73 | 64 | writel(sec, ioaddr + PTP_STSUR); |
---|
.. | .. |
---|
78 | 69 | writel(value, ioaddr + PTP_TCR); |
---|
79 | 70 | |
---|
80 | 71 | /* wait for present system time initialize to complete */ |
---|
81 | | - limit = 10; |
---|
82 | | - while (limit--) { |
---|
83 | | - if (!(readl(ioaddr + PTP_TCR) & PTP_TCR_TSINIT)) |
---|
84 | | - break; |
---|
85 | | - mdelay(10); |
---|
86 | | - } |
---|
87 | | - if (limit < 0) |
---|
88 | | - return -EBUSY; |
---|
89 | | - |
---|
90 | | - return 0; |
---|
| 72 | + return readl_poll_timeout_atomic(ioaddr + PTP_TCR, value, |
---|
| 73 | + !(value & PTP_TCR_TSINIT), |
---|
| 74 | + 10, 100000); |
---|
91 | 75 | } |
---|
92 | 76 | |
---|
93 | 77 | static int config_addend(void __iomem *ioaddr, u32 addend) |
---|
.. | .. |
---|
159 | 143 | |
---|
160 | 144 | static void get_systime(void __iomem *ioaddr, u64 *systime) |
---|
161 | 145 | { |
---|
162 | | - u64 ns; |
---|
| 146 | + u64 ns, sec0, sec1; |
---|
163 | 147 | |
---|
164 | | - /* Get the TSSS value */ |
---|
165 | | - ns = readl(ioaddr + PTP_STNSR); |
---|
166 | | - /* Get the TSS and convert sec time value to nanosecond */ |
---|
167 | | - ns += readl(ioaddr + PTP_STSR) * 1000000000ULL; |
---|
| 148 | + /* Get the TSS value */ |
---|
| 149 | + sec1 = readl_relaxed(ioaddr + PTP_STSR); |
---|
| 150 | + do { |
---|
| 151 | + sec0 = sec1; |
---|
| 152 | + /* Get the TSSS value */ |
---|
| 153 | + ns = readl_relaxed(ioaddr + PTP_STNSR); |
---|
| 154 | + /* Get the TSS value */ |
---|
| 155 | + sec1 = readl_relaxed(ioaddr + PTP_STSR); |
---|
| 156 | + } while (sec0 != sec1); |
---|
168 | 157 | |
---|
169 | 158 | if (systime) |
---|
170 | | - *systime = ns; |
---|
| 159 | + *systime = ns + (sec1 * 1000000000ULL); |
---|
171 | 160 | } |
---|
172 | 161 | |
---|
173 | 162 | const struct stmmac_hwtimestamp stmmac_ptp = { |
---|