1 // SPDX-License-Identifier: GPL-2.0 2 /* Marvell RVU Ethernet driver 3 * 4 * Copyright (C) 2020 Marvell. 5 * 6 */ 7 8 #include <linux/module.h> 9 10 #include "otx2_common.h" 11 #include "otx2_ptp.h" 12 13 static u64 otx2_ptp_get_clock(struct otx2_ptp *ptp) 14 { 15 struct ptp_req *req; 16 struct ptp_rsp *rsp; 17 int err; 18 19 if (!ptp->nic) 20 return 0; 21 22 req = otx2_mbox_alloc_msg_ptp_op(&ptp->nic->mbox); 23 if (!req) 24 return 0; 25 26 req->op = PTP_OP_GET_CLOCK; 27 28 err = otx2_sync_mbox_msg(&ptp->nic->mbox); 29 if (err) 30 return 0; 31 32 rsp = (struct ptp_rsp *)otx2_mbox_get_rsp(&ptp->nic->mbox.mbox, 0, 33 &req->hdr); 34 if (IS_ERR(rsp)) 35 return 0; 36 37 return rsp->clk; 38 } 39 40 static int otx2_ptp_adjfine(struct ptp_clock_info *ptp_info, long scaled_ppm) 41 { 42 struct otx2_ptp *ptp = container_of(ptp_info, struct otx2_ptp, 43 ptp_info); 44 struct ptp_req *req; 45 46 if (!ptp->nic) 47 return -ENODEV; 48 49 req = otx2_mbox_alloc_msg_ptp_op(&ptp->nic->mbox); 50 if (!req) 51 return -ENOMEM; 52 53 req->op = PTP_OP_ADJFINE; 54 req->scaled_ppm = scaled_ppm; 55 56 return otx2_sync_mbox_msg(&ptp->nic->mbox); 57 } 58 59 static int ptp_set_thresh(struct otx2_ptp *ptp, u64 thresh) 60 { 61 struct ptp_req *req; 62 63 if (!ptp->nic) 64 return -ENODEV; 65 66 req = otx2_mbox_alloc_msg_ptp_op(&ptp->nic->mbox); 67 if (!req) 68 return -ENOMEM; 69 70 req->op = PTP_OP_SET_THRESH; 71 req->thresh = thresh; 72 73 return otx2_sync_mbox_msg(&ptp->nic->mbox); 74 } 75 76 static int ptp_extts_on(struct otx2_ptp *ptp, int on) 77 { 78 struct ptp_req *req; 79 80 if (!ptp->nic) 81 return -ENODEV; 82 83 req = otx2_mbox_alloc_msg_ptp_op(&ptp->nic->mbox); 84 if (!req) 85 return -ENOMEM; 86 87 req->op = PTP_OP_EXTTS_ON; 88 req->extts_on = on; 89 90 return otx2_sync_mbox_msg(&ptp->nic->mbox); 91 } 92 93 static u64 ptp_cc_read(const struct cyclecounter *cc) 94 { 95 struct otx2_ptp *ptp = container_of(cc, struct otx2_ptp, cycle_counter); 96 97 return otx2_ptp_get_clock(ptp); 98 } 99 100 static u64 ptp_tstmp_read(struct otx2_ptp *ptp) 101 { 102 struct ptp_req *req; 103 struct ptp_rsp *rsp; 104 int err; 105 106 if (!ptp->nic) 107 return 0; 108 109 req = otx2_mbox_alloc_msg_ptp_op(&ptp->nic->mbox); 110 if (!req) 111 return 0; 112 113 req->op = PTP_OP_GET_TSTMP; 114 115 err = otx2_sync_mbox_msg(&ptp->nic->mbox); 116 if (err) 117 return 0; 118 119 rsp = (struct ptp_rsp *)otx2_mbox_get_rsp(&ptp->nic->mbox.mbox, 0, 120 &req->hdr); 121 if (IS_ERR(rsp)) 122 return 0; 123 124 return rsp->clk; 125 } 126 127 static void otx2_get_ptpclock(struct otx2_ptp *ptp, u64 *tstamp) 128 { 129 struct otx2_nic *pfvf = ptp->nic; 130 131 mutex_lock(&pfvf->mbox.lock); 132 *tstamp = timecounter_read(&ptp->time_counter); 133 mutex_unlock(&pfvf->mbox.lock); 134 } 135 136 static int otx2_ptp_adjtime(struct ptp_clock_info *ptp_info, s64 delta) 137 { 138 struct otx2_ptp *ptp = container_of(ptp_info, struct otx2_ptp, 139 ptp_info); 140 struct otx2_nic *pfvf = ptp->nic; 141 142 mutex_lock(&pfvf->mbox.lock); 143 timecounter_adjtime(&ptp->time_counter, delta); 144 mutex_unlock(&pfvf->mbox.lock); 145 146 return 0; 147 } 148 149 static int otx2_ptp_gettime(struct ptp_clock_info *ptp_info, 150 struct timespec64 *ts) 151 { 152 struct otx2_ptp *ptp = container_of(ptp_info, struct otx2_ptp, 153 ptp_info); 154 u64 tstamp; 155 156 otx2_get_ptpclock(ptp, &tstamp); 157 *ts = ns_to_timespec64(tstamp); 158 159 return 0; 160 } 161 162 static int otx2_ptp_settime(struct ptp_clock_info *ptp_info, 163 const struct timespec64 *ts) 164 { 165 struct otx2_ptp *ptp = container_of(ptp_info, struct otx2_ptp, 166 ptp_info); 167 struct otx2_nic *pfvf = ptp->nic; 168 u64 nsec; 169 170 nsec = timespec64_to_ns(ts); 171 172 mutex_lock(&pfvf->mbox.lock); 173 timecounter_init(&ptp->time_counter, &ptp->cycle_counter, nsec); 174 mutex_unlock(&pfvf->mbox.lock); 175 176 return 0; 177 } 178 179 static int otx2_ptp_verify_pin(struct ptp_clock_info *ptp, unsigned int pin, 180 enum ptp_pin_function func, unsigned int chan) 181 { 182 switch (func) { 183 case PTP_PF_NONE: 184 case PTP_PF_EXTTS: 185 break; 186 case PTP_PF_PEROUT: 187 case PTP_PF_PHYSYNC: 188 return -1; 189 } 190 return 0; 191 } 192 193 static void otx2_ptp_extts_check(struct work_struct *work) 194 { 195 struct otx2_ptp *ptp = container_of(work, struct otx2_ptp, 196 extts_work.work); 197 struct ptp_clock_event event; 198 u64 tstmp, new_thresh; 199 200 mutex_lock(&ptp->nic->mbox.lock); 201 tstmp = ptp_tstmp_read(ptp); 202 mutex_unlock(&ptp->nic->mbox.lock); 203 204 if (tstmp != ptp->last_extts) { 205 event.type = PTP_CLOCK_EXTTS; 206 event.index = 0; 207 event.timestamp = timecounter_cyc2time(&ptp->time_counter, tstmp); 208 ptp_clock_event(ptp->ptp_clock, &event); 209 new_thresh = tstmp % 500000000; 210 if (ptp->thresh != new_thresh) { 211 mutex_lock(&ptp->nic->mbox.lock); 212 ptp_set_thresh(ptp, new_thresh); 213 mutex_unlock(&ptp->nic->mbox.lock); 214 ptp->thresh = new_thresh; 215 } 216 ptp->last_extts = tstmp; 217 } 218 schedule_delayed_work(&ptp->extts_work, msecs_to_jiffies(200)); 219 } 220 221 static void otx2_sync_tstamp(struct work_struct *work) 222 { 223 struct otx2_ptp *ptp = container_of(work, struct otx2_ptp, 224 synctstamp_work.work); 225 struct otx2_nic *pfvf = ptp->nic; 226 u64 tstamp; 227 228 mutex_lock(&pfvf->mbox.lock); 229 tstamp = otx2_ptp_get_clock(ptp); 230 mutex_unlock(&pfvf->mbox.lock); 231 232 ptp->tstamp = timecounter_cyc2time(&pfvf->ptp->time_counter, tstamp); 233 ptp->base_ns = tstamp % NSEC_PER_SEC; 234 235 schedule_delayed_work(&ptp->synctstamp_work, msecs_to_jiffies(250)); 236 } 237 238 static int otx2_ptp_enable(struct ptp_clock_info *ptp_info, 239 struct ptp_clock_request *rq, int on) 240 { 241 struct otx2_ptp *ptp = container_of(ptp_info, struct otx2_ptp, 242 ptp_info); 243 int pin; 244 245 if (!ptp->nic) 246 return -ENODEV; 247 248 switch (rq->type) { 249 case PTP_CLK_REQ_EXTTS: 250 pin = ptp_find_pin(ptp->ptp_clock, PTP_PF_EXTTS, 251 rq->extts.index); 252 if (pin < 0) 253 return -EBUSY; 254 if (on) { 255 ptp_extts_on(ptp, on); 256 schedule_delayed_work(&ptp->extts_work, msecs_to_jiffies(200)); 257 } else { 258 ptp_extts_on(ptp, on); 259 cancel_delayed_work_sync(&ptp->extts_work); 260 } 261 return 0; 262 default: 263 break; 264 } 265 return -EOPNOTSUPP; 266 } 267 268 int otx2_ptp_init(struct otx2_nic *pfvf) 269 { 270 struct otx2_ptp *ptp_ptr; 271 struct cyclecounter *cc; 272 struct ptp_req *req; 273 int err; 274 275 if (is_otx2_lbkvf(pfvf->pdev)) { 276 pfvf->ptp = NULL; 277 return 0; 278 } 279 280 mutex_lock(&pfvf->mbox.lock); 281 /* check if PTP block is available */ 282 req = otx2_mbox_alloc_msg_ptp_op(&pfvf->mbox); 283 if (!req) { 284 mutex_unlock(&pfvf->mbox.lock); 285 return -ENOMEM; 286 } 287 288 req->op = PTP_OP_GET_CLOCK; 289 290 err = otx2_sync_mbox_msg(&pfvf->mbox); 291 if (err) { 292 mutex_unlock(&pfvf->mbox.lock); 293 return err; 294 } 295 mutex_unlock(&pfvf->mbox.lock); 296 297 ptp_ptr = kzalloc(sizeof(*ptp_ptr), GFP_KERNEL); 298 if (!ptp_ptr) { 299 err = -ENOMEM; 300 goto error; 301 } 302 303 ptp_ptr->nic = pfvf; 304 305 cc = &ptp_ptr->cycle_counter; 306 cc->read = ptp_cc_read; 307 cc->mask = CYCLECOUNTER_MASK(64); 308 cc->mult = 1; 309 cc->shift = 0; 310 311 timecounter_init(&ptp_ptr->time_counter, &ptp_ptr->cycle_counter, 312 ktime_to_ns(ktime_get_real())); 313 314 snprintf(ptp_ptr->extts_config.name, sizeof(ptp_ptr->extts_config.name), "TSTAMP"); 315 ptp_ptr->extts_config.index = 0; 316 ptp_ptr->extts_config.func = PTP_PF_NONE; 317 318 ptp_ptr->ptp_info = (struct ptp_clock_info) { 319 .owner = THIS_MODULE, 320 .name = "OcteonTX2 PTP", 321 .max_adj = 1000000000ull, 322 .n_ext_ts = 1, 323 .n_pins = 1, 324 .pps = 0, 325 .pin_config = &ptp_ptr->extts_config, 326 .adjfine = otx2_ptp_adjfine, 327 .adjtime = otx2_ptp_adjtime, 328 .gettime64 = otx2_ptp_gettime, 329 .settime64 = otx2_ptp_settime, 330 .enable = otx2_ptp_enable, 331 .verify = otx2_ptp_verify_pin, 332 }; 333 334 INIT_DELAYED_WORK(&ptp_ptr->extts_work, otx2_ptp_extts_check); 335 336 ptp_ptr->ptp_clock = ptp_clock_register(&ptp_ptr->ptp_info, pfvf->dev); 337 if (IS_ERR_OR_NULL(ptp_ptr->ptp_clock)) { 338 err = ptp_ptr->ptp_clock ? 339 PTR_ERR(ptp_ptr->ptp_clock) : -ENODEV; 340 kfree(ptp_ptr); 341 goto error; 342 } 343 344 if (is_dev_otx2(pfvf->pdev)) { 345 ptp_ptr->convert_rx_ptp_tstmp = &otx2_ptp_convert_rx_timestamp; 346 ptp_ptr->convert_tx_ptp_tstmp = &otx2_ptp_convert_tx_timestamp; 347 } else { 348 ptp_ptr->convert_rx_ptp_tstmp = &cn10k_ptp_convert_timestamp; 349 ptp_ptr->convert_tx_ptp_tstmp = &cn10k_ptp_convert_timestamp; 350 } 351 352 INIT_DELAYED_WORK(&ptp_ptr->synctstamp_work, otx2_sync_tstamp); 353 354 pfvf->ptp = ptp_ptr; 355 356 error: 357 return err; 358 } 359 EXPORT_SYMBOL_GPL(otx2_ptp_init); 360 361 void otx2_ptp_destroy(struct otx2_nic *pfvf) 362 { 363 struct otx2_ptp *ptp = pfvf->ptp; 364 365 if (!ptp) 366 return; 367 368 cancel_delayed_work(&pfvf->ptp->synctstamp_work); 369 370 ptp_clock_unregister(ptp->ptp_clock); 371 kfree(ptp); 372 pfvf->ptp = NULL; 373 } 374 EXPORT_SYMBOL_GPL(otx2_ptp_destroy); 375 376 int otx2_ptp_clock_index(struct otx2_nic *pfvf) 377 { 378 if (!pfvf->ptp) 379 return -ENODEV; 380 381 return ptp_clock_index(pfvf->ptp->ptp_clock); 382 } 383 EXPORT_SYMBOL_GPL(otx2_ptp_clock_index); 384 385 int otx2_ptp_tstamp2time(struct otx2_nic *pfvf, u64 tstamp, u64 *tsns) 386 { 387 if (!pfvf->ptp) 388 return -ENODEV; 389 390 *tsns = timecounter_cyc2time(&pfvf->ptp->time_counter, tstamp); 391 392 return 0; 393 } 394 EXPORT_SYMBOL_GPL(otx2_ptp_tstamp2time); 395 396 MODULE_AUTHOR("Sunil Goutham <sgoutham@marvell.com>"); 397 MODULE_DESCRIPTION("Marvell RVU NIC PTP Driver"); 398 MODULE_LICENSE("GPL v2"); 399