1 // SPDX-License-Identifier: (GPL-2.0 OR MIT)
2 /* Microsemi Ocelot PTP clock driver
3 *
4 * Copyright (c) 2017 Microsemi Corporation
5 * Copyright 2020 NXP
6 */
7 #include <soc/mscc/ocelot_ptp.h>
8 #include <soc/mscc/ocelot_sys.h>
9 #include <soc/mscc/ocelot.h>
10
ocelot_ptp_gettime64(struct ptp_clock_info * ptp,struct timespec64 * ts)11 int ocelot_ptp_gettime64(struct ptp_clock_info *ptp, struct timespec64 *ts)
12 {
13 struct ocelot *ocelot = container_of(ptp, struct ocelot, ptp_info);
14 unsigned long flags;
15 time64_t s;
16 u32 val;
17 s64 ns;
18
19 spin_lock_irqsave(&ocelot->ptp_clock_lock, flags);
20
21 val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN);
22 val &= ~(PTP_PIN_CFG_SYNC | PTP_PIN_CFG_ACTION_MASK | PTP_PIN_CFG_DOM);
23 val |= PTP_PIN_CFG_ACTION(PTP_PIN_ACTION_SAVE);
24 ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN);
25
26 s = ocelot_read_rix(ocelot, PTP_PIN_TOD_SEC_MSB, TOD_ACC_PIN) & 0xffff;
27 s <<= 32;
28 s += ocelot_read_rix(ocelot, PTP_PIN_TOD_SEC_LSB, TOD_ACC_PIN);
29 ns = ocelot_read_rix(ocelot, PTP_PIN_TOD_NSEC, TOD_ACC_PIN);
30
31 spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags);
32
33 /* Deal with negative values */
34 if (ns >= 0x3ffffff0 && ns <= 0x3fffffff) {
35 s--;
36 ns &= 0xf;
37 ns += 999999984;
38 }
39
40 set_normalized_timespec64(ts, s, ns);
41 return 0;
42 }
43 EXPORT_SYMBOL(ocelot_ptp_gettime64);
44
ocelot_ptp_settime64(struct ptp_clock_info * ptp,const struct timespec64 * ts)45 int ocelot_ptp_settime64(struct ptp_clock_info *ptp,
46 const struct timespec64 *ts)
47 {
48 struct ocelot *ocelot = container_of(ptp, struct ocelot, ptp_info);
49 unsigned long flags;
50 u32 val;
51
52 spin_lock_irqsave(&ocelot->ptp_clock_lock, flags);
53
54 val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN);
55 val &= ~(PTP_PIN_CFG_SYNC | PTP_PIN_CFG_ACTION_MASK | PTP_PIN_CFG_DOM);
56 val |= PTP_PIN_CFG_ACTION(PTP_PIN_ACTION_IDLE);
57
58 ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN);
59
60 ocelot_write_rix(ocelot, lower_32_bits(ts->tv_sec), PTP_PIN_TOD_SEC_LSB,
61 TOD_ACC_PIN);
62 ocelot_write_rix(ocelot, upper_32_bits(ts->tv_sec), PTP_PIN_TOD_SEC_MSB,
63 TOD_ACC_PIN);
64 ocelot_write_rix(ocelot, ts->tv_nsec, PTP_PIN_TOD_NSEC, TOD_ACC_PIN);
65
66 val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN);
67 val &= ~(PTP_PIN_CFG_SYNC | PTP_PIN_CFG_ACTION_MASK | PTP_PIN_CFG_DOM);
68 val |= PTP_PIN_CFG_ACTION(PTP_PIN_ACTION_LOAD);
69
70 ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN);
71
72 spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags);
73 return 0;
74 }
75 EXPORT_SYMBOL(ocelot_ptp_settime64);
76
ocelot_ptp_adjtime(struct ptp_clock_info * ptp,s64 delta)77 int ocelot_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
78 {
79 if (delta > -(NSEC_PER_SEC / 2) && delta < (NSEC_PER_SEC / 2)) {
80 struct ocelot *ocelot = container_of(ptp, struct ocelot,
81 ptp_info);
82 unsigned long flags;
83 u32 val;
84
85 spin_lock_irqsave(&ocelot->ptp_clock_lock, flags);
86
87 val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN);
88 val &= ~(PTP_PIN_CFG_SYNC | PTP_PIN_CFG_ACTION_MASK |
89 PTP_PIN_CFG_DOM);
90 val |= PTP_PIN_CFG_ACTION(PTP_PIN_ACTION_IDLE);
91
92 ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN);
93
94 ocelot_write_rix(ocelot, 0, PTP_PIN_TOD_SEC_LSB, TOD_ACC_PIN);
95 ocelot_write_rix(ocelot, 0, PTP_PIN_TOD_SEC_MSB, TOD_ACC_PIN);
96 ocelot_write_rix(ocelot, delta, PTP_PIN_TOD_NSEC, TOD_ACC_PIN);
97
98 val = ocelot_read_rix(ocelot, PTP_PIN_CFG, TOD_ACC_PIN);
99 val &= ~(PTP_PIN_CFG_SYNC | PTP_PIN_CFG_ACTION_MASK |
100 PTP_PIN_CFG_DOM);
101 val |= PTP_PIN_CFG_ACTION(PTP_PIN_ACTION_DELTA);
102
103 ocelot_write_rix(ocelot, val, PTP_PIN_CFG, TOD_ACC_PIN);
104
105 spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags);
106 } else {
107 /* Fall back using ocelot_ptp_settime64 which is not exact. */
108 struct timespec64 ts;
109 u64 now;
110
111 ocelot_ptp_gettime64(ptp, &ts);
112
113 now = ktime_to_ns(timespec64_to_ktime(ts));
114 ts = ns_to_timespec64(now + delta);
115
116 ocelot_ptp_settime64(ptp, &ts);
117 }
118 return 0;
119 }
120 EXPORT_SYMBOL(ocelot_ptp_adjtime);
121
ocelot_ptp_adjfine(struct ptp_clock_info * ptp,long scaled_ppm)122 int ocelot_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
123 {
124 struct ocelot *ocelot = container_of(ptp, struct ocelot, ptp_info);
125 u32 unit = 0, direction = 0;
126 unsigned long flags;
127 u64 adj = 0;
128
129 spin_lock_irqsave(&ocelot->ptp_clock_lock, flags);
130
131 if (!scaled_ppm)
132 goto disable_adj;
133
134 if (scaled_ppm < 0) {
135 direction = PTP_CFG_CLK_ADJ_CFG_DIR;
136 scaled_ppm = -scaled_ppm;
137 }
138
139 adj = PSEC_PER_SEC << 16;
140 do_div(adj, scaled_ppm);
141 do_div(adj, 1000);
142
143 /* If the adjustment value is too large, use ns instead */
144 if (adj >= (1L << 30)) {
145 unit = PTP_CFG_CLK_ADJ_FREQ_NS;
146 do_div(adj, 1000);
147 }
148
149 /* Still too big */
150 if (adj >= (1L << 30))
151 goto disable_adj;
152
153 ocelot_write(ocelot, unit | adj, PTP_CLK_CFG_ADJ_FREQ);
154 ocelot_write(ocelot, PTP_CFG_CLK_ADJ_CFG_ENA | direction,
155 PTP_CLK_CFG_ADJ_CFG);
156
157 spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags);
158 return 0;
159
160 disable_adj:
161 ocelot_write(ocelot, 0, PTP_CLK_CFG_ADJ_CFG);
162
163 spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags);
164 return 0;
165 }
166 EXPORT_SYMBOL(ocelot_ptp_adjfine);
167
ocelot_ptp_verify(struct ptp_clock_info * ptp,unsigned int pin,enum ptp_pin_function func,unsigned int chan)168 int ocelot_ptp_verify(struct ptp_clock_info *ptp, unsigned int pin,
169 enum ptp_pin_function func, unsigned int chan)
170 {
171 switch (func) {
172 case PTP_PF_NONE:
173 case PTP_PF_PEROUT:
174 break;
175 case PTP_PF_EXTTS:
176 case PTP_PF_PHYSYNC:
177 return -1;
178 }
179 return 0;
180 }
181 EXPORT_SYMBOL(ocelot_ptp_verify);
182
ocelot_ptp_enable(struct ptp_clock_info * ptp,struct ptp_clock_request * rq,int on)183 int ocelot_ptp_enable(struct ptp_clock_info *ptp,
184 struct ptp_clock_request *rq, int on)
185 {
186 struct ocelot *ocelot = container_of(ptp, struct ocelot, ptp_info);
187 struct timespec64 ts_phase, ts_period;
188 enum ocelot_ptp_pins ptp_pin;
189 unsigned long flags;
190 bool pps = false;
191 int pin = -1;
192 s64 wf_high;
193 s64 wf_low;
194 u32 val;
195
196 switch (rq->type) {
197 case PTP_CLK_REQ_PEROUT:
198 /* Reject requests with unsupported flags */
199 if (rq->perout.flags & ~(PTP_PEROUT_DUTY_CYCLE |
200 PTP_PEROUT_PHASE))
201 return -EOPNOTSUPP;
202
203 pin = ptp_find_pin(ocelot->ptp_clock, PTP_PF_PEROUT,
204 rq->perout.index);
205 if (pin == 0)
206 ptp_pin = PTP_PIN_0;
207 else if (pin == 1)
208 ptp_pin = PTP_PIN_1;
209 else if (pin == 2)
210 ptp_pin = PTP_PIN_2;
211 else if (pin == 3)
212 ptp_pin = PTP_PIN_3;
213 else
214 return -EBUSY;
215
216 ts_period.tv_sec = rq->perout.period.sec;
217 ts_period.tv_nsec = rq->perout.period.nsec;
218
219 if (ts_period.tv_sec == 1 && ts_period.tv_nsec == 0)
220 pps = true;
221
222 /* Handle turning off */
223 if (!on) {
224 spin_lock_irqsave(&ocelot->ptp_clock_lock, flags);
225 val = PTP_PIN_CFG_ACTION(PTP_PIN_ACTION_IDLE);
226 ocelot_write_rix(ocelot, val, PTP_PIN_CFG, ptp_pin);
227 spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags);
228 break;
229 }
230
231 if (rq->perout.flags & PTP_PEROUT_PHASE) {
232 ts_phase.tv_sec = rq->perout.phase.sec;
233 ts_phase.tv_nsec = rq->perout.phase.nsec;
234 } else {
235 /* Compatibility */
236 ts_phase.tv_sec = rq->perout.start.sec;
237 ts_phase.tv_nsec = rq->perout.start.nsec;
238 }
239 if (ts_phase.tv_sec || (ts_phase.tv_nsec && !pps)) {
240 dev_warn(ocelot->dev,
241 "Absolute start time not supported!\n");
242 dev_warn(ocelot->dev,
243 "Accept nsec for PPS phase adjustment, otherwise start time should be 0 0.\n");
244 return -EINVAL;
245 }
246
247 /* Calculate waveform high and low times */
248 if (rq->perout.flags & PTP_PEROUT_DUTY_CYCLE) {
249 struct timespec64 ts_on;
250
251 ts_on.tv_sec = rq->perout.on.sec;
252 ts_on.tv_nsec = rq->perout.on.nsec;
253
254 wf_high = timespec64_to_ns(&ts_on);
255 } else {
256 if (pps) {
257 wf_high = 1000;
258 } else {
259 wf_high = timespec64_to_ns(&ts_period);
260 wf_high = div_s64(wf_high, 2);
261 }
262 }
263
264 wf_low = timespec64_to_ns(&ts_period);
265 wf_low -= wf_high;
266
267 /* Handle PPS request */
268 if (pps) {
269 spin_lock_irqsave(&ocelot->ptp_clock_lock, flags);
270 ocelot_write_rix(ocelot, ts_phase.tv_nsec,
271 PTP_PIN_WF_LOW_PERIOD, ptp_pin);
272 ocelot_write_rix(ocelot, wf_high,
273 PTP_PIN_WF_HIGH_PERIOD, ptp_pin);
274 val = PTP_PIN_CFG_ACTION(PTP_PIN_ACTION_CLOCK);
275 val |= PTP_PIN_CFG_SYNC;
276 ocelot_write_rix(ocelot, val, PTP_PIN_CFG, ptp_pin);
277 spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags);
278 break;
279 }
280
281 /* Handle periodic clock */
282 if (wf_high > 0x3fffffff || wf_high <= 0x6)
283 return -EINVAL;
284 if (wf_low > 0x3fffffff || wf_low <= 0x6)
285 return -EINVAL;
286
287 spin_lock_irqsave(&ocelot->ptp_clock_lock, flags);
288 ocelot_write_rix(ocelot, wf_low, PTP_PIN_WF_LOW_PERIOD,
289 ptp_pin);
290 ocelot_write_rix(ocelot, wf_high, PTP_PIN_WF_HIGH_PERIOD,
291 ptp_pin);
292 val = PTP_PIN_CFG_ACTION(PTP_PIN_ACTION_CLOCK);
293 ocelot_write_rix(ocelot, val, PTP_PIN_CFG, ptp_pin);
294 spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags);
295 break;
296 default:
297 return -EOPNOTSUPP;
298 }
299 return 0;
300 }
301 EXPORT_SYMBOL(ocelot_ptp_enable);
302
ocelot_init_timestamp(struct ocelot * ocelot,const struct ptp_clock_info * info)303 int ocelot_init_timestamp(struct ocelot *ocelot,
304 const struct ptp_clock_info *info)
305 {
306 struct ptp_clock *ptp_clock;
307 int i;
308
309 ocelot->ptp_info = *info;
310
311 for (i = 0; i < OCELOT_PTP_PINS_NUM; i++) {
312 struct ptp_pin_desc *p = &ocelot->ptp_pins[i];
313
314 snprintf(p->name, sizeof(p->name), "switch_1588_dat%d", i);
315 p->index = i;
316 p->func = PTP_PF_NONE;
317 }
318
319 ocelot->ptp_info.pin_config = &ocelot->ptp_pins[0];
320
321 ptp_clock = ptp_clock_register(&ocelot->ptp_info, ocelot->dev);
322 if (IS_ERR(ptp_clock))
323 return PTR_ERR(ptp_clock);
324 /* Check if PHC support is missing at the configuration level */
325 if (!ptp_clock)
326 return 0;
327
328 ocelot->ptp_clock = ptp_clock;
329
330 ocelot_write(ocelot, SYS_PTP_CFG_PTP_STAMP_WID(30), SYS_PTP_CFG);
331 ocelot_write(ocelot, 0xffffffff, ANA_TABLES_PTP_ID_LOW);
332 ocelot_write(ocelot, 0xffffffff, ANA_TABLES_PTP_ID_HIGH);
333
334 ocelot_write(ocelot, PTP_CFG_MISC_PTP_EN, PTP_CFG_MISC);
335
336 /* There is no device reconfiguration, PTP Rx stamping is always
337 * enabled.
338 */
339 ocelot->hwtstamp_config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
340
341 return 0;
342 }
343 EXPORT_SYMBOL(ocelot_init_timestamp);
344
ocelot_deinit_timestamp(struct ocelot * ocelot)345 int ocelot_deinit_timestamp(struct ocelot *ocelot)
346 {
347 if (ocelot->ptp_clock)
348 ptp_clock_unregister(ocelot->ptp_clock);
349 return 0;
350 }
351 EXPORT_SYMBOL(ocelot_deinit_timestamp);
352