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
otx2_ptp_adjfine(struct ptp_clock_info * ptp_info,long scaled_ppm)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
ptp_cc_read(const struct cyclecounter * cc)30 static u64 ptp_cc_read(const struct cyclecounter *cc)
31 {
32 struct otx2_ptp *ptp = container_of(cc, struct otx2_ptp, cycle_counter);
33 struct ptp_req *req;
34 struct ptp_rsp *rsp;
35 int err;
36
37 if (!ptp->nic)
38 return 0;
39
40 req = otx2_mbox_alloc_msg_ptp_op(&ptp->nic->mbox);
41 if (!req)
42 return 0;
43
44 req->op = PTP_OP_GET_CLOCK;
45
46 err = otx2_sync_mbox_msg(&ptp->nic->mbox);
47 if (err)
48 return 0;
49
50 rsp = (struct ptp_rsp *)otx2_mbox_get_rsp(&ptp->nic->mbox.mbox, 0,
51 &req->hdr);
52 if (IS_ERR(rsp))
53 return 0;
54
55 return rsp->clk;
56 }
57
otx2_ptp_adjtime(struct ptp_clock_info * ptp_info,s64 delta)58 static int otx2_ptp_adjtime(struct ptp_clock_info *ptp_info, s64 delta)
59 {
60 struct otx2_ptp *ptp = container_of(ptp_info, struct otx2_ptp,
61 ptp_info);
62 struct otx2_nic *pfvf = ptp->nic;
63
64 mutex_lock(&pfvf->mbox.lock);
65 timecounter_adjtime(&ptp->time_counter, delta);
66 mutex_unlock(&pfvf->mbox.lock);
67
68 return 0;
69 }
70
otx2_ptp_gettime(struct ptp_clock_info * ptp_info,struct timespec64 * ts)71 static int otx2_ptp_gettime(struct ptp_clock_info *ptp_info,
72 struct timespec64 *ts)
73 {
74 struct otx2_ptp *ptp = container_of(ptp_info, struct otx2_ptp,
75 ptp_info);
76 struct otx2_nic *pfvf = ptp->nic;
77 u64 nsec;
78
79 mutex_lock(&pfvf->mbox.lock);
80 nsec = timecounter_read(&ptp->time_counter);
81 mutex_unlock(&pfvf->mbox.lock);
82
83 *ts = ns_to_timespec64(nsec);
84
85 return 0;
86 }
87
otx2_ptp_settime(struct ptp_clock_info * ptp_info,const struct timespec64 * ts)88 static int otx2_ptp_settime(struct ptp_clock_info *ptp_info,
89 const struct timespec64 *ts)
90 {
91 struct otx2_ptp *ptp = container_of(ptp_info, struct otx2_ptp,
92 ptp_info);
93 struct otx2_nic *pfvf = ptp->nic;
94 u64 nsec;
95
96 nsec = timespec64_to_ns(ts);
97
98 mutex_lock(&pfvf->mbox.lock);
99 timecounter_init(&ptp->time_counter, &ptp->cycle_counter, nsec);
100 mutex_unlock(&pfvf->mbox.lock);
101
102 return 0;
103 }
104
otx2_ptp_enable(struct ptp_clock_info * ptp_info,struct ptp_clock_request * rq,int on)105 static int otx2_ptp_enable(struct ptp_clock_info *ptp_info,
106 struct ptp_clock_request *rq, int on)
107 {
108 return -EOPNOTSUPP;
109 }
110
otx2_ptp_init(struct otx2_nic * pfvf)111 int otx2_ptp_init(struct otx2_nic *pfvf)
112 {
113 struct otx2_ptp *ptp_ptr;
114 struct cyclecounter *cc;
115 struct ptp_req *req;
116 int err;
117
118 mutex_lock(&pfvf->mbox.lock);
119 /* check if PTP block is available */
120 req = otx2_mbox_alloc_msg_ptp_op(&pfvf->mbox);
121 if (!req) {
122 mutex_unlock(&pfvf->mbox.lock);
123 return -ENOMEM;
124 }
125
126 req->op = PTP_OP_GET_CLOCK;
127
128 err = otx2_sync_mbox_msg(&pfvf->mbox);
129 if (err) {
130 mutex_unlock(&pfvf->mbox.lock);
131 return err;
132 }
133 mutex_unlock(&pfvf->mbox.lock);
134
135 ptp_ptr = kzalloc(sizeof(*ptp_ptr), GFP_KERNEL);
136 if (!ptp_ptr) {
137 err = -ENOMEM;
138 goto error;
139 }
140
141 ptp_ptr->nic = pfvf;
142
143 cc = &ptp_ptr->cycle_counter;
144 cc->read = ptp_cc_read;
145 cc->mask = CYCLECOUNTER_MASK(64);
146 cc->mult = 1;
147 cc->shift = 0;
148
149 timecounter_init(&ptp_ptr->time_counter, &ptp_ptr->cycle_counter,
150 ktime_to_ns(ktime_get_real()));
151
152 ptp_ptr->ptp_info = (struct ptp_clock_info) {
153 .owner = THIS_MODULE,
154 .name = "OcteonTX2 PTP",
155 .max_adj = 1000000000ull,
156 .n_ext_ts = 0,
157 .n_pins = 0,
158 .pps = 0,
159 .adjfine = otx2_ptp_adjfine,
160 .adjtime = otx2_ptp_adjtime,
161 .gettime64 = otx2_ptp_gettime,
162 .settime64 = otx2_ptp_settime,
163 .enable = otx2_ptp_enable,
164 };
165
166 ptp_ptr->ptp_clock = ptp_clock_register(&ptp_ptr->ptp_info, pfvf->dev);
167 if (IS_ERR_OR_NULL(ptp_ptr->ptp_clock)) {
168 err = ptp_ptr->ptp_clock ?
169 PTR_ERR(ptp_ptr->ptp_clock) : -ENODEV;
170 kfree(ptp_ptr);
171 goto error;
172 }
173
174 pfvf->ptp = ptp_ptr;
175
176 error:
177 return err;
178 }
179
otx2_ptp_destroy(struct otx2_nic * pfvf)180 void otx2_ptp_destroy(struct otx2_nic *pfvf)
181 {
182 struct otx2_ptp *ptp = pfvf->ptp;
183
184 if (!ptp)
185 return;
186
187 ptp_clock_unregister(ptp->ptp_clock);
188 kfree(ptp);
189 pfvf->ptp = NULL;
190 }
191
otx2_ptp_clock_index(struct otx2_nic * pfvf)192 int otx2_ptp_clock_index(struct otx2_nic *pfvf)
193 {
194 if (!pfvf->ptp)
195 return -ENODEV;
196
197 return ptp_clock_index(pfvf->ptp->ptp_clock);
198 }
199
otx2_ptp_tstamp2time(struct otx2_nic * pfvf,u64 tstamp,u64 * tsns)200 int otx2_ptp_tstamp2time(struct otx2_nic *pfvf, u64 tstamp, u64 *tsns)
201 {
202 if (!pfvf->ptp)
203 return -ENODEV;
204
205 *tsns = timecounter_cyc2time(&pfvf->ptp->time_counter, tstamp);
206
207 return 0;
208 }
209