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