ptp.c (8858ccc837e6e89c917f4b4bb1d7335d62e1baab) ptp.c (7150961487c5b4521ef5b6557373546e370709d2)
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Marvell 88E6xxx Switch PTP support
4 *
5 * Copyright (c) 2008 Marvell Semiconductor
6 *
7 * Copyright (c) 2017 National Instruments
8 * Erik Hons <erik.hons@ni.com>
9 * Brandon Streiff <brandon.streiff@ni.com>
10 * Dane Wagner <dane.wagner@ni.com>
11 */
12
13#include "chip.h"
14#include "global2.h"
15#include "hwtstamp.h"
16#include "ptp.h"
17
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Marvell 88E6xxx Switch PTP support
4 *
5 * Copyright (c) 2008 Marvell Semiconductor
6 *
7 * Copyright (c) 2017 National Instruments
8 * Erik Hons <erik.hons@ni.com>
9 * Brandon Streiff <brandon.streiff@ni.com>
10 * Dane Wagner <dane.wagner@ni.com>
11 */
12
13#include "chip.h"
14#include "global2.h"
15#include "hwtstamp.h"
16#include "ptp.h"
17
18/* Raw timestamps are in units of 8-ns clock periods. */
19#define CC_SHIFT 28
20#define CC_MULT (8 << CC_SHIFT)
21#define CC_MULT_NUM (1 << 9)
22#define CC_MULT_DEM 15625ULL
18#define MV88E6XXX_MAX_ADJ_PPB 1000000
23
19
20/* Family MV88E6250:
21 * Raw timestamps are in units of 10-ns clock periods.
22 *
23 * clkadj = scaled_ppm * 10*2^28 / (10^6 * 2^16)
24 * simplifies to
25 * clkadj = scaled_ppm * 2^7 / 5^5
26 */
27#define MV88E6250_CC_SHIFT 28
28#define MV88E6250_CC_MULT (10 << MV88E6250_CC_SHIFT)
29#define MV88E6250_CC_MULT_NUM (1 << 7)
30#define MV88E6250_CC_MULT_DEM 3125ULL
31
32/* Other families:
33 * Raw timestamps are in units of 8-ns clock periods.
34 *
35 * clkadj = scaled_ppm * 8*2^28 / (10^6 * 2^16)
36 * simplifies to
37 * clkadj = scaled_ppm * 2^9 / 5^6
38 */
39#define MV88E6XXX_CC_SHIFT 28
40#define MV88E6XXX_CC_MULT (8 << MV88E6XXX_CC_SHIFT)
41#define MV88E6XXX_CC_MULT_NUM (1 << 9)
42#define MV88E6XXX_CC_MULT_DEM 15625ULL
43
24#define TAI_EVENT_WORK_INTERVAL msecs_to_jiffies(100)
25
26#define cc_to_chip(cc) container_of(cc, struct mv88e6xxx_chip, tstamp_cc)
27#define dw_overflow_to_chip(dw) container_of(dw, struct mv88e6xxx_chip, \
28 overflow_work)
29#define dw_tai_event_to_chip(dw) container_of(dw, struct mv88e6xxx_chip, \
30 tai_event_work)
31

--- 142 unchanged lines hidden (view full) ---

174 ptp_clock_event(chip->ptp_clock, &ev);
175out:
176 schedule_delayed_work(&chip->tai_event_work, TAI_EVENT_WORK_INTERVAL);
177}
178
179static int mv88e6xxx_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
180{
181 struct mv88e6xxx_chip *chip = ptp_to_chip(ptp);
44#define TAI_EVENT_WORK_INTERVAL msecs_to_jiffies(100)
45
46#define cc_to_chip(cc) container_of(cc, struct mv88e6xxx_chip, tstamp_cc)
47#define dw_overflow_to_chip(dw) container_of(dw, struct mv88e6xxx_chip, \
48 overflow_work)
49#define dw_tai_event_to_chip(dw) container_of(dw, struct mv88e6xxx_chip, \
50 tai_event_work)
51

--- 142 unchanged lines hidden (view full) ---

194 ptp_clock_event(chip->ptp_clock, &ev);
195out:
196 schedule_delayed_work(&chip->tai_event_work, TAI_EVENT_WORK_INTERVAL);
197}
198
199static int mv88e6xxx_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
200{
201 struct mv88e6xxx_chip *chip = ptp_to_chip(ptp);
202 const struct mv88e6xxx_ptp_ops *ptp_ops = chip->info->ops->ptp_ops;
182 int neg_adj = 0;
183 u32 diff, mult;
184 u64 adj;
185
186 if (scaled_ppm < 0) {
187 neg_adj = 1;
188 scaled_ppm = -scaled_ppm;
189 }
203 int neg_adj = 0;
204 u32 diff, mult;
205 u64 adj;
206
207 if (scaled_ppm < 0) {
208 neg_adj = 1;
209 scaled_ppm = -scaled_ppm;
210 }
190 mult = CC_MULT;
191 adj = CC_MULT_NUM;
211
212 mult = ptp_ops->cc_mult;
213 adj = ptp_ops->cc_mult_num;
192 adj *= scaled_ppm;
214 adj *= scaled_ppm;
193 diff = div_u64(adj, CC_MULT_DEM);
215 diff = div_u64(adj, ptp_ops->cc_mult_dem);
194
195 mv88e6xxx_reg_lock(chip);
196
197 timecounter_read(&chip->tstamp_tc);
198 chip->tstamp_cc.mult = neg_adj ? mult - diff : mult + diff;
199
200 mv88e6xxx_reg_unlock(chip);
201

--- 117 unchanged lines hidden (view full) ---

319 .dep_sts_reg = MV88E6165_PORT_PTP_DEP_STS,
320 .rx_filters = (1 << HWTSTAMP_FILTER_NONE) |
321 (1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
322 (1 << HWTSTAMP_FILTER_PTP_V2_L2_SYNC) |
323 (1 << HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ) |
324 (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) |
325 (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) |
326 (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ),
216
217 mv88e6xxx_reg_lock(chip);
218
219 timecounter_read(&chip->tstamp_tc);
220 chip->tstamp_cc.mult = neg_adj ? mult - diff : mult + diff;
221
222 mv88e6xxx_reg_unlock(chip);
223

--- 117 unchanged lines hidden (view full) ---

341 .dep_sts_reg = MV88E6165_PORT_PTP_DEP_STS,
342 .rx_filters = (1 << HWTSTAMP_FILTER_NONE) |
343 (1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
344 (1 << HWTSTAMP_FILTER_PTP_V2_L2_SYNC) |
345 (1 << HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ) |
346 (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) |
347 (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) |
348 (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ),
349 .cc_shift = MV88E6XXX_CC_SHIFT,
350 .cc_mult = MV88E6XXX_CC_MULT,
351 .cc_mult_num = MV88E6XXX_CC_MULT_NUM,
352 .cc_mult_dem = MV88E6XXX_CC_MULT_DEM,
327};
328
353};
354
355const struct mv88e6xxx_ptp_ops mv88e6250_ptp_ops = {
356 .clock_read = mv88e6352_ptp_clock_read,
357 .ptp_enable = mv88e6352_ptp_enable,
358 .ptp_verify = mv88e6352_ptp_verify,
359 .event_work = mv88e6352_tai_event_work,
360 .port_enable = mv88e6352_hwtstamp_port_enable,
361 .port_disable = mv88e6352_hwtstamp_port_disable,
362 .n_ext_ts = 1,
363 .arr0_sts_reg = MV88E6XXX_PORT_PTP_ARR0_STS,
364 .arr1_sts_reg = MV88E6XXX_PORT_PTP_ARR1_STS,
365 .dep_sts_reg = MV88E6XXX_PORT_PTP_DEP_STS,
366 .rx_filters = (1 << HWTSTAMP_FILTER_NONE) |
367 (1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT) |
368 (1 << HWTSTAMP_FILTER_PTP_V2_L4_SYNC) |
369 (1 << HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ) |
370 (1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
371 (1 << HWTSTAMP_FILTER_PTP_V2_L2_SYNC) |
372 (1 << HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ) |
373 (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) |
374 (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) |
375 (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ),
376 .cc_shift = MV88E6250_CC_SHIFT,
377 .cc_mult = MV88E6250_CC_MULT,
378 .cc_mult_num = MV88E6250_CC_MULT_NUM,
379 .cc_mult_dem = MV88E6250_CC_MULT_DEM,
380};
381
329const struct mv88e6xxx_ptp_ops mv88e6352_ptp_ops = {
330 .clock_read = mv88e6352_ptp_clock_read,
331 .ptp_enable = mv88e6352_ptp_enable,
332 .ptp_verify = mv88e6352_ptp_verify,
333 .event_work = mv88e6352_tai_event_work,
334 .port_enable = mv88e6352_hwtstamp_port_enable,
335 .port_disable = mv88e6352_hwtstamp_port_disable,
336 .n_ext_ts = 1,

--- 5 unchanged lines hidden (view full) ---

342 (1 << HWTSTAMP_FILTER_PTP_V2_L4_SYNC) |
343 (1 << HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ) |
344 (1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
345 (1 << HWTSTAMP_FILTER_PTP_V2_L2_SYNC) |
346 (1 << HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ) |
347 (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) |
348 (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) |
349 (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ),
382const struct mv88e6xxx_ptp_ops mv88e6352_ptp_ops = {
383 .clock_read = mv88e6352_ptp_clock_read,
384 .ptp_enable = mv88e6352_ptp_enable,
385 .ptp_verify = mv88e6352_ptp_verify,
386 .event_work = mv88e6352_tai_event_work,
387 .port_enable = mv88e6352_hwtstamp_port_enable,
388 .port_disable = mv88e6352_hwtstamp_port_disable,
389 .n_ext_ts = 1,

--- 5 unchanged lines hidden (view full) ---

395 (1 << HWTSTAMP_FILTER_PTP_V2_L4_SYNC) |
396 (1 << HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ) |
397 (1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
398 (1 << HWTSTAMP_FILTER_PTP_V2_L2_SYNC) |
399 (1 << HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ) |
400 (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) |
401 (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) |
402 (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ),
403 .cc_shift = MV88E6XXX_CC_SHIFT,
404 .cc_mult = MV88E6XXX_CC_MULT,
405 .cc_mult_num = MV88E6XXX_CC_MULT_NUM,
406 .cc_mult_dem = MV88E6XXX_CC_MULT_DEM,
350};
351
352static u64 mv88e6xxx_ptp_clock_read(const struct cyclecounter *cc)
353{
354 struct mv88e6xxx_chip *chip = cc_to_chip(cc);
355
356 if (chip->info->ops->ptp_ops->clock_read)
357 return chip->info->ops->ptp_ops->clock_read(cc);

--- 21 unchanged lines hidden (view full) ---

379{
380 const struct mv88e6xxx_ptp_ops *ptp_ops = chip->info->ops->ptp_ops;
381 int i;
382
383 /* Set up the cycle counter */
384 memset(&chip->tstamp_cc, 0, sizeof(chip->tstamp_cc));
385 chip->tstamp_cc.read = mv88e6xxx_ptp_clock_read;
386 chip->tstamp_cc.mask = CYCLECOUNTER_MASK(32);
407};
408
409static u64 mv88e6xxx_ptp_clock_read(const struct cyclecounter *cc)
410{
411 struct mv88e6xxx_chip *chip = cc_to_chip(cc);
412
413 if (chip->info->ops->ptp_ops->clock_read)
414 return chip->info->ops->ptp_ops->clock_read(cc);

--- 21 unchanged lines hidden (view full) ---

436{
437 const struct mv88e6xxx_ptp_ops *ptp_ops = chip->info->ops->ptp_ops;
438 int i;
439
440 /* Set up the cycle counter */
441 memset(&chip->tstamp_cc, 0, sizeof(chip->tstamp_cc));
442 chip->tstamp_cc.read = mv88e6xxx_ptp_clock_read;
443 chip->tstamp_cc.mask = CYCLECOUNTER_MASK(32);
387 chip->tstamp_cc.mult = CC_MULT;
388 chip->tstamp_cc.shift = CC_SHIFT;
444 chip->tstamp_cc.mult = ptp_ops->cc_mult;
445 chip->tstamp_cc.shift = ptp_ops->cc_shift;
389
390 timecounter_init(&chip->tstamp_tc, &chip->tstamp_cc,
391 ktime_to_ns(ktime_get_real()));
392
393 INIT_DELAYED_WORK(&chip->overflow_work, mv88e6xxx_ptp_overflow_check);
394 if (ptp_ops->event_work)
395 INIT_DELAYED_WORK(&chip->tai_event_work, ptp_ops->event_work);
396
397 chip->ptp_clock_info.owner = THIS_MODULE;
398 snprintf(chip->ptp_clock_info.name, sizeof(chip->ptp_clock_info.name),
399 "%s", dev_name(chip->dev));
446
447 timecounter_init(&chip->tstamp_tc, &chip->tstamp_cc,
448 ktime_to_ns(ktime_get_real()));
449
450 INIT_DELAYED_WORK(&chip->overflow_work, mv88e6xxx_ptp_overflow_check);
451 if (ptp_ops->event_work)
452 INIT_DELAYED_WORK(&chip->tai_event_work, ptp_ops->event_work);
453
454 chip->ptp_clock_info.owner = THIS_MODULE;
455 snprintf(chip->ptp_clock_info.name, sizeof(chip->ptp_clock_info.name),
456 "%s", dev_name(chip->dev));
400 chip->ptp_clock_info.max_adj = 1000000;
401
402 chip->ptp_clock_info.n_ext_ts = ptp_ops->n_ext_ts;
403 chip->ptp_clock_info.n_per_out = 0;
404 chip->ptp_clock_info.n_pins = mv88e6xxx_num_gpio(chip);
405 chip->ptp_clock_info.pps = 0;
406
407 for (i = 0; i < chip->ptp_clock_info.n_pins; ++i) {
408 struct ptp_pin_desc *ppd = &chip->pin_config[i];
409
410 snprintf(ppd->name, sizeof(ppd->name), "mv88e6xxx_gpio%d", i);
411 ppd->index = i;
412 ppd->func = PTP_PF_NONE;
413 }
414 chip->ptp_clock_info.pin_config = chip->pin_config;
415
457
458 chip->ptp_clock_info.n_ext_ts = ptp_ops->n_ext_ts;
459 chip->ptp_clock_info.n_per_out = 0;
460 chip->ptp_clock_info.n_pins = mv88e6xxx_num_gpio(chip);
461 chip->ptp_clock_info.pps = 0;
462
463 for (i = 0; i < chip->ptp_clock_info.n_pins; ++i) {
464 struct ptp_pin_desc *ppd = &chip->pin_config[i];
465
466 snprintf(ppd->name, sizeof(ppd->name), "mv88e6xxx_gpio%d", i);
467 ppd->index = i;
468 ppd->func = PTP_PF_NONE;
469 }
470 chip->ptp_clock_info.pin_config = chip->pin_config;
471
472 chip->ptp_clock_info.max_adj = MV88E6XXX_MAX_ADJ_PPB;
416 chip->ptp_clock_info.adjfine = mv88e6xxx_ptp_adjfine;
417 chip->ptp_clock_info.adjtime = mv88e6xxx_ptp_adjtime;
418 chip->ptp_clock_info.gettime64 = mv88e6xxx_ptp_gettime;
419 chip->ptp_clock_info.settime64 = mv88e6xxx_ptp_settime;
420 chip->ptp_clock_info.enable = ptp_ops->ptp_enable;
421 chip->ptp_clock_info.verify = ptp_ops->ptp_verify;
422 chip->ptp_clock_info.do_aux_work = mv88e6xxx_hwtstamp_work;
423

--- 21 unchanged lines hidden ---
473 chip->ptp_clock_info.adjfine = mv88e6xxx_ptp_adjfine;
474 chip->ptp_clock_info.adjtime = mv88e6xxx_ptp_adjtime;
475 chip->ptp_clock_info.gettime64 = mv88e6xxx_ptp_gettime;
476 chip->ptp_clock_info.settime64 = mv88e6xxx_ptp_settime;
477 chip->ptp_clock_info.enable = ptp_ops->ptp_enable;
478 chip->ptp_clock_info.verify = ptp_ops->ptp_verify;
479 chip->ptp_clock_info.do_aux_work = mv88e6xxx_hwtstamp_work;
480

--- 21 unchanged lines hidden ---