1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Marvell 88E6xxx Switch PTP support
5 * Copyright (c) 2008 Marvell Semiconductor
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>
18 #define MV88E6XXX_MAX_ADJ_PPB 1000000
21 * Raw timestamps are in units of 10-ns clock periods.
23 * clkadj = scaled_ppm * 10*2^28 / (10^6 * 2^16)
25 * clkadj = scaled_ppm * 2^7 / 5^5
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
33 * Raw timestamps are in units of 8-ns clock periods.
35 * clkadj = scaled_ppm * 8*2^28 / (10^6 * 2^16)
37 * clkadj = scaled_ppm * 2^9 / 5^6
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
44 #define TAI_EVENT_WORK_INTERVAL msecs_to_jiffies(100)
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, \
49 #define dw_tai_event_to_chip(dw) container_of(dw, struct mv88e6xxx_chip, \
52 static int mv88e6xxx_tai_read(struct mv88e6xxx_chip
*chip
, int addr
,
55 if (!chip
->info
->ops
->avb_ops
->tai_read
)
58 return chip
->info
->ops
->avb_ops
->tai_read(chip
, addr
, data
, len
);
61 static int mv88e6xxx_tai_write(struct mv88e6xxx_chip
*chip
, int addr
, u16 data
)
63 if (!chip
->info
->ops
->avb_ops
->tai_write
)
66 return chip
->info
->ops
->avb_ops
->tai_write(chip
, addr
, data
);
69 /* TODO: places where this are called should be using pinctrl */
70 static int mv88e6352_set_gpio_func(struct mv88e6xxx_chip
*chip
, int pin
,
75 if (!chip
->info
->ops
->gpio_ops
)
78 err
= chip
->info
->ops
->gpio_ops
->set_dir(chip
, pin
, input
);
82 return chip
->info
->ops
->gpio_ops
->set_pctl(chip
, pin
, func
);
85 static u64
mv88e6352_ptp_clock_read(const struct cyclecounter
*cc
)
87 struct mv88e6xxx_chip
*chip
= cc_to_chip(cc
);
91 err
= mv88e6xxx_tai_read(chip
, MV88E6XXX_TAI_TIME_LO
, phc_time
,
92 ARRAY_SIZE(phc_time
));
96 return ((u32
)phc_time
[1] << 16) | phc_time
[0];
99 static u64
mv88e6165_ptp_clock_read(const struct cyclecounter
*cc
)
101 struct mv88e6xxx_chip
*chip
= cc_to_chip(cc
);
105 err
= mv88e6xxx_tai_read(chip
, MV88E6XXX_PTP_GC_TIME_LO
, phc_time
,
106 ARRAY_SIZE(phc_time
));
110 return ((u32
)phc_time
[1] << 16) | phc_time
[0];
113 /* mv88e6352_config_eventcap - configure TAI event capture
114 * @event: PTP_CLOCK_PPS (internal) or PTP_CLOCK_EXTTS (external)
115 * @rising: zero for falling-edge trigger, else rising-edge trigger
117 * This will also reset the capture sequence counter.
119 static int mv88e6352_config_eventcap(struct mv88e6xxx_chip
*chip
, int event
,
126 chip
->evcap_config
= MV88E6XXX_TAI_CFG_CAP_OVERWRITE
|
127 MV88E6XXX_TAI_CFG_CAP_CTR_START
;
129 chip
->evcap_config
|= MV88E6XXX_TAI_CFG_EVREQ_FALLING
;
131 global_config
= (chip
->evcap_config
| chip
->trig_config
);
132 err
= mv88e6xxx_tai_write(chip
, MV88E6XXX_TAI_CFG
, global_config
);
136 if (event
== PTP_CLOCK_PPS
) {
137 cap_config
= MV88E6XXX_TAI_EVENT_STATUS_CAP_TRIG
;
138 } else if (event
== PTP_CLOCK_EXTTS
) {
139 /* if STATUS_CAP_TRIG is unset we capture PTP_EVREQ events */
145 /* Write the capture config; this also clears the capture counter */
146 err
= mv88e6xxx_tai_write(chip
, MV88E6XXX_TAI_EVENT_STATUS
,
152 static void mv88e6352_tai_event_work(struct work_struct
*ugly
)
154 struct delayed_work
*dw
= to_delayed_work(ugly
);
155 struct mv88e6xxx_chip
*chip
= dw_tai_event_to_chip(dw
);
156 struct ptp_clock_event ev
;
161 mv88e6xxx_reg_lock(chip
);
162 err
= mv88e6xxx_tai_read(chip
, MV88E6XXX_TAI_EVENT_STATUS
,
163 status
, ARRAY_SIZE(status
));
164 mv88e6xxx_reg_unlock(chip
);
167 dev_err(chip
->dev
, "failed to read TAI status register\n");
170 if (status
[0] & MV88E6XXX_TAI_EVENT_STATUS_ERROR
) {
171 dev_warn(chip
->dev
, "missed event capture\n");
174 if (!(status
[0] & MV88E6XXX_TAI_EVENT_STATUS_VALID
))
177 raw_ts
= ((u32
)status
[2] << 16) | status
[1];
179 /* Clear the valid bit so the next timestamp can come in */
180 status
[0] &= ~MV88E6XXX_TAI_EVENT_STATUS_VALID
;
181 mv88e6xxx_reg_lock(chip
);
182 err
= mv88e6xxx_tai_write(chip
, MV88E6XXX_TAI_EVENT_STATUS
, status
[0]);
183 mv88e6xxx_reg_unlock(chip
);
185 /* This is an external timestamp */
186 ev
.type
= PTP_CLOCK_EXTTS
;
188 /* We only have one timestamping channel. */
190 mv88e6xxx_reg_lock(chip
);
191 ev
.timestamp
= timecounter_cyc2time(&chip
->tstamp_tc
, raw_ts
);
192 mv88e6xxx_reg_unlock(chip
);
194 ptp_clock_event(chip
->ptp_clock
, &ev
);
196 schedule_delayed_work(&chip
->tai_event_work
, TAI_EVENT_WORK_INTERVAL
);
199 static int mv88e6xxx_ptp_adjfine(struct ptp_clock_info
*ptp
, long scaled_ppm
)
201 struct mv88e6xxx_chip
*chip
= ptp_to_chip(ptp
);
202 const struct mv88e6xxx_ptp_ops
*ptp_ops
= chip
->info
->ops
->ptp_ops
;
207 if (scaled_ppm
< 0) {
209 scaled_ppm
= -scaled_ppm
;
212 mult
= ptp_ops
->cc_mult
;
213 adj
= ptp_ops
->cc_mult_num
;
215 diff
= div_u64(adj
, ptp_ops
->cc_mult_dem
);
217 mv88e6xxx_reg_lock(chip
);
219 timecounter_read(&chip
->tstamp_tc
);
220 chip
->tstamp_cc
.mult
= neg_adj
? mult
- diff
: mult
+ diff
;
222 mv88e6xxx_reg_unlock(chip
);
227 static int mv88e6xxx_ptp_adjtime(struct ptp_clock_info
*ptp
, s64 delta
)
229 struct mv88e6xxx_chip
*chip
= ptp_to_chip(ptp
);
231 mv88e6xxx_reg_lock(chip
);
232 timecounter_adjtime(&chip
->tstamp_tc
, delta
);
233 mv88e6xxx_reg_unlock(chip
);
238 static int mv88e6xxx_ptp_gettime(struct ptp_clock_info
*ptp
,
239 struct timespec64
*ts
)
241 struct mv88e6xxx_chip
*chip
= ptp_to_chip(ptp
);
244 mv88e6xxx_reg_lock(chip
);
245 ns
= timecounter_read(&chip
->tstamp_tc
);
246 mv88e6xxx_reg_unlock(chip
);
248 *ts
= ns_to_timespec64(ns
);
253 static int mv88e6xxx_ptp_settime(struct ptp_clock_info
*ptp
,
254 const struct timespec64
*ts
)
256 struct mv88e6xxx_chip
*chip
= ptp_to_chip(ptp
);
259 ns
= timespec64_to_ns(ts
);
261 mv88e6xxx_reg_lock(chip
);
262 timecounter_init(&chip
->tstamp_tc
, &chip
->tstamp_cc
, ns
);
263 mv88e6xxx_reg_unlock(chip
);
268 static int mv88e6352_ptp_enable_extts(struct mv88e6xxx_chip
*chip
,
269 struct ptp_clock_request
*rq
, int on
)
271 int rising
= (rq
->extts
.flags
& PTP_RISING_EDGE
);
276 /* Reject requests with unsupported flags */
277 if (rq
->extts
.flags
& ~(PTP_ENABLE_FEATURE
|
283 /* Reject requests to enable time stamping on both edges. */
284 if ((rq
->extts
.flags
& PTP_STRICT_FLAGS
) &&
285 (rq
->extts
.flags
& PTP_ENABLE_FEATURE
) &&
286 (rq
->extts
.flags
& PTP_EXTTS_EDGES
) == PTP_EXTTS_EDGES
)
289 pin
= ptp_find_pin(chip
->ptp_clock
, PTP_PF_EXTTS
, rq
->extts
.index
);
294 mv88e6xxx_reg_lock(chip
);
297 func
= MV88E6352_G2_SCRATCH_GPIO_PCTL_EVREQ
;
299 err
= mv88e6352_set_gpio_func(chip
, pin
, func
, true);
303 schedule_delayed_work(&chip
->tai_event_work
,
304 TAI_EVENT_WORK_INTERVAL
);
306 err
= mv88e6352_config_eventcap(chip
, PTP_CLOCK_EXTTS
, rising
);
308 func
= MV88E6352_G2_SCRATCH_GPIO_PCTL_GPIO
;
310 err
= mv88e6352_set_gpio_func(chip
, pin
, func
, true);
312 cancel_delayed_work_sync(&chip
->tai_event_work
);
316 mv88e6xxx_reg_unlock(chip
);
321 static int mv88e6352_ptp_enable(struct ptp_clock_info
*ptp
,
322 struct ptp_clock_request
*rq
, int on
)
324 struct mv88e6xxx_chip
*chip
= ptp_to_chip(ptp
);
327 case PTP_CLK_REQ_EXTTS
:
328 return mv88e6352_ptp_enable_extts(chip
, rq
, on
);
334 static int mv88e6352_ptp_verify(struct ptp_clock_info
*ptp
, unsigned int pin
,
335 enum ptp_pin_function func
, unsigned int chan
)
348 const struct mv88e6xxx_ptp_ops mv88e6165_ptp_ops
= {
349 .clock_read
= mv88e6165_ptp_clock_read
,
350 .global_enable
= mv88e6165_global_enable
,
351 .global_disable
= mv88e6165_global_disable
,
352 .arr0_sts_reg
= MV88E6165_PORT_PTP_ARR0_STS
,
353 .arr1_sts_reg
= MV88E6165_PORT_PTP_ARR1_STS
,
354 .dep_sts_reg
= MV88E6165_PORT_PTP_DEP_STS
,
355 .rx_filters
= (1 << HWTSTAMP_FILTER_NONE
) |
356 (1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT
) |
357 (1 << HWTSTAMP_FILTER_PTP_V2_L2_SYNC
) |
358 (1 << HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ
) |
359 (1 << HWTSTAMP_FILTER_PTP_V2_EVENT
) |
360 (1 << HWTSTAMP_FILTER_PTP_V2_SYNC
) |
361 (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ
),
362 .cc_shift
= MV88E6XXX_CC_SHIFT
,
363 .cc_mult
= MV88E6XXX_CC_MULT
,
364 .cc_mult_num
= MV88E6XXX_CC_MULT_NUM
,
365 .cc_mult_dem
= MV88E6XXX_CC_MULT_DEM
,
368 const struct mv88e6xxx_ptp_ops mv88e6250_ptp_ops
= {
369 .clock_read
= mv88e6352_ptp_clock_read
,
370 .ptp_enable
= mv88e6352_ptp_enable
,
371 .ptp_verify
= mv88e6352_ptp_verify
,
372 .event_work
= mv88e6352_tai_event_work
,
373 .port_enable
= mv88e6352_hwtstamp_port_enable
,
374 .port_disable
= mv88e6352_hwtstamp_port_disable
,
376 .arr0_sts_reg
= MV88E6XXX_PORT_PTP_ARR0_STS
,
377 .arr1_sts_reg
= MV88E6XXX_PORT_PTP_ARR1_STS
,
378 .dep_sts_reg
= MV88E6XXX_PORT_PTP_DEP_STS
,
379 .rx_filters
= (1 << HWTSTAMP_FILTER_NONE
) |
380 (1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT
) |
381 (1 << HWTSTAMP_FILTER_PTP_V2_L4_SYNC
) |
382 (1 << HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ
) |
383 (1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT
) |
384 (1 << HWTSTAMP_FILTER_PTP_V2_L2_SYNC
) |
385 (1 << HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ
) |
386 (1 << HWTSTAMP_FILTER_PTP_V2_EVENT
) |
387 (1 << HWTSTAMP_FILTER_PTP_V2_SYNC
) |
388 (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ
),
389 .cc_shift
= MV88E6250_CC_SHIFT
,
390 .cc_mult
= MV88E6250_CC_MULT
,
391 .cc_mult_num
= MV88E6250_CC_MULT_NUM
,
392 .cc_mult_dem
= MV88E6250_CC_MULT_DEM
,
395 const struct mv88e6xxx_ptp_ops mv88e6352_ptp_ops
= {
396 .clock_read
= mv88e6352_ptp_clock_read
,
397 .ptp_enable
= mv88e6352_ptp_enable
,
398 .ptp_verify
= mv88e6352_ptp_verify
,
399 .event_work
= mv88e6352_tai_event_work
,
400 .port_enable
= mv88e6352_hwtstamp_port_enable
,
401 .port_disable
= mv88e6352_hwtstamp_port_disable
,
403 .arr0_sts_reg
= MV88E6XXX_PORT_PTP_ARR0_STS
,
404 .arr1_sts_reg
= MV88E6XXX_PORT_PTP_ARR1_STS
,
405 .dep_sts_reg
= MV88E6XXX_PORT_PTP_DEP_STS
,
406 .rx_filters
= (1 << HWTSTAMP_FILTER_NONE
) |
407 (1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT
) |
408 (1 << HWTSTAMP_FILTER_PTP_V2_L4_SYNC
) |
409 (1 << HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ
) |
410 (1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT
) |
411 (1 << HWTSTAMP_FILTER_PTP_V2_L2_SYNC
) |
412 (1 << HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ
) |
413 (1 << HWTSTAMP_FILTER_PTP_V2_EVENT
) |
414 (1 << HWTSTAMP_FILTER_PTP_V2_SYNC
) |
415 (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ
),
416 .cc_shift
= MV88E6XXX_CC_SHIFT
,
417 .cc_mult
= MV88E6XXX_CC_MULT
,
418 .cc_mult_num
= MV88E6XXX_CC_MULT_NUM
,
419 .cc_mult_dem
= MV88E6XXX_CC_MULT_DEM
,
422 static u64
mv88e6xxx_ptp_clock_read(const struct cyclecounter
*cc
)
424 struct mv88e6xxx_chip
*chip
= cc_to_chip(cc
);
426 if (chip
->info
->ops
->ptp_ops
->clock_read
)
427 return chip
->info
->ops
->ptp_ops
->clock_read(cc
);
432 /* With a 125MHz input clock, the 32-bit timestamp counter overflows in ~34.3
433 * seconds; this task forces periodic reads so that we don't miss any.
435 #define MV88E6XXX_TAI_OVERFLOW_PERIOD (HZ * 16)
436 static void mv88e6xxx_ptp_overflow_check(struct work_struct
*work
)
438 struct delayed_work
*dw
= to_delayed_work(work
);
439 struct mv88e6xxx_chip
*chip
= dw_overflow_to_chip(dw
);
440 struct timespec64 ts
;
442 mv88e6xxx_ptp_gettime(&chip
->ptp_clock_info
, &ts
);
444 schedule_delayed_work(&chip
->overflow_work
,
445 MV88E6XXX_TAI_OVERFLOW_PERIOD
);
448 int mv88e6xxx_ptp_setup(struct mv88e6xxx_chip
*chip
)
450 const struct mv88e6xxx_ptp_ops
*ptp_ops
= chip
->info
->ops
->ptp_ops
;
453 /* Set up the cycle counter */
454 memset(&chip
->tstamp_cc
, 0, sizeof(chip
->tstamp_cc
));
455 chip
->tstamp_cc
.read
= mv88e6xxx_ptp_clock_read
;
456 chip
->tstamp_cc
.mask
= CYCLECOUNTER_MASK(32);
457 chip
->tstamp_cc
.mult
= ptp_ops
->cc_mult
;
458 chip
->tstamp_cc
.shift
= ptp_ops
->cc_shift
;
460 timecounter_init(&chip
->tstamp_tc
, &chip
->tstamp_cc
,
461 ktime_to_ns(ktime_get_real()));
463 INIT_DELAYED_WORK(&chip
->overflow_work
, mv88e6xxx_ptp_overflow_check
);
464 if (ptp_ops
->event_work
)
465 INIT_DELAYED_WORK(&chip
->tai_event_work
, ptp_ops
->event_work
);
467 chip
->ptp_clock_info
.owner
= THIS_MODULE
;
468 snprintf(chip
->ptp_clock_info
.name
, sizeof(chip
->ptp_clock_info
.name
),
469 "%s", dev_name(chip
->dev
));
471 chip
->ptp_clock_info
.n_ext_ts
= ptp_ops
->n_ext_ts
;
472 chip
->ptp_clock_info
.n_per_out
= 0;
473 chip
->ptp_clock_info
.n_pins
= mv88e6xxx_num_gpio(chip
);
474 chip
->ptp_clock_info
.pps
= 0;
476 for (i
= 0; i
< chip
->ptp_clock_info
.n_pins
; ++i
) {
477 struct ptp_pin_desc
*ppd
= &chip
->pin_config
[i
];
479 snprintf(ppd
->name
, sizeof(ppd
->name
), "mv88e6xxx_gpio%d", i
);
481 ppd
->func
= PTP_PF_NONE
;
483 chip
->ptp_clock_info
.pin_config
= chip
->pin_config
;
485 chip
->ptp_clock_info
.max_adj
= MV88E6XXX_MAX_ADJ_PPB
;
486 chip
->ptp_clock_info
.adjfine
= mv88e6xxx_ptp_adjfine
;
487 chip
->ptp_clock_info
.adjtime
= mv88e6xxx_ptp_adjtime
;
488 chip
->ptp_clock_info
.gettime64
= mv88e6xxx_ptp_gettime
;
489 chip
->ptp_clock_info
.settime64
= mv88e6xxx_ptp_settime
;
490 chip
->ptp_clock_info
.enable
= ptp_ops
->ptp_enable
;
491 chip
->ptp_clock_info
.verify
= ptp_ops
->ptp_verify
;
492 chip
->ptp_clock_info
.do_aux_work
= mv88e6xxx_hwtstamp_work
;
494 chip
->ptp_clock
= ptp_clock_register(&chip
->ptp_clock_info
, chip
->dev
);
495 if (IS_ERR(chip
->ptp_clock
))
496 return PTR_ERR(chip
->ptp_clock
);
498 schedule_delayed_work(&chip
->overflow_work
,
499 MV88E6XXX_TAI_OVERFLOW_PERIOD
);
504 void mv88e6xxx_ptp_free(struct mv88e6xxx_chip
*chip
)
506 if (chip
->ptp_clock
) {
507 cancel_delayed_work_sync(&chip
->overflow_work
);
508 if (chip
->info
->ops
->ptp_ops
->event_work
)
509 cancel_delayed_work_sync(&chip
->tai_event_work
);
511 ptp_clock_unregister(chip
->ptp_clock
);
512 chip
->ptp_clock
= NULL
;