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