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 "global1.h" 15 #include "global2.h" 16 #include "hwtstamp.h" 17 #include "ptp.h" 18 19 #define MV88E6XXX_MAX_ADJ_PPB 1000000 20 21 struct mv88e6xxx_cc_coeffs { 22 u32 cc_shift; 23 u32 cc_mult; 24 u32 cc_mult_num; 25 u32 cc_mult_dem; 26 }; 27 28 /* Family MV88E6250: 29 * Raw timestamps are in units of 10-ns clock periods. 30 * 31 * clkadj = scaled_ppm * 10*2^28 / (10^6 * 2^16) 32 * simplifies to 33 * clkadj = scaled_ppm * 2^7 / 5^5 34 */ 35 #define MV88E6XXX_CC_10NS_SHIFT 28 36 static const struct mv88e6xxx_cc_coeffs mv88e6xxx_cc_10ns_coeffs = { 37 .cc_shift = MV88E6XXX_CC_10NS_SHIFT, 38 .cc_mult = 10 << MV88E6XXX_CC_10NS_SHIFT, 39 .cc_mult_num = 1 << 7, 40 .cc_mult_dem = 3125ULL, 41 }; 42 43 /* Other families except MV88E6393X in internal clock mode: 44 * Raw timestamps are in units of 8-ns clock periods. 45 * 46 * clkadj = scaled_ppm * 8*2^28 / (10^6 * 2^16) 47 * simplifies to 48 * clkadj = scaled_ppm * 2^9 / 5^6 49 */ 50 #define MV88E6XXX_CC_8NS_SHIFT 28 51 static const struct mv88e6xxx_cc_coeffs mv88e6xxx_cc_8ns_coeffs = { 52 .cc_shift = MV88E6XXX_CC_8NS_SHIFT, 53 .cc_mult = 8 << MV88E6XXX_CC_8NS_SHIFT, 54 .cc_mult_num = 1 << 9, 55 .cc_mult_dem = 15625ULL 56 }; 57 58 /* Family MV88E6393X using internal clock: 59 * Raw timestamps are in units of 4-ns clock periods. 60 * 61 * clkadj = scaled_ppm * 4*2^28 / (10^6 * 2^16) 62 * simplifies to 63 * clkadj = scaled_ppm * 2^8 / 5^6 64 */ 65 #define MV88E6XXX_CC_4NS_SHIFT 28 66 static const struct mv88e6xxx_cc_coeffs mv88e6xxx_cc_4ns_coeffs = { 67 .cc_shift = MV88E6XXX_CC_4NS_SHIFT, 68 .cc_mult = 4 << MV88E6XXX_CC_4NS_SHIFT, 69 .cc_mult_num = 1 << 8, 70 .cc_mult_dem = 15625ULL 71 }; 72 73 #define TAI_EVENT_WORK_INTERVAL msecs_to_jiffies(100) 74 75 #define cc_to_chip(cc) container_of(cc, struct mv88e6xxx_chip, tstamp_cc) 76 #define dw_overflow_to_chip(dw) container_of(dw, struct mv88e6xxx_chip, \ 77 overflow_work) 78 #define dw_tai_event_to_chip(dw) container_of(dw, struct mv88e6xxx_chip, \ 79 tai_event_work) 80 81 static int mv88e6xxx_tai_read(struct mv88e6xxx_chip *chip, int addr, 82 u16 *data, int len) 83 { 84 if (!chip->info->ops->avb_ops->tai_read) 85 return -EOPNOTSUPP; 86 87 return chip->info->ops->avb_ops->tai_read(chip, addr, data, len); 88 } 89 90 static int mv88e6xxx_tai_write(struct mv88e6xxx_chip *chip, int addr, u16 data) 91 { 92 if (!chip->info->ops->avb_ops->tai_write) 93 return -EOPNOTSUPP; 94 95 return chip->info->ops->avb_ops->tai_write(chip, addr, data); 96 } 97 98 /* TODO: places where this are called should be using pinctrl */ 99 static int mv88e6352_set_gpio_func(struct mv88e6xxx_chip *chip, int pin, 100 int func, int input) 101 { 102 int err; 103 104 if (!chip->info->ops->gpio_ops) 105 return -EOPNOTSUPP; 106 107 err = chip->info->ops->gpio_ops->set_dir(chip, pin, input); 108 if (err) 109 return err; 110 111 return chip->info->ops->gpio_ops->set_pctl(chip, pin, func); 112 } 113 114 static const struct mv88e6xxx_cc_coeffs * 115 mv88e6xxx_cc_coeff_get(struct mv88e6xxx_chip *chip) 116 { 117 u16 period_ps; 118 int err; 119 120 err = mv88e6xxx_tai_read(chip, MV88E6XXX_TAI_CLOCK_PERIOD, &period_ps, 1); 121 if (err) { 122 dev_err(chip->dev, "failed to read cycle counter period: %d\n", 123 err); 124 return ERR_PTR(err); 125 } 126 127 switch (period_ps) { 128 case 4000: 129 return &mv88e6xxx_cc_4ns_coeffs; 130 case 8000: 131 return &mv88e6xxx_cc_8ns_coeffs; 132 case 10000: 133 return &mv88e6xxx_cc_10ns_coeffs; 134 default: 135 dev_err(chip->dev, "unexpected cycle counter period of %u ps\n", 136 period_ps); 137 return ERR_PTR(-ENODEV); 138 } 139 } 140 141 static u64 mv88e6352_ptp_clock_read(const struct cyclecounter *cc) 142 { 143 struct mv88e6xxx_chip *chip = cc_to_chip(cc); 144 u16 phc_time[2]; 145 int err; 146 147 err = mv88e6xxx_tai_read(chip, MV88E6XXX_TAI_TIME_LO, phc_time, 148 ARRAY_SIZE(phc_time)); 149 if (err) 150 return 0; 151 else 152 return ((u32)phc_time[1] << 16) | phc_time[0]; 153 } 154 155 static u64 mv88e6165_ptp_clock_read(const struct cyclecounter *cc) 156 { 157 struct mv88e6xxx_chip *chip = cc_to_chip(cc); 158 u16 phc_time[2]; 159 int err; 160 161 err = mv88e6xxx_tai_read(chip, MV88E6XXX_PTP_GC_TIME_LO, phc_time, 162 ARRAY_SIZE(phc_time)); 163 if (err) 164 return 0; 165 else 166 return ((u32)phc_time[1] << 16) | phc_time[0]; 167 } 168 169 /* mv88e6352_config_eventcap - configure TAI event capture 170 * @event: PTP_CLOCK_PPS (internal) or PTP_CLOCK_EXTTS (external) 171 * @rising: zero for falling-edge trigger, else rising-edge trigger 172 * 173 * This will also reset the capture sequence counter. 174 */ 175 static int mv88e6352_config_eventcap(struct mv88e6xxx_chip *chip, int event, 176 int rising) 177 { 178 u16 global_config; 179 u16 cap_config; 180 int err; 181 182 chip->evcap_config = MV88E6XXX_TAI_CFG_CAP_OVERWRITE | 183 MV88E6XXX_TAI_CFG_CAP_CTR_START; 184 if (!rising) 185 chip->evcap_config |= MV88E6XXX_TAI_CFG_EVREQ_FALLING; 186 187 global_config = (chip->evcap_config | chip->trig_config); 188 err = mv88e6xxx_tai_write(chip, MV88E6XXX_TAI_CFG, global_config); 189 if (err) 190 return err; 191 192 if (event == PTP_CLOCK_PPS) { 193 cap_config = MV88E6XXX_TAI_EVENT_STATUS_CAP_TRIG; 194 } else if (event == PTP_CLOCK_EXTTS) { 195 /* if STATUS_CAP_TRIG is unset we capture PTP_EVREQ events */ 196 cap_config = 0; 197 } else { 198 return -EINVAL; 199 } 200 201 /* Write the capture config; this also clears the capture counter */ 202 err = mv88e6xxx_tai_write(chip, MV88E6XXX_TAI_EVENT_STATUS, 203 cap_config); 204 205 return err; 206 } 207 208 static void mv88e6352_tai_event_work(struct work_struct *ugly) 209 { 210 struct delayed_work *dw = to_delayed_work(ugly); 211 struct mv88e6xxx_chip *chip = dw_tai_event_to_chip(dw); 212 struct ptp_clock_event ev; 213 u16 status[4]; 214 u32 raw_ts; 215 int err; 216 217 mv88e6xxx_reg_lock(chip); 218 err = mv88e6xxx_tai_read(chip, MV88E6XXX_TAI_EVENT_STATUS, 219 status, ARRAY_SIZE(status)); 220 mv88e6xxx_reg_unlock(chip); 221 222 if (err) { 223 dev_err(chip->dev, "failed to read TAI status register\n"); 224 return; 225 } 226 if (status[0] & MV88E6XXX_TAI_EVENT_STATUS_ERROR) { 227 dev_warn(chip->dev, "missed event capture\n"); 228 return; 229 } 230 if (!(status[0] & MV88E6XXX_TAI_EVENT_STATUS_VALID)) 231 goto out; 232 233 raw_ts = ((u32)status[2] << 16) | status[1]; 234 235 /* Clear the valid bit so the next timestamp can come in */ 236 status[0] &= ~MV88E6XXX_TAI_EVENT_STATUS_VALID; 237 mv88e6xxx_reg_lock(chip); 238 err = mv88e6xxx_tai_write(chip, MV88E6XXX_TAI_EVENT_STATUS, status[0]); 239 mv88e6xxx_reg_unlock(chip); 240 if (err) { 241 dev_err(chip->dev, "failed to write TAI status register\n"); 242 return; 243 } 244 245 /* This is an external timestamp */ 246 ev.type = PTP_CLOCK_EXTTS; 247 248 /* We only have one timestamping channel. */ 249 ev.index = 0; 250 mv88e6xxx_reg_lock(chip); 251 ev.timestamp = timecounter_cyc2time(&chip->tstamp_tc, raw_ts); 252 mv88e6xxx_reg_unlock(chip); 253 254 ptp_clock_event(chip->ptp_clock, &ev); 255 out: 256 schedule_delayed_work(&chip->tai_event_work, TAI_EVENT_WORK_INTERVAL); 257 } 258 259 static int mv88e6xxx_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm) 260 { 261 struct mv88e6xxx_chip *chip = ptp_to_chip(ptp); 262 int neg_adj = 0; 263 u32 diff, mult; 264 u64 adj; 265 266 if (scaled_ppm < 0) { 267 neg_adj = 1; 268 scaled_ppm = -scaled_ppm; 269 } 270 271 mult = chip->cc_coeffs->cc_mult; 272 adj = chip->cc_coeffs->cc_mult_num; 273 adj *= scaled_ppm; 274 diff = div_u64(adj, chip->cc_coeffs->cc_mult_dem); 275 276 mv88e6xxx_reg_lock(chip); 277 278 timecounter_read(&chip->tstamp_tc); 279 chip->tstamp_cc.mult = neg_adj ? mult - diff : mult + diff; 280 281 mv88e6xxx_reg_unlock(chip); 282 283 return 0; 284 } 285 286 static int mv88e6xxx_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta) 287 { 288 struct mv88e6xxx_chip *chip = ptp_to_chip(ptp); 289 290 mv88e6xxx_reg_lock(chip); 291 timecounter_adjtime(&chip->tstamp_tc, delta); 292 mv88e6xxx_reg_unlock(chip); 293 294 return 0; 295 } 296 297 static int mv88e6xxx_ptp_gettime(struct ptp_clock_info *ptp, 298 struct timespec64 *ts) 299 { 300 struct mv88e6xxx_chip *chip = ptp_to_chip(ptp); 301 u64 ns; 302 303 mv88e6xxx_reg_lock(chip); 304 ns = timecounter_read(&chip->tstamp_tc); 305 mv88e6xxx_reg_unlock(chip); 306 307 *ts = ns_to_timespec64(ns); 308 309 return 0; 310 } 311 312 static int mv88e6xxx_ptp_settime(struct ptp_clock_info *ptp, 313 const struct timespec64 *ts) 314 { 315 struct mv88e6xxx_chip *chip = ptp_to_chip(ptp); 316 u64 ns; 317 318 ns = timespec64_to_ns(ts); 319 320 mv88e6xxx_reg_lock(chip); 321 timecounter_init(&chip->tstamp_tc, &chip->tstamp_cc, ns); 322 mv88e6xxx_reg_unlock(chip); 323 324 return 0; 325 } 326 327 static int mv88e6352_ptp_enable_extts(struct mv88e6xxx_chip *chip, 328 struct ptp_clock_request *rq, int on) 329 { 330 int rising = (rq->extts.flags & PTP_RISING_EDGE); 331 int func; 332 int pin; 333 int err; 334 335 /* Reject requests with unsupported flags */ 336 if (rq->extts.flags & ~(PTP_ENABLE_FEATURE | 337 PTP_RISING_EDGE | 338 PTP_FALLING_EDGE | 339 PTP_STRICT_FLAGS)) 340 return -EOPNOTSUPP; 341 342 /* Reject requests to enable time stamping on both edges. */ 343 if ((rq->extts.flags & PTP_STRICT_FLAGS) && 344 (rq->extts.flags & PTP_ENABLE_FEATURE) && 345 (rq->extts.flags & PTP_EXTTS_EDGES) == PTP_EXTTS_EDGES) 346 return -EOPNOTSUPP; 347 348 pin = ptp_find_pin(chip->ptp_clock, PTP_PF_EXTTS, rq->extts.index); 349 350 if (pin < 0) 351 return -EBUSY; 352 353 mv88e6xxx_reg_lock(chip); 354 355 if (on) { 356 func = MV88E6352_G2_SCRATCH_GPIO_PCTL_EVREQ; 357 358 err = mv88e6352_set_gpio_func(chip, pin, func, true); 359 if (err) 360 goto out; 361 362 schedule_delayed_work(&chip->tai_event_work, 363 TAI_EVENT_WORK_INTERVAL); 364 365 err = mv88e6352_config_eventcap(chip, PTP_CLOCK_EXTTS, rising); 366 } else { 367 func = MV88E6352_G2_SCRATCH_GPIO_PCTL_GPIO; 368 369 err = mv88e6352_set_gpio_func(chip, pin, func, true); 370 371 cancel_delayed_work_sync(&chip->tai_event_work); 372 } 373 374 out: 375 mv88e6xxx_reg_unlock(chip); 376 377 return err; 378 } 379 380 static int mv88e6352_ptp_enable(struct ptp_clock_info *ptp, 381 struct ptp_clock_request *rq, int on) 382 { 383 struct mv88e6xxx_chip *chip = ptp_to_chip(ptp); 384 385 switch (rq->type) { 386 case PTP_CLK_REQ_EXTTS: 387 return mv88e6352_ptp_enable_extts(chip, rq, on); 388 default: 389 return -EOPNOTSUPP; 390 } 391 } 392 393 static int mv88e6352_ptp_verify(struct ptp_clock_info *ptp, unsigned int pin, 394 enum ptp_pin_function func, unsigned int chan) 395 { 396 switch (func) { 397 case PTP_PF_NONE: 398 case PTP_PF_EXTTS: 399 break; 400 case PTP_PF_PEROUT: 401 case PTP_PF_PHYSYNC: 402 return -EOPNOTSUPP; 403 } 404 return 0; 405 } 406 407 const struct mv88e6xxx_ptp_ops mv88e6165_ptp_ops = { 408 .clock_read = mv88e6165_ptp_clock_read, 409 .global_enable = mv88e6165_global_enable, 410 .global_disable = mv88e6165_global_disable, 411 .arr0_sts_reg = MV88E6165_PORT_PTP_ARR0_STS, 412 .arr1_sts_reg = MV88E6165_PORT_PTP_ARR1_STS, 413 .dep_sts_reg = MV88E6165_PORT_PTP_DEP_STS, 414 .rx_filters = (1 << HWTSTAMP_FILTER_NONE) | 415 (1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) | 416 (1 << HWTSTAMP_FILTER_PTP_V2_L2_SYNC) | 417 (1 << HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ) | 418 (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) | 419 (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) | 420 (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ), 421 }; 422 423 const struct mv88e6xxx_ptp_ops mv88e6250_ptp_ops = { 424 .clock_read = mv88e6352_ptp_clock_read, 425 .ptp_enable = mv88e6352_ptp_enable, 426 .ptp_verify = mv88e6352_ptp_verify, 427 .event_work = mv88e6352_tai_event_work, 428 .port_enable = mv88e6352_hwtstamp_port_enable, 429 .port_disable = mv88e6352_hwtstamp_port_disable, 430 .n_ext_ts = 1, 431 .arr0_sts_reg = MV88E6XXX_PORT_PTP_ARR0_STS, 432 .arr1_sts_reg = MV88E6XXX_PORT_PTP_ARR1_STS, 433 .dep_sts_reg = MV88E6XXX_PORT_PTP_DEP_STS, 434 .rx_filters = (1 << HWTSTAMP_FILTER_NONE) | 435 (1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT) | 436 (1 << HWTSTAMP_FILTER_PTP_V2_L4_SYNC) | 437 (1 << HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ) | 438 (1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) | 439 (1 << HWTSTAMP_FILTER_PTP_V2_L2_SYNC) | 440 (1 << HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ) | 441 (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) | 442 (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) | 443 (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ), 444 }; 445 446 const struct mv88e6xxx_ptp_ops mv88e6352_ptp_ops = { 447 .clock_read = mv88e6352_ptp_clock_read, 448 .ptp_enable = mv88e6352_ptp_enable, 449 .ptp_verify = mv88e6352_ptp_verify, 450 .event_work = mv88e6352_tai_event_work, 451 .port_enable = mv88e6352_hwtstamp_port_enable, 452 .port_disable = mv88e6352_hwtstamp_port_disable, 453 .n_ext_ts = 1, 454 .arr0_sts_reg = MV88E6XXX_PORT_PTP_ARR0_STS, 455 .arr1_sts_reg = MV88E6XXX_PORT_PTP_ARR1_STS, 456 .dep_sts_reg = MV88E6XXX_PORT_PTP_DEP_STS, 457 .rx_filters = (1 << HWTSTAMP_FILTER_NONE) | 458 (1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT) | 459 (1 << HWTSTAMP_FILTER_PTP_V2_L4_SYNC) | 460 (1 << HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ) | 461 (1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) | 462 (1 << HWTSTAMP_FILTER_PTP_V2_L2_SYNC) | 463 (1 << HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ) | 464 (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) | 465 (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) | 466 (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ), 467 }; 468 469 const struct mv88e6xxx_ptp_ops mv88e6390_ptp_ops = { 470 .clock_read = mv88e6352_ptp_clock_read, 471 .ptp_enable = mv88e6352_ptp_enable, 472 .ptp_verify = mv88e6352_ptp_verify, 473 .event_work = mv88e6352_tai_event_work, 474 .port_enable = mv88e6352_hwtstamp_port_enable, 475 .port_disable = mv88e6352_hwtstamp_port_disable, 476 .set_ptp_cpu_port = mv88e6390_g1_set_ptp_cpu_port, 477 .n_ext_ts = 1, 478 .arr0_sts_reg = MV88E6XXX_PORT_PTP_ARR0_STS, 479 .arr1_sts_reg = MV88E6XXX_PORT_PTP_ARR1_STS, 480 .dep_sts_reg = MV88E6XXX_PORT_PTP_DEP_STS, 481 .rx_filters = (1 << HWTSTAMP_FILTER_NONE) | 482 (1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT) | 483 (1 << HWTSTAMP_FILTER_PTP_V2_L4_SYNC) | 484 (1 << HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ) | 485 (1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) | 486 (1 << HWTSTAMP_FILTER_PTP_V2_L2_SYNC) | 487 (1 << HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ) | 488 (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) | 489 (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) | 490 (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ), 491 }; 492 493 static u64 mv88e6xxx_ptp_clock_read(const struct cyclecounter *cc) 494 { 495 struct mv88e6xxx_chip *chip = cc_to_chip(cc); 496 497 if (chip->info->ops->ptp_ops->clock_read) 498 return chip->info->ops->ptp_ops->clock_read(cc); 499 500 return 0; 501 } 502 503 /* With a 250MHz input clock, the 32-bit timestamp counter overflows in ~17.2 504 * seconds; this task forces periodic reads so that we don't miss any. 505 */ 506 #define MV88E6XXX_TAI_OVERFLOW_PERIOD (HZ * 8) 507 static void mv88e6xxx_ptp_overflow_check(struct work_struct *work) 508 { 509 struct delayed_work *dw = to_delayed_work(work); 510 struct mv88e6xxx_chip *chip = dw_overflow_to_chip(dw); 511 struct timespec64 ts; 512 513 mv88e6xxx_ptp_gettime(&chip->ptp_clock_info, &ts); 514 515 schedule_delayed_work(&chip->overflow_work, 516 MV88E6XXX_TAI_OVERFLOW_PERIOD); 517 } 518 519 int mv88e6xxx_ptp_setup(struct mv88e6xxx_chip *chip) 520 { 521 const struct mv88e6xxx_ptp_ops *ptp_ops = chip->info->ops->ptp_ops; 522 int i; 523 524 /* Set up the cycle counter */ 525 chip->cc_coeffs = mv88e6xxx_cc_coeff_get(chip); 526 if (IS_ERR(chip->cc_coeffs)) 527 return PTR_ERR(chip->cc_coeffs); 528 529 memset(&chip->tstamp_cc, 0, sizeof(chip->tstamp_cc)); 530 chip->tstamp_cc.read = mv88e6xxx_ptp_clock_read; 531 chip->tstamp_cc.mask = CYCLECOUNTER_MASK(32); 532 chip->tstamp_cc.mult = chip->cc_coeffs->cc_mult; 533 chip->tstamp_cc.shift = chip->cc_coeffs->cc_shift; 534 535 timecounter_init(&chip->tstamp_tc, &chip->tstamp_cc, 536 ktime_to_ns(ktime_get_real())); 537 538 INIT_DELAYED_WORK(&chip->overflow_work, mv88e6xxx_ptp_overflow_check); 539 if (ptp_ops->event_work) 540 INIT_DELAYED_WORK(&chip->tai_event_work, ptp_ops->event_work); 541 542 chip->ptp_clock_info.owner = THIS_MODULE; 543 snprintf(chip->ptp_clock_info.name, sizeof(chip->ptp_clock_info.name), 544 "%s", dev_name(chip->dev)); 545 546 chip->ptp_clock_info.n_ext_ts = ptp_ops->n_ext_ts; 547 chip->ptp_clock_info.n_per_out = 0; 548 chip->ptp_clock_info.n_pins = mv88e6xxx_num_gpio(chip); 549 chip->ptp_clock_info.pps = 0; 550 551 for (i = 0; i < chip->ptp_clock_info.n_pins; ++i) { 552 struct ptp_pin_desc *ppd = &chip->pin_config[i]; 553 554 snprintf(ppd->name, sizeof(ppd->name), "mv88e6xxx_gpio%d", i); 555 ppd->index = i; 556 ppd->func = PTP_PF_NONE; 557 } 558 chip->ptp_clock_info.pin_config = chip->pin_config; 559 560 chip->ptp_clock_info.max_adj = MV88E6XXX_MAX_ADJ_PPB; 561 chip->ptp_clock_info.adjfine = mv88e6xxx_ptp_adjfine; 562 chip->ptp_clock_info.adjtime = mv88e6xxx_ptp_adjtime; 563 chip->ptp_clock_info.gettime64 = mv88e6xxx_ptp_gettime; 564 chip->ptp_clock_info.settime64 = mv88e6xxx_ptp_settime; 565 chip->ptp_clock_info.enable = ptp_ops->ptp_enable; 566 chip->ptp_clock_info.verify = ptp_ops->ptp_verify; 567 chip->ptp_clock_info.do_aux_work = mv88e6xxx_hwtstamp_work; 568 569 if (ptp_ops->set_ptp_cpu_port) { 570 struct dsa_port *dp; 571 int upstream = 0; 572 int err; 573 574 dsa_switch_for_each_user_port(dp, chip->ds) { 575 upstream = dsa_upstream_port(chip->ds, dp->index); 576 break; 577 } 578 579 err = ptp_ops->set_ptp_cpu_port(chip, upstream); 580 if (err) { 581 dev_err(chip->dev, "Failed to set PTP CPU destination port!\n"); 582 return err; 583 } 584 } 585 586 chip->ptp_clock = ptp_clock_register(&chip->ptp_clock_info, chip->dev); 587 if (IS_ERR(chip->ptp_clock)) 588 return PTR_ERR(chip->ptp_clock); 589 590 schedule_delayed_work(&chip->overflow_work, 591 MV88E6XXX_TAI_OVERFLOW_PERIOD); 592 593 return 0; 594 } 595 596 void mv88e6xxx_ptp_free(struct mv88e6xxx_chip *chip) 597 { 598 if (chip->ptp_clock) { 599 cancel_delayed_work_sync(&chip->overflow_work); 600 if (chip->info->ops->ptp_ops->event_work) 601 cancel_delayed_work_sync(&chip->tai_event_work); 602 603 ptp_clock_unregister(chip->ptp_clock); 604 chip->ptp_clock = NULL; 605 } 606 } 607