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