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 --- |