Merge git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers.git
[platform/kernel/linux-starfive.git] / drivers / net / ethernet / mscc / ocelot_ptp.c
1 // SPDX-License-Identifier: (GPL-2.0 OR MIT)
2 /* Microsemi Ocelot PTP clock driver
3  *
4  * Copyright (c) 2017 Microsemi Corporation
5  * Copyright 2020 NXP
6  */
7 #include <soc/mscc/ocelot_ptp.h>
8 #include <soc/mscc/ocelot_sys.h>
9 #include <soc/mscc/ocelot.h>
10
11 int ocelot_ptp_gettime64(struct ptp_clock_info *ptp, struct timespec64 *ts)
12 {
13         struct ocelot *ocelot = container_of(ptp, struct ocelot, ptp_info);
14         unsigned long flags;
15         time64_t s;
16         u32 val;
17         s64 ns;
18
19         spin_lock_irqsave(&ocelot->ptp_clock_lock, flags);
20
21         val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN);
22         val &= ~(PTP_PIN_CFG_SYNC | PTP_PIN_CFG_ACTION_MASK | PTP_PIN_CFG_DOM);
23         val |= PTP_PIN_CFG_ACTION(PTP_PIN_ACTION_SAVE);
24         ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN);
25
26         s = ocelot_read_rix(ocelot, PTP_PIN_TOD_SEC_MSB, TOD_ACC_PIN) & 0xffff;
27         s <<= 32;
28         s += ocelot_read_rix(ocelot, PTP_PIN_TOD_SEC_LSB, TOD_ACC_PIN);
29         ns = ocelot_read_rix(ocelot, PTP_PIN_TOD_NSEC, TOD_ACC_PIN);
30
31         spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags);
32
33         /* Deal with negative values */
34         if (ns >= 0x3ffffff0 && ns <= 0x3fffffff) {
35                 s--;
36                 ns &= 0xf;
37                 ns += 999999984;
38         }
39
40         set_normalized_timespec64(ts, s, ns);
41         return 0;
42 }
43 EXPORT_SYMBOL(ocelot_ptp_gettime64);
44
45 int ocelot_ptp_settime64(struct ptp_clock_info *ptp,
46                          const struct timespec64 *ts)
47 {
48         struct ocelot *ocelot = container_of(ptp, struct ocelot, ptp_info);
49         unsigned long flags;
50         u32 val;
51
52         spin_lock_irqsave(&ocelot->ptp_clock_lock, flags);
53
54         val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN);
55         val &= ~(PTP_PIN_CFG_SYNC | PTP_PIN_CFG_ACTION_MASK | PTP_PIN_CFG_DOM);
56         val |= PTP_PIN_CFG_ACTION(PTP_PIN_ACTION_IDLE);
57
58         ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN);
59
60         ocelot_write_rix(ocelot, lower_32_bits(ts->tv_sec), PTP_PIN_TOD_SEC_LSB,
61                          TOD_ACC_PIN);
62         ocelot_write_rix(ocelot, upper_32_bits(ts->tv_sec), PTP_PIN_TOD_SEC_MSB,
63                          TOD_ACC_PIN);
64         ocelot_write_rix(ocelot, ts->tv_nsec, PTP_PIN_TOD_NSEC, TOD_ACC_PIN);
65
66         val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN);
67         val &= ~(PTP_PIN_CFG_SYNC | PTP_PIN_CFG_ACTION_MASK | PTP_PIN_CFG_DOM);
68         val |= PTP_PIN_CFG_ACTION(PTP_PIN_ACTION_LOAD);
69
70         ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN);
71
72         spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags);
73         return 0;
74 }
75 EXPORT_SYMBOL(ocelot_ptp_settime64);
76
77 int ocelot_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
78 {
79         if (delta > -(NSEC_PER_SEC / 2) && delta < (NSEC_PER_SEC / 2)) {
80                 struct ocelot *ocelot = container_of(ptp, struct ocelot,
81                                                      ptp_info);
82                 unsigned long flags;
83                 u32 val;
84
85                 spin_lock_irqsave(&ocelot->ptp_clock_lock, flags);
86
87                 val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN);
88                 val &= ~(PTP_PIN_CFG_SYNC | PTP_PIN_CFG_ACTION_MASK |
89                          PTP_PIN_CFG_DOM);
90                 val |= PTP_PIN_CFG_ACTION(PTP_PIN_ACTION_IDLE);
91
92                 ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN);
93
94                 ocelot_write_rix(ocelot, 0, PTP_PIN_TOD_SEC_LSB, TOD_ACC_PIN);
95                 ocelot_write_rix(ocelot, 0, PTP_PIN_TOD_SEC_MSB, TOD_ACC_PIN);
96                 ocelot_write_rix(ocelot, delta, PTP_PIN_TOD_NSEC, TOD_ACC_PIN);
97
98                 val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN);
99                 val &= ~(PTP_PIN_CFG_SYNC | PTP_PIN_CFG_ACTION_MASK |
100                          PTP_PIN_CFG_DOM);
101                 val |= PTP_PIN_CFG_ACTION(PTP_PIN_ACTION_DELTA);
102
103                 ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN);
104
105                 spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags);
106         } else {
107                 /* Fall back using ocelot_ptp_settime64 which is not exact. */
108                 struct timespec64 ts;
109                 u64 now;
110
111                 ocelot_ptp_gettime64(ptp, &ts);
112
113                 now = ktime_to_ns(timespec64_to_ktime(ts));
114                 ts = ns_to_timespec64(now + delta);
115
116                 ocelot_ptp_settime64(ptp, &ts);
117         }
118         return 0;
119 }
120 EXPORT_SYMBOL(ocelot_ptp_adjtime);
121
122 int ocelot_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
123 {
124         struct ocelot *ocelot = container_of(ptp, struct ocelot, ptp_info);
125         u32 unit = 0, direction = 0;
126         unsigned long flags;
127         u64 adj = 0;
128
129         spin_lock_irqsave(&ocelot->ptp_clock_lock, flags);
130
131         if (!scaled_ppm)
132                 goto disable_adj;
133
134         if (scaled_ppm < 0) {
135                 direction = PTP_CFG_CLK_ADJ_CFG_DIR;
136                 scaled_ppm = -scaled_ppm;
137         }
138
139         adj = PSEC_PER_SEC << 16;
140         do_div(adj, scaled_ppm);
141         do_div(adj, 1000);
142
143         /* If the adjustment value is too large, use ns instead */
144         if (adj >= (1L << 30)) {
145                 unit = PTP_CFG_CLK_ADJ_FREQ_NS;
146                 do_div(adj, 1000);
147         }
148
149         /* Still too big */
150         if (adj >= (1L << 30))
151                 goto disable_adj;
152
153         ocelot_write(ocelot, unit | adj, PTP_CLK_CFG_ADJ_FREQ);
154         ocelot_write(ocelot, PTP_CFG_CLK_ADJ_CFG_ENA | direction,
155                      PTP_CLK_CFG_ADJ_CFG);
156
157         spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags);
158         return 0;
159
160 disable_adj:
161         ocelot_write(ocelot, 0, PTP_CLK_CFG_ADJ_CFG);
162
163         spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags);
164         return 0;
165 }
166 EXPORT_SYMBOL(ocelot_ptp_adjfine);
167
168 int ocelot_ptp_verify(struct ptp_clock_info *ptp, unsigned int pin,
169                       enum ptp_pin_function func, unsigned int chan)
170 {
171         switch (func) {
172         case PTP_PF_NONE:
173         case PTP_PF_PEROUT:
174                 break;
175         case PTP_PF_EXTTS:
176         case PTP_PF_PHYSYNC:
177                 return -1;
178         }
179         return 0;
180 }
181 EXPORT_SYMBOL(ocelot_ptp_verify);
182
183 int ocelot_ptp_enable(struct ptp_clock_info *ptp,
184                       struct ptp_clock_request *rq, int on)
185 {
186         struct ocelot *ocelot = container_of(ptp, struct ocelot, ptp_info);
187         struct timespec64 ts_phase, ts_period;
188         enum ocelot_ptp_pins ptp_pin;
189         unsigned long flags;
190         bool pps = false;
191         int pin = -1;
192         s64 wf_high;
193         s64 wf_low;
194         u32 val;
195
196         switch (rq->type) {
197         case PTP_CLK_REQ_PEROUT:
198                 /* Reject requests with unsupported flags */
199                 if (rq->perout.flags & ~(PTP_PEROUT_DUTY_CYCLE |
200                                          PTP_PEROUT_PHASE))
201                         return -EOPNOTSUPP;
202
203                 pin = ptp_find_pin(ocelot->ptp_clock, PTP_PF_PEROUT,
204                                    rq->perout.index);
205                 if (pin == 0)
206                         ptp_pin = PTP_PIN_0;
207                 else if (pin == 1)
208                         ptp_pin = PTP_PIN_1;
209                 else if (pin == 2)
210                         ptp_pin = PTP_PIN_2;
211                 else if (pin == 3)
212                         ptp_pin = PTP_PIN_3;
213                 else
214                         return -EBUSY;
215
216                 ts_period.tv_sec = rq->perout.period.sec;
217                 ts_period.tv_nsec = rq->perout.period.nsec;
218
219                 if (ts_period.tv_sec == 1 && ts_period.tv_nsec == 0)
220                         pps = true;
221
222                 /* Handle turning off */
223                 if (!on) {
224                         spin_lock_irqsave(&ocelot->ptp_clock_lock, flags);
225                         val = PTP_PIN_CFG_ACTION(PTP_PIN_ACTION_IDLE);
226                         ocelot_write_rix(ocelot, val, PTP_PIN_CFG, ptp_pin);
227                         spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags);
228                         break;
229                 }
230
231                 if (rq->perout.flags & PTP_PEROUT_PHASE) {
232                         ts_phase.tv_sec = rq->perout.phase.sec;
233                         ts_phase.tv_nsec = rq->perout.phase.nsec;
234                 } else {
235                         /* Compatibility */
236                         ts_phase.tv_sec = rq->perout.start.sec;
237                         ts_phase.tv_nsec = rq->perout.start.nsec;
238                 }
239                 if (ts_phase.tv_sec || (ts_phase.tv_nsec && !pps)) {
240                         dev_warn(ocelot->dev,
241                                  "Absolute start time not supported!\n");
242                         dev_warn(ocelot->dev,
243                                  "Accept nsec for PPS phase adjustment, otherwise start time should be 0 0.\n");
244                         return -EINVAL;
245                 }
246
247                 /* Calculate waveform high and low times */
248                 if (rq->perout.flags & PTP_PEROUT_DUTY_CYCLE) {
249                         struct timespec64 ts_on;
250
251                         ts_on.tv_sec = rq->perout.on.sec;
252                         ts_on.tv_nsec = rq->perout.on.nsec;
253
254                         wf_high = timespec64_to_ns(&ts_on);
255                 } else {
256                         if (pps) {
257                                 wf_high = 1000;
258                         } else {
259                                 wf_high = timespec64_to_ns(&ts_period);
260                                 wf_high = div_s64(wf_high, 2);
261                         }
262                 }
263
264                 wf_low = timespec64_to_ns(&ts_period);
265                 wf_low -= wf_high;
266
267                 /* Handle PPS request */
268                 if (pps) {
269                         spin_lock_irqsave(&ocelot->ptp_clock_lock, flags);
270                         ocelot_write_rix(ocelot, ts_phase.tv_nsec,
271                                          PTP_PIN_WF_LOW_PERIOD, ptp_pin);
272                         ocelot_write_rix(ocelot, wf_high,
273                                          PTP_PIN_WF_HIGH_PERIOD, ptp_pin);
274                         val = PTP_PIN_CFG_ACTION(PTP_PIN_ACTION_CLOCK);
275                         val |= PTP_PIN_CFG_SYNC;
276                         ocelot_write_rix(ocelot, val, PTP_PIN_CFG, ptp_pin);
277                         spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags);
278                         break;
279                 }
280
281                 /* Handle periodic clock */
282                 if (wf_high > 0x3fffffff || wf_high <= 0x6)
283                         return -EINVAL;
284                 if (wf_low > 0x3fffffff || wf_low <= 0x6)
285                         return -EINVAL;
286
287                 spin_lock_irqsave(&ocelot->ptp_clock_lock, flags);
288                 ocelot_write_rix(ocelot, wf_low, PTP_PIN_WF_LOW_PERIOD,
289                                  ptp_pin);
290                 ocelot_write_rix(ocelot, wf_high, PTP_PIN_WF_HIGH_PERIOD,
291                                  ptp_pin);
292                 val = PTP_PIN_CFG_ACTION(PTP_PIN_ACTION_CLOCK);
293                 ocelot_write_rix(ocelot, val, PTP_PIN_CFG, ptp_pin);
294                 spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags);
295                 break;
296         default:
297                 return -EOPNOTSUPP;
298         }
299         return 0;
300 }
301 EXPORT_SYMBOL(ocelot_ptp_enable);
302
303 int ocelot_init_timestamp(struct ocelot *ocelot, struct ptp_clock_info *info)
304 {
305         struct ptp_clock *ptp_clock;
306         int i;
307
308         ocelot->ptp_info = *info;
309
310         for (i = 0; i < OCELOT_PTP_PINS_NUM; i++) {
311                 struct ptp_pin_desc *p = &ocelot->ptp_pins[i];
312
313                 snprintf(p->name, sizeof(p->name), "switch_1588_dat%d", i);
314                 p->index = i;
315                 p->func = PTP_PF_NONE;
316         }
317
318         ocelot->ptp_info.pin_config = &ocelot->ptp_pins[0];
319
320         ptp_clock = ptp_clock_register(&ocelot->ptp_info, ocelot->dev);
321         if (IS_ERR(ptp_clock))
322                 return PTR_ERR(ptp_clock);
323         /* Check if PHC support is missing at the configuration level */
324         if (!ptp_clock)
325                 return 0;
326
327         ocelot->ptp_clock = ptp_clock;
328
329         ocelot_write(ocelot, SYS_PTP_CFG_PTP_STAMP_WID(30), SYS_PTP_CFG);
330         ocelot_write(ocelot, 0xffffffff, ANA_TABLES_PTP_ID_LOW);
331         ocelot_write(ocelot, 0xffffffff, ANA_TABLES_PTP_ID_HIGH);
332
333         ocelot_write(ocelot, PTP_CFG_MISC_PTP_EN, PTP_CFG_MISC);
334
335         /* There is no device reconfiguration, PTP Rx stamping is always
336          * enabled.
337          */
338         ocelot->hwtstamp_config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
339
340         return 0;
341 }
342 EXPORT_SYMBOL(ocelot_init_timestamp);
343
344 int ocelot_deinit_timestamp(struct ocelot *ocelot)
345 {
346         if (ocelot->ptp_clock)
347                 ptp_clock_unregister(ocelot->ptp_clock);
348         return 0;
349 }
350 EXPORT_SYMBOL(ocelot_deinit_timestamp);