Merge branch 'for-4.16' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq
[sfrench/cifs-2.6.git] / drivers / net / ethernet / mellanox / mlx5 / core / lib / clock.c
1 /*
2  * Copyright (c) 2015, Mellanox Technologies. All rights reserved.
3  *
4  * This software is available to you under a choice of one of two
5  * licenses.  You may choose to be licensed under the terms of the GNU
6  * General Public License (GPL) Version 2, available from the file
7  * COPYING in the main directory of this source tree, or the
8  * OpenIB.org BSD license below:
9  *
10  *     Redistribution and use in source and binary forms, with or
11  *     without modification, are permitted provided that the following
12  *     conditions are met:
13  *
14  *      - Redistributions of source code must retain the above
15  *        copyright notice, this list of conditions and the following
16  *        disclaimer.
17  *
18  *      - Redistributions in binary form must reproduce the above
19  *        copyright notice, this list of conditions and the following
20  *        disclaimer in the documentation and/or other materials
21  *        provided with the distribution.
22  *
23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30  * SOFTWARE.
31  */
32
33 #include <linux/clocksource.h>
34 #include "en.h"
35
36 enum {
37         MLX5_CYCLES_SHIFT       = 23
38 };
39
40 enum {
41         MLX5_PIN_MODE_IN                = 0x0,
42         MLX5_PIN_MODE_OUT               = 0x1,
43 };
44
45 enum {
46         MLX5_OUT_PATTERN_PULSE          = 0x0,
47         MLX5_OUT_PATTERN_PERIODIC       = 0x1,
48 };
49
50 enum {
51         MLX5_EVENT_MODE_DISABLE = 0x0,
52         MLX5_EVENT_MODE_REPETETIVE      = 0x1,
53         MLX5_EVENT_MODE_ONCE_TILL_ARM   = 0x2,
54 };
55
56 enum {
57         MLX5_MTPPS_FS_ENABLE                    = BIT(0x0),
58         MLX5_MTPPS_FS_PATTERN                   = BIT(0x2),
59         MLX5_MTPPS_FS_PIN_MODE                  = BIT(0x3),
60         MLX5_MTPPS_FS_TIME_STAMP                = BIT(0x4),
61         MLX5_MTPPS_FS_OUT_PULSE_DURATION        = BIT(0x5),
62         MLX5_MTPPS_FS_ENH_OUT_PER_ADJ           = BIT(0x7),
63 };
64
65 static u64 read_internal_timer(const struct cyclecounter *cc)
66 {
67         struct mlx5_clock *clock = container_of(cc, struct mlx5_clock, cycles);
68         struct mlx5_core_dev *mdev = container_of(clock, struct mlx5_core_dev,
69                                                   clock);
70
71         return mlx5_read_internal_timer(mdev) & cc->mask;
72 }
73
74 static void mlx5_pps_out(struct work_struct *work)
75 {
76         struct mlx5_pps *pps_info = container_of(work, struct mlx5_pps,
77                                                  out_work);
78         struct mlx5_clock *clock = container_of(pps_info, struct mlx5_clock,
79                                                 pps_info);
80         struct mlx5_core_dev *mdev = container_of(clock, struct mlx5_core_dev,
81                                                   clock);
82         u32 in[MLX5_ST_SZ_DW(mtpps_reg)] = {0};
83         unsigned long flags;
84         int i;
85
86         for (i = 0; i < clock->ptp_info.n_pins; i++) {
87                 u64 tstart;
88
89                 write_lock_irqsave(&clock->lock, flags);
90                 tstart = clock->pps_info.start[i];
91                 clock->pps_info.start[i] = 0;
92                 write_unlock_irqrestore(&clock->lock, flags);
93                 if (!tstart)
94                         continue;
95
96                 MLX5_SET(mtpps_reg, in, pin, i);
97                 MLX5_SET64(mtpps_reg, in, time_stamp, tstart);
98                 MLX5_SET(mtpps_reg, in, field_select, MLX5_MTPPS_FS_TIME_STAMP);
99                 mlx5_set_mtpps(mdev, in, sizeof(in));
100         }
101 }
102
103 static void mlx5_timestamp_overflow(struct work_struct *work)
104 {
105         struct delayed_work *dwork = to_delayed_work(work);
106         struct mlx5_clock *clock = container_of(dwork, struct mlx5_clock,
107                                                 overflow_work);
108         unsigned long flags;
109
110         write_lock_irqsave(&clock->lock, flags);
111         timecounter_read(&clock->tc);
112         write_unlock_irqrestore(&clock->lock, flags);
113         schedule_delayed_work(&clock->overflow_work, clock->overflow_period);
114 }
115
116 static int mlx5_ptp_settime(struct ptp_clock_info *ptp,
117                             const struct timespec64 *ts)
118 {
119         struct mlx5_clock *clock = container_of(ptp, struct mlx5_clock,
120                                                  ptp_info);
121         u64 ns = timespec64_to_ns(ts);
122         unsigned long flags;
123
124         write_lock_irqsave(&clock->lock, flags);
125         timecounter_init(&clock->tc, &clock->cycles, ns);
126         write_unlock_irqrestore(&clock->lock, flags);
127
128         return 0;
129 }
130
131 static int mlx5_ptp_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)
132 {
133         struct mlx5_clock *clock = container_of(ptp, struct mlx5_clock,
134                                                 ptp_info);
135         u64 ns;
136         unsigned long flags;
137
138         write_lock_irqsave(&clock->lock, flags);
139         ns = timecounter_read(&clock->tc);
140         write_unlock_irqrestore(&clock->lock, flags);
141
142         *ts = ns_to_timespec64(ns);
143
144         return 0;
145 }
146
147 static int mlx5_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
148 {
149         struct mlx5_clock *clock = container_of(ptp, struct mlx5_clock,
150                                                 ptp_info);
151         unsigned long flags;
152
153         write_lock_irqsave(&clock->lock, flags);
154         timecounter_adjtime(&clock->tc, delta);
155         write_unlock_irqrestore(&clock->lock, flags);
156
157         return 0;
158 }
159
160 static int mlx5_ptp_adjfreq(struct ptp_clock_info *ptp, s32 delta)
161 {
162         u64 adj;
163         u32 diff;
164         unsigned long flags;
165         int neg_adj = 0;
166         struct mlx5_clock *clock = container_of(ptp, struct mlx5_clock,
167                                                 ptp_info);
168
169         if (delta < 0) {
170                 neg_adj = 1;
171                 delta = -delta;
172         }
173
174         adj = clock->nominal_c_mult;
175         adj *= delta;
176         diff = div_u64(adj, 1000000000ULL);
177
178         write_lock_irqsave(&clock->lock, flags);
179         timecounter_read(&clock->tc);
180         clock->cycles.mult = neg_adj ? clock->nominal_c_mult - diff :
181                                        clock->nominal_c_mult + diff;
182         write_unlock_irqrestore(&clock->lock, flags);
183
184         return 0;
185 }
186
187 static int mlx5_extts_configure(struct ptp_clock_info *ptp,
188                                 struct ptp_clock_request *rq,
189                                 int on)
190 {
191         struct mlx5_clock *clock =
192                         container_of(ptp, struct mlx5_clock, ptp_info);
193         struct mlx5_core_dev *mdev =
194                         container_of(clock, struct mlx5_core_dev, clock);
195         u32 in[MLX5_ST_SZ_DW(mtpps_reg)] = {0};
196         u32 field_select = 0;
197         u8 pin_mode = 0;
198         u8 pattern = 0;
199         int pin = -1;
200         int err = 0;
201
202         if (!MLX5_PPS_CAP(mdev))
203                 return -EOPNOTSUPP;
204
205         if (rq->extts.index >= clock->ptp_info.n_pins)
206                 return -EINVAL;
207
208         if (on) {
209                 pin = ptp_find_pin(clock->ptp, PTP_PF_EXTTS, rq->extts.index);
210                 if (pin < 0)
211                         return -EBUSY;
212                 pin_mode = MLX5_PIN_MODE_IN;
213                 pattern = !!(rq->extts.flags & PTP_FALLING_EDGE);
214                 field_select = MLX5_MTPPS_FS_PIN_MODE |
215                                MLX5_MTPPS_FS_PATTERN |
216                                MLX5_MTPPS_FS_ENABLE;
217         } else {
218                 pin = rq->extts.index;
219                 field_select = MLX5_MTPPS_FS_ENABLE;
220         }
221
222         MLX5_SET(mtpps_reg, in, pin, pin);
223         MLX5_SET(mtpps_reg, in, pin_mode, pin_mode);
224         MLX5_SET(mtpps_reg, in, pattern, pattern);
225         MLX5_SET(mtpps_reg, in, enable, on);
226         MLX5_SET(mtpps_reg, in, field_select, field_select);
227
228         err = mlx5_set_mtpps(mdev, in, sizeof(in));
229         if (err)
230                 return err;
231
232         return mlx5_set_mtppse(mdev, pin, 0,
233                                MLX5_EVENT_MODE_REPETETIVE & on);
234 }
235
236 static int mlx5_perout_configure(struct ptp_clock_info *ptp,
237                                  struct ptp_clock_request *rq,
238                                  int on)
239 {
240         struct mlx5_clock *clock =
241                         container_of(ptp, struct mlx5_clock, ptp_info);
242         struct mlx5_core_dev *mdev =
243                         container_of(clock, struct mlx5_core_dev, clock);
244         u32 in[MLX5_ST_SZ_DW(mtpps_reg)] = {0};
245         u64 nsec_now, nsec_delta, time_stamp = 0;
246         u64 cycles_now, cycles_delta;
247         struct timespec64 ts;
248         unsigned long flags;
249         u32 field_select = 0;
250         u8 pin_mode = 0;
251         u8 pattern = 0;
252         int pin = -1;
253         int err = 0;
254         s64 ns;
255
256         if (!MLX5_PPS_CAP(mdev))
257                 return -EOPNOTSUPP;
258
259         if (rq->perout.index >= clock->ptp_info.n_pins)
260                 return -EINVAL;
261
262         if (on) {
263                 pin = ptp_find_pin(clock->ptp, PTP_PF_PEROUT,
264                                    rq->perout.index);
265                 if (pin < 0)
266                         return -EBUSY;
267
268                 pin_mode = MLX5_PIN_MODE_OUT;
269                 pattern = MLX5_OUT_PATTERN_PERIODIC;
270                 ts.tv_sec = rq->perout.period.sec;
271                 ts.tv_nsec = rq->perout.period.nsec;
272                 ns = timespec64_to_ns(&ts);
273
274                 if ((ns >> 1) != 500000000LL)
275                         return -EINVAL;
276
277                 ts.tv_sec = rq->perout.start.sec;
278                 ts.tv_nsec = rq->perout.start.nsec;
279                 ns = timespec64_to_ns(&ts);
280                 cycles_now = mlx5_read_internal_timer(mdev);
281                 write_lock_irqsave(&clock->lock, flags);
282                 nsec_now = timecounter_cyc2time(&clock->tc, cycles_now);
283                 nsec_delta = ns - nsec_now;
284                 cycles_delta = div64_u64(nsec_delta << clock->cycles.shift,
285                                          clock->cycles.mult);
286                 write_unlock_irqrestore(&clock->lock, flags);
287                 time_stamp = cycles_now + cycles_delta;
288                 field_select = MLX5_MTPPS_FS_PIN_MODE |
289                                MLX5_MTPPS_FS_PATTERN |
290                                MLX5_MTPPS_FS_ENABLE |
291                                MLX5_MTPPS_FS_TIME_STAMP;
292         } else {
293                 pin = rq->perout.index;
294                 field_select = MLX5_MTPPS_FS_ENABLE;
295         }
296
297         MLX5_SET(mtpps_reg, in, pin, pin);
298         MLX5_SET(mtpps_reg, in, pin_mode, pin_mode);
299         MLX5_SET(mtpps_reg, in, pattern, pattern);
300         MLX5_SET(mtpps_reg, in, enable, on);
301         MLX5_SET64(mtpps_reg, in, time_stamp, time_stamp);
302         MLX5_SET(mtpps_reg, in, field_select, field_select);
303
304         err = mlx5_set_mtpps(mdev, in, sizeof(in));
305         if (err)
306                 return err;
307
308         return mlx5_set_mtppse(mdev, pin, 0,
309                                MLX5_EVENT_MODE_REPETETIVE & on);
310 }
311
312 static int mlx5_pps_configure(struct ptp_clock_info *ptp,
313                               struct ptp_clock_request *rq,
314                               int on)
315 {
316         struct mlx5_clock *clock =
317                         container_of(ptp, struct mlx5_clock, ptp_info);
318
319         clock->pps_info.enabled = !!on;
320         return 0;
321 }
322
323 static int mlx5_ptp_enable(struct ptp_clock_info *ptp,
324                            struct ptp_clock_request *rq,
325                            int on)
326 {
327         switch (rq->type) {
328         case PTP_CLK_REQ_EXTTS:
329                 return mlx5_extts_configure(ptp, rq, on);
330         case PTP_CLK_REQ_PEROUT:
331                 return mlx5_perout_configure(ptp, rq, on);
332         case PTP_CLK_REQ_PPS:
333                 return mlx5_pps_configure(ptp, rq, on);
334         default:
335                 return -EOPNOTSUPP;
336         }
337         return 0;
338 }
339
340 static int mlx5_ptp_verify(struct ptp_clock_info *ptp, unsigned int pin,
341                            enum ptp_pin_function func, unsigned int chan)
342 {
343         return (func == PTP_PF_PHYSYNC) ? -EOPNOTSUPP : 0;
344 }
345
346 static const struct ptp_clock_info mlx5_ptp_clock_info = {
347         .owner          = THIS_MODULE,
348         .name           = "mlx5_p2p",
349         .max_adj        = 100000000,
350         .n_alarm        = 0,
351         .n_ext_ts       = 0,
352         .n_per_out      = 0,
353         .n_pins         = 0,
354         .pps            = 0,
355         .adjfreq        = mlx5_ptp_adjfreq,
356         .adjtime        = mlx5_ptp_adjtime,
357         .gettime64      = mlx5_ptp_gettime,
358         .settime64      = mlx5_ptp_settime,
359         .enable         = NULL,
360         .verify         = NULL,
361 };
362
363 static int mlx5_init_pin_config(struct mlx5_clock *clock)
364 {
365         int i;
366
367         clock->ptp_info.pin_config =
368                         kzalloc(sizeof(*clock->ptp_info.pin_config) *
369                                 clock->ptp_info.n_pins, GFP_KERNEL);
370         if (!clock->ptp_info.pin_config)
371                 return -ENOMEM;
372         clock->ptp_info.enable = mlx5_ptp_enable;
373         clock->ptp_info.verify = mlx5_ptp_verify;
374         clock->ptp_info.pps = 1;
375
376         for (i = 0; i < clock->ptp_info.n_pins; i++) {
377                 snprintf(clock->ptp_info.pin_config[i].name,
378                          sizeof(clock->ptp_info.pin_config[i].name),
379                          "mlx5_pps%d", i);
380                 clock->ptp_info.pin_config[i].index = i;
381                 clock->ptp_info.pin_config[i].func = PTP_PF_NONE;
382                 clock->ptp_info.pin_config[i].chan = i;
383         }
384
385         return 0;
386 }
387
388 static void mlx5_get_pps_caps(struct mlx5_core_dev *mdev)
389 {
390         struct mlx5_clock *clock = &mdev->clock;
391         u32 out[MLX5_ST_SZ_DW(mtpps_reg)] = {0};
392
393         mlx5_query_mtpps(mdev, out, sizeof(out));
394
395         clock->ptp_info.n_pins = MLX5_GET(mtpps_reg, out,
396                                           cap_number_of_pps_pins);
397         clock->ptp_info.n_ext_ts = MLX5_GET(mtpps_reg, out,
398                                             cap_max_num_of_pps_in_pins);
399         clock->ptp_info.n_per_out = MLX5_GET(mtpps_reg, out,
400                                              cap_max_num_of_pps_out_pins);
401
402         clock->pps_info.pin_caps[0] = MLX5_GET(mtpps_reg, out, cap_pin_0_mode);
403         clock->pps_info.pin_caps[1] = MLX5_GET(mtpps_reg, out, cap_pin_1_mode);
404         clock->pps_info.pin_caps[2] = MLX5_GET(mtpps_reg, out, cap_pin_2_mode);
405         clock->pps_info.pin_caps[3] = MLX5_GET(mtpps_reg, out, cap_pin_3_mode);
406         clock->pps_info.pin_caps[4] = MLX5_GET(mtpps_reg, out, cap_pin_4_mode);
407         clock->pps_info.pin_caps[5] = MLX5_GET(mtpps_reg, out, cap_pin_5_mode);
408         clock->pps_info.pin_caps[6] = MLX5_GET(mtpps_reg, out, cap_pin_6_mode);
409         clock->pps_info.pin_caps[7] = MLX5_GET(mtpps_reg, out, cap_pin_7_mode);
410 }
411
412 void mlx5_pps_event(struct mlx5_core_dev *mdev,
413                     struct mlx5_eqe *eqe)
414 {
415         struct mlx5_clock *clock = &mdev->clock;
416         struct ptp_clock_event ptp_event;
417         struct timespec64 ts;
418         u64 nsec_now, nsec_delta;
419         u64 cycles_now, cycles_delta;
420         int pin = eqe->data.pps.pin;
421         s64 ns;
422         unsigned long flags;
423
424         switch (clock->ptp_info.pin_config[pin].func) {
425         case PTP_PF_EXTTS:
426                 ptp_event.index = pin;
427                 ptp_event.timestamp = timecounter_cyc2time(&clock->tc,
428                                         be64_to_cpu(eqe->data.pps.time_stamp));
429                 if (clock->pps_info.enabled) {
430                         ptp_event.type = PTP_CLOCK_PPSUSR;
431                         ptp_event.pps_times.ts_real =
432                                         ns_to_timespec64(ptp_event.timestamp);
433                 } else {
434                         ptp_event.type = PTP_CLOCK_EXTTS;
435                 }
436                 ptp_clock_event(clock->ptp, &ptp_event);
437                 break;
438         case PTP_PF_PEROUT:
439                 mlx5_ptp_gettime(&clock->ptp_info, &ts);
440                 cycles_now = mlx5_read_internal_timer(mdev);
441                 ts.tv_sec += 1;
442                 ts.tv_nsec = 0;
443                 ns = timespec64_to_ns(&ts);
444                 write_lock_irqsave(&clock->lock, flags);
445                 nsec_now = timecounter_cyc2time(&clock->tc, cycles_now);
446                 nsec_delta = ns - nsec_now;
447                 cycles_delta = div64_u64(nsec_delta << clock->cycles.shift,
448                                          clock->cycles.mult);
449                 clock->pps_info.start[pin] = cycles_now + cycles_delta;
450                 schedule_work(&clock->pps_info.out_work);
451                 write_unlock_irqrestore(&clock->lock, flags);
452                 break;
453         default:
454                 mlx5_core_err(mdev, " Unhandled event\n");
455         }
456 }
457
458 void mlx5_init_clock(struct mlx5_core_dev *mdev)
459 {
460         struct mlx5_clock *clock = &mdev->clock;
461         u64 ns;
462         u64 frac = 0;
463         u32 dev_freq;
464
465         dev_freq = MLX5_CAP_GEN(mdev, device_frequency_khz);
466         if (!dev_freq) {
467                 mlx5_core_warn(mdev, "invalid device_frequency_khz, aborting HW clock init\n");
468                 return;
469         }
470         rwlock_init(&clock->lock);
471         clock->cycles.read = read_internal_timer;
472         clock->cycles.shift = MLX5_CYCLES_SHIFT;
473         clock->cycles.mult = clocksource_khz2mult(dev_freq,
474                                                   clock->cycles.shift);
475         clock->nominal_c_mult = clock->cycles.mult;
476         clock->cycles.mask = CLOCKSOURCE_MASK(41);
477
478         timecounter_init(&clock->tc, &clock->cycles,
479                          ktime_to_ns(ktime_get_real()));
480
481         /* Calculate period in seconds to call the overflow watchdog - to make
482          * sure counter is checked at least once every wrap around.
483          */
484         ns = cyclecounter_cyc2ns(&clock->cycles, clock->cycles.mask,
485                                  frac, &frac);
486         do_div(ns, NSEC_PER_SEC / 2 / HZ);
487         clock->overflow_period = ns;
488
489         INIT_WORK(&clock->pps_info.out_work, mlx5_pps_out);
490         INIT_DELAYED_WORK(&clock->overflow_work, mlx5_timestamp_overflow);
491         if (clock->overflow_period)
492                 schedule_delayed_work(&clock->overflow_work, 0);
493         else
494                 mlx5_core_warn(mdev, "invalid overflow period, overflow_work is not scheduled\n");
495
496         /* Configure the PHC */
497         clock->ptp_info = mlx5_ptp_clock_info;
498
499         /* Initialize 1PPS data structures */
500         if (MLX5_PPS_CAP(mdev))
501                 mlx5_get_pps_caps(mdev);
502         if (clock->ptp_info.n_pins)
503                 mlx5_init_pin_config(clock);
504
505         clock->ptp = ptp_clock_register(&clock->ptp_info,
506                                         &mdev->pdev->dev);
507         if (IS_ERR(clock->ptp)) {
508                 mlx5_core_warn(mdev, "ptp_clock_register failed %ld\n",
509                                PTR_ERR(clock->ptp));
510                 clock->ptp = NULL;
511         }
512 }
513
514 void mlx5_cleanup_clock(struct mlx5_core_dev *mdev)
515 {
516         struct mlx5_clock *clock = &mdev->clock;
517
518         if (!MLX5_CAP_GEN(mdev, device_frequency_khz))
519                 return;
520
521         if (clock->ptp) {
522                 ptp_clock_unregister(clock->ptp);
523                 clock->ptp = NULL;
524         }
525
526         cancel_work_sync(&clock->pps_info.out_work);
527         cancel_delayed_work_sync(&clock->overflow_work);
528         kfree(clock->ptp_info.pin_config);
529 }