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