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 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 
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 
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 
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 
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 
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 
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 
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 
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