1 // SPDX-License-Identifier: GPL-2.0+
2 /* Microchip Sparx5 Switch driver
3  *
4  * Copyright (c) 2021 Microchip Technology Inc. and its subsidiaries.
5  *
6  * The Sparx5 Chip Register Model can be browsed at this location:
7  * https://github.com/microchip-ung/sparx-5_reginfo
8  */
9 #include <linux/ptp_classify.h>
10 
11 #include "sparx5_main_regs.h"
12 #include "sparx5_main.h"
13 
14 #define SPARX5_MAX_PTP_ID	512
15 
16 #define TOD_ACC_PIN		0x4
17 
18 enum {
19 	PTP_PIN_ACTION_IDLE = 0,
20 	PTP_PIN_ACTION_LOAD,
21 	PTP_PIN_ACTION_SAVE,
22 	PTP_PIN_ACTION_CLOCK,
23 	PTP_PIN_ACTION_DELTA,
24 	PTP_PIN_ACTION_TOD
25 };
26 
27 static u64 sparx5_ptp_get_1ppm(struct sparx5 *sparx5)
28 {
29 	/* Represents 1ppm adjustment in 2^59 format with 1.59687500000(625)
30 	 * 1.99609375000(500), 3.99218750000(250) as reference
31 	 * The value is calculated as following:
32 	 * (1/1000000)/((2^-59)/X)
33 	 */
34 
35 	u64 res;
36 
37 	switch (sparx5->coreclock) {
38 	case SPX5_CORE_CLOCK_250MHZ:
39 		res = 2301339409586;
40 		break;
41 	case SPX5_CORE_CLOCK_500MHZ:
42 		res = 1150669704793;
43 		break;
44 	case SPX5_CORE_CLOCK_625MHZ:
45 		res =  920535763834;
46 		break;
47 	default:
48 		WARN_ON("Invalid core clock");
49 		break;
50 	}
51 
52 	return res;
53 }
54 
55 static u64 sparx5_ptp_get_nominal_value(struct sparx5 *sparx5)
56 {
57 	u64 res;
58 
59 	switch (sparx5->coreclock) {
60 	case SPX5_CORE_CLOCK_250MHZ:
61 		res = 0x1FF0000000000000;
62 		break;
63 	case SPX5_CORE_CLOCK_500MHZ:
64 		res = 0x0FF8000000000000;
65 		break;
66 	case SPX5_CORE_CLOCK_625MHZ:
67 		res = 0x0CC6666666666666;
68 		break;
69 	default:
70 		WARN_ON("Invalid core clock");
71 		break;
72 	}
73 
74 	return res;
75 }
76 
77 int sparx5_ptp_hwtstamp_set(struct sparx5_port *port, struct ifreq *ifr)
78 {
79 	struct sparx5 *sparx5 = port->sparx5;
80 	struct hwtstamp_config cfg;
81 	struct sparx5_phc *phc;
82 
83 	/* For now don't allow to run ptp on ports that are part of a bridge,
84 	 * because in case of transparent clock the HW will still forward the
85 	 * frames, so there would be duplicate frames
86 	 */
87 
88 	if (test_bit(port->portno, sparx5->bridge_mask))
89 		return -EINVAL;
90 
91 	if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg)))
92 		return -EFAULT;
93 
94 	switch (cfg.tx_type) {
95 	case HWTSTAMP_TX_ON:
96 		port->ptp_cmd = IFH_REW_OP_TWO_STEP_PTP;
97 		break;
98 	case HWTSTAMP_TX_ONESTEP_SYNC:
99 		port->ptp_cmd = IFH_REW_OP_ONE_STEP_PTP;
100 		break;
101 	case HWTSTAMP_TX_OFF:
102 		port->ptp_cmd = IFH_REW_OP_NOOP;
103 		break;
104 	default:
105 		return -ERANGE;
106 	}
107 
108 	switch (cfg.rx_filter) {
109 	case HWTSTAMP_FILTER_NONE:
110 		break;
111 	case HWTSTAMP_FILTER_ALL:
112 	case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
113 	case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
114 	case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
115 	case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
116 	case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
117 	case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
118 	case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
119 	case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
120 	case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
121 	case HWTSTAMP_FILTER_PTP_V2_EVENT:
122 	case HWTSTAMP_FILTER_PTP_V2_SYNC:
123 	case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
124 	case HWTSTAMP_FILTER_NTP_ALL:
125 		cfg.rx_filter = HWTSTAMP_FILTER_ALL;
126 		break;
127 	default:
128 		return -ERANGE;
129 	}
130 
131 	/* Commit back the result & save it */
132 	mutex_lock(&sparx5->ptp_lock);
133 	phc = &sparx5->phc[SPARX5_PHC_PORT];
134 	memcpy(&phc->hwtstamp_config, &cfg, sizeof(cfg));
135 	mutex_unlock(&sparx5->ptp_lock);
136 
137 	return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0;
138 }
139 
140 int sparx5_ptp_hwtstamp_get(struct sparx5_port *port, struct ifreq *ifr)
141 {
142 	struct sparx5 *sparx5 = port->sparx5;
143 	struct sparx5_phc *phc;
144 
145 	phc = &sparx5->phc[SPARX5_PHC_PORT];
146 	return copy_to_user(ifr->ifr_data, &phc->hwtstamp_config,
147 			    sizeof(phc->hwtstamp_config)) ? -EFAULT : 0;
148 }
149 
150 static int sparx5_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
151 {
152 	struct sparx5_phc *phc = container_of(ptp, struct sparx5_phc, info);
153 	struct sparx5 *sparx5 = phc->sparx5;
154 	unsigned long flags;
155 	bool neg_adj = 0;
156 	u64 tod_inc;
157 	u64 ref;
158 
159 	if (!scaled_ppm)
160 		return 0;
161 
162 	if (scaled_ppm < 0) {
163 		neg_adj = 1;
164 		scaled_ppm = -scaled_ppm;
165 	}
166 
167 	tod_inc = sparx5_ptp_get_nominal_value(sparx5);
168 
169 	/* The multiplication is split in 2 separate additions because of
170 	 * overflow issues. If scaled_ppm with 16bit fractional part was bigger
171 	 * than 20ppm then we got overflow.
172 	 */
173 	ref = sparx5_ptp_get_1ppm(sparx5) * (scaled_ppm >> 16);
174 	ref += (sparx5_ptp_get_1ppm(sparx5) * (0xffff & scaled_ppm)) >> 16;
175 	tod_inc = neg_adj ? tod_inc - ref : tod_inc + ref;
176 
177 	spin_lock_irqsave(&sparx5->ptp_clock_lock, flags);
178 
179 	spx5_rmw(PTP_PTP_DOM_CFG_PTP_CLKCFG_DIS_SET(1 << BIT(phc->index)),
180 		 PTP_PTP_DOM_CFG_PTP_CLKCFG_DIS,
181 		 sparx5, PTP_PTP_DOM_CFG);
182 
183 	spx5_wr((u32)tod_inc & 0xFFFFFFFF, sparx5,
184 		PTP_CLK_PER_CFG(phc->index, 0));
185 	spx5_wr((u32)(tod_inc >> 32), sparx5,
186 		PTP_CLK_PER_CFG(phc->index, 1));
187 
188 	spx5_rmw(PTP_PTP_DOM_CFG_PTP_CLKCFG_DIS_SET(0),
189 		 PTP_PTP_DOM_CFG_PTP_CLKCFG_DIS, sparx5,
190 		 PTP_PTP_DOM_CFG);
191 
192 	spin_unlock_irqrestore(&sparx5->ptp_clock_lock, flags);
193 
194 	return 0;
195 }
196 
197 static int sparx5_ptp_settime64(struct ptp_clock_info *ptp,
198 				const struct timespec64 *ts)
199 {
200 	struct sparx5_phc *phc = container_of(ptp, struct sparx5_phc, info);
201 	struct sparx5 *sparx5 = phc->sparx5;
202 	unsigned long flags;
203 
204 	spin_lock_irqsave(&sparx5->ptp_clock_lock, flags);
205 
206 	/* Must be in IDLE mode before the time can be loaded */
207 	spx5_rmw(PTP_PTP_PIN_CFG_PTP_PIN_ACTION_SET(PTP_PIN_ACTION_IDLE) |
208 		 PTP_PTP_PIN_CFG_PTP_PIN_DOM_SET(phc->index) |
209 		 PTP_PTP_PIN_CFG_PTP_PIN_SYNC_SET(0),
210 		 PTP_PTP_PIN_CFG_PTP_PIN_ACTION |
211 		 PTP_PTP_PIN_CFG_PTP_PIN_DOM |
212 		 PTP_PTP_PIN_CFG_PTP_PIN_SYNC,
213 		 sparx5, PTP_PTP_PIN_CFG(TOD_ACC_PIN));
214 
215 	/* Set new value */
216 	spx5_wr(PTP_PTP_TOD_SEC_MSB_PTP_TOD_SEC_MSB_SET(upper_32_bits(ts->tv_sec)),
217 		sparx5, PTP_PTP_TOD_SEC_MSB(TOD_ACC_PIN));
218 	spx5_wr(lower_32_bits(ts->tv_sec),
219 		sparx5, PTP_PTP_TOD_SEC_LSB(TOD_ACC_PIN));
220 	spx5_wr(ts->tv_nsec, sparx5, PTP_PTP_TOD_NSEC(TOD_ACC_PIN));
221 
222 	/* Apply new values */
223 	spx5_rmw(PTP_PTP_PIN_CFG_PTP_PIN_ACTION_SET(PTP_PIN_ACTION_LOAD) |
224 		 PTP_PTP_PIN_CFG_PTP_PIN_DOM_SET(phc->index) |
225 		 PTP_PTP_PIN_CFG_PTP_PIN_SYNC_SET(0),
226 		 PTP_PTP_PIN_CFG_PTP_PIN_ACTION |
227 		 PTP_PTP_PIN_CFG_PTP_PIN_DOM |
228 		 PTP_PTP_PIN_CFG_PTP_PIN_SYNC,
229 		 sparx5, PTP_PTP_PIN_CFG(TOD_ACC_PIN));
230 
231 	spin_unlock_irqrestore(&sparx5->ptp_clock_lock, flags);
232 
233 	return 0;
234 }
235 
236 static int sparx5_ptp_gettime64(struct ptp_clock_info *ptp,
237 				struct timespec64 *ts)
238 {
239 	struct sparx5_phc *phc = container_of(ptp, struct sparx5_phc, info);
240 	struct sparx5 *sparx5 = phc->sparx5;
241 	unsigned long flags;
242 	time64_t s;
243 	s64 ns;
244 
245 	spin_lock_irqsave(&sparx5->ptp_clock_lock, flags);
246 
247 	spx5_rmw(PTP_PTP_PIN_CFG_PTP_PIN_ACTION_SET(PTP_PIN_ACTION_SAVE) |
248 		 PTP_PTP_PIN_CFG_PTP_PIN_DOM_SET(phc->index) |
249 		 PTP_PTP_PIN_CFG_PTP_PIN_SYNC_SET(0),
250 		 PTP_PTP_PIN_CFG_PTP_PIN_ACTION |
251 		 PTP_PTP_PIN_CFG_PTP_PIN_DOM |
252 		 PTP_PTP_PIN_CFG_PTP_PIN_SYNC,
253 		 sparx5, PTP_PTP_PIN_CFG(TOD_ACC_PIN));
254 
255 	s = spx5_rd(sparx5, PTP_PTP_TOD_SEC_MSB(TOD_ACC_PIN));
256 	s <<= 32;
257 	s |= spx5_rd(sparx5, PTP_PTP_TOD_SEC_LSB(TOD_ACC_PIN));
258 	ns = spx5_rd(sparx5, PTP_PTP_TOD_NSEC(TOD_ACC_PIN));
259 	ns &= PTP_PTP_TOD_NSEC_PTP_TOD_NSEC;
260 
261 	spin_unlock_irqrestore(&sparx5->ptp_clock_lock, flags);
262 
263 	/* Deal with negative values */
264 	if ((ns & 0xFFFFFFF0) == 0x3FFFFFF0) {
265 		s--;
266 		ns &= 0xf;
267 		ns += 999999984;
268 	}
269 
270 	set_normalized_timespec64(ts, s, ns);
271 	return 0;
272 }
273 
274 static int sparx5_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
275 {
276 	struct sparx5_phc *phc = container_of(ptp, struct sparx5_phc, info);
277 	struct sparx5 *sparx5 = phc->sparx5;
278 
279 	if (delta > -(NSEC_PER_SEC / 2) && delta < (NSEC_PER_SEC / 2)) {
280 		unsigned long flags;
281 
282 		spin_lock_irqsave(&sparx5->ptp_clock_lock, flags);
283 
284 		/* Must be in IDLE mode before the time can be loaded */
285 		spx5_rmw(PTP_PTP_PIN_CFG_PTP_PIN_ACTION_SET(PTP_PIN_ACTION_IDLE) |
286 			 PTP_PTP_PIN_CFG_PTP_PIN_DOM_SET(phc->index) |
287 			 PTP_PTP_PIN_CFG_PTP_PIN_SYNC_SET(0),
288 			 PTP_PTP_PIN_CFG_PTP_PIN_ACTION |
289 			 PTP_PTP_PIN_CFG_PTP_PIN_DOM |
290 			 PTP_PTP_PIN_CFG_PTP_PIN_SYNC,
291 			 sparx5, PTP_PTP_PIN_CFG(TOD_ACC_PIN));
292 
293 		spx5_wr(PTP_PTP_TOD_NSEC_PTP_TOD_NSEC_SET(delta),
294 			sparx5, PTP_PTP_TOD_NSEC(TOD_ACC_PIN));
295 
296 		/* Adjust time with the value of PTP_TOD_NSEC */
297 		spx5_rmw(PTP_PTP_PIN_CFG_PTP_PIN_ACTION_SET(PTP_PIN_ACTION_DELTA) |
298 			 PTP_PTP_PIN_CFG_PTP_PIN_DOM_SET(phc->index) |
299 			 PTP_PTP_PIN_CFG_PTP_PIN_SYNC_SET(0),
300 			 PTP_PTP_PIN_CFG_PTP_PIN_ACTION |
301 			 PTP_PTP_PIN_CFG_PTP_PIN_DOM |
302 			 PTP_PTP_PIN_CFG_PTP_PIN_SYNC,
303 			 sparx5, PTP_PTP_PIN_CFG(TOD_ACC_PIN));
304 
305 		spin_unlock_irqrestore(&sparx5->ptp_clock_lock, flags);
306 	} else {
307 		/* Fall back using sparx5_ptp_settime64 which is not exact */
308 		struct timespec64 ts;
309 		u64 now;
310 
311 		sparx5_ptp_gettime64(ptp, &ts);
312 
313 		now = ktime_to_ns(timespec64_to_ktime(ts));
314 		ts = ns_to_timespec64(now + delta);
315 
316 		sparx5_ptp_settime64(ptp, &ts);
317 	}
318 
319 	return 0;
320 }
321 
322 static struct ptp_clock_info sparx5_ptp_clock_info = {
323 	.owner		= THIS_MODULE,
324 	.name		= "sparx5 ptp",
325 	.max_adj	= 200000,
326 	.gettime64	= sparx5_ptp_gettime64,
327 	.settime64	= sparx5_ptp_settime64,
328 	.adjtime	= sparx5_ptp_adjtime,
329 	.adjfine	= sparx5_ptp_adjfine,
330 };
331 
332 static int sparx5_ptp_phc_init(struct sparx5 *sparx5,
333 			       int index,
334 			       struct ptp_clock_info *clock_info)
335 {
336 	struct sparx5_phc *phc = &sparx5->phc[index];
337 
338 	phc->info = *clock_info;
339 	phc->clock = ptp_clock_register(&phc->info, sparx5->dev);
340 	if (IS_ERR(phc->clock))
341 		return PTR_ERR(phc->clock);
342 
343 	phc->index = index;
344 	phc->sparx5 = sparx5;
345 
346 	/* PTP Rx stamping is always enabled.  */
347 	phc->hwtstamp_config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
348 
349 	return 0;
350 }
351 
352 int sparx5_ptp_init(struct sparx5 *sparx5)
353 {
354 	u64 tod_adj = sparx5_ptp_get_nominal_value(sparx5);
355 	int err, i;
356 
357 	if (!sparx5->ptp)
358 		return 0;
359 
360 	for (i = 0; i < SPARX5_PHC_COUNT; ++i) {
361 		err = sparx5_ptp_phc_init(sparx5, i, &sparx5_ptp_clock_info);
362 		if (err)
363 			return err;
364 	}
365 
366 	spin_lock_init(&sparx5->ptp_clock_lock);
367 	mutex_init(&sparx5->ptp_lock);
368 
369 	/* Disable master counters */
370 	spx5_wr(PTP_PTP_DOM_CFG_PTP_ENA_SET(0), sparx5, PTP_PTP_DOM_CFG);
371 
372 	/* Configure the nominal TOD increment per clock cycle */
373 	spx5_rmw(PTP_PTP_DOM_CFG_PTP_CLKCFG_DIS_SET(0x7),
374 		 PTP_PTP_DOM_CFG_PTP_CLKCFG_DIS,
375 		 sparx5, PTP_PTP_DOM_CFG);
376 
377 	for (i = 0; i < SPARX5_PHC_COUNT; ++i) {
378 		spx5_wr((u32)tod_adj & 0xFFFFFFFF, sparx5,
379 			PTP_CLK_PER_CFG(i, 0));
380 		spx5_wr((u32)(tod_adj >> 32), sparx5,
381 			PTP_CLK_PER_CFG(i, 1));
382 	}
383 
384 	spx5_rmw(PTP_PTP_DOM_CFG_PTP_CLKCFG_DIS_SET(0),
385 		 PTP_PTP_DOM_CFG_PTP_CLKCFG_DIS,
386 		 sparx5, PTP_PTP_DOM_CFG);
387 
388 	/* Enable master counters */
389 	spx5_wr(PTP_PTP_DOM_CFG_PTP_ENA_SET(0x7), sparx5, PTP_PTP_DOM_CFG);
390 
391 	return 0;
392 }
393 
394 void sparx5_ptp_deinit(struct sparx5 *sparx5)
395 {
396 	int i;
397 
398 	for (i = 0; i < SPARX5_PHC_COUNT; ++i)
399 		ptp_clock_unregister(sparx5->phc[i].clock);
400 }
401