1 // SPDX-License-Identifier: GPL-2.0
3 * Marvell PP2.2 TAI support
6 * Do NOT use the event capture support.
7 * Do Not even set the MPP muxes to allow PTP_EVENT_REQ to be used.
8 * It will disrupt the operation of this driver, and there is nothing
9 * that this driver can do to prevent that. Even using PTP_EVENT_REQ
10 * as an output will be seen as a trigger input, which can't be masked.
11 * When ever a trigger input is seen, the action in the TCFCR0_TCF
12 * field will be performed - whether it is a set, increment, decrement
13 * read, or frequency update.
15 * Other notes (useful, not specified in the documentation):
16 * - PTP_PULSE_OUT (PTP_EVENT_REQ MPP)
17 * It looks like the hardware can't generate a pulse at nsec=0. (The
18 * output doesn't trigger if the nsec field is zero.)
19 * Note: when configured as an output via the register at 0xfX441120,
20 * the input is still very much alive, and will trigger the current TCF
22 * - PTP_CLK_OUT (PTP_TRIG_GEN MPP)
23 * This generates a "PPS" signal determined by the CCC registers. It
24 * seems this is not aligned to the TOD counter in any way (it may be
25 * initially, but if you specify a non-round second interval, it won't,
26 * and you can't easily get it back.)
28 * This generates a 50% duty cycle clock based on the TOD counter, and
29 * seems it can be set to any period of 1ns resolution. It is probably
30 * limited by the TOD step size. Its period is defined by the PCLK_CCC
31 * registers. Again, its alignment to the second is questionable.
33 * Consequently, we support none of these.
36 #include <linux/ptp_clock_kernel.h>
37 #include <linux/slab.h>
41 #define CR0_SW_NRESET BIT(0)
43 #define TCFCR0_PHASE_UPDATE_ENABLE BIT(8)
44 #define TCFCR0_TCF_MASK (7 << 2)
45 #define TCFCR0_TCF_UPDATE (0 << 2)
46 #define TCFCR0_TCF_FREQUPDATE (1 << 2)
47 #define TCFCR0_TCF_INCREMENT (2 << 2)
48 #define TCFCR0_TCF_DECREMENT (3 << 2)
49 #define TCFCR0_TCF_CAPTURE (4 << 2)
50 #define TCFCR0_TCF_NOP (7 << 2)
51 #define TCFCR0_TCF_TRIGGER BIT(0)
53 #define TCSR_CAPTURE_1_VALID BIT(1)
54 #define TCSR_CAPTURE_0_VALID BIT(0)
57 struct ptp_clock_info caps
;
58 struct ptp_clock
*ptp_clock
;
61 u64 period
; // nanosecond period in 32.32 fixed point
62 /* This timestamp is updated every two seconds */
63 struct timespec64 stamp
;
66 static void mvpp2_tai_modify(void __iomem
*reg
, u32 mask
, u32 set
)
70 val
= readl_relaxed(reg
) & ~mask
;
75 static void mvpp2_tai_write(u32 val
, void __iomem
*reg
)
77 writel_relaxed(val
& 0xffff, reg
);
80 static u32
mvpp2_tai_read(void __iomem
*reg
)
82 return readl_relaxed(reg
) & 0xffff;
85 static struct mvpp2_tai
*ptp_to_tai(struct ptp_clock_info
*ptp
)
87 return container_of(ptp
, struct mvpp2_tai
, caps
);
90 static void mvpp22_tai_read_ts(struct timespec64
*ts
, void __iomem
*base
)
92 ts
->tv_sec
= (u64
)mvpp2_tai_read(base
+ 0) << 32 |
93 mvpp2_tai_read(base
+ 4) << 16 |
94 mvpp2_tai_read(base
+ 8);
96 ts
->tv_nsec
= mvpp2_tai_read(base
+ 12) << 16 |
97 mvpp2_tai_read(base
+ 16);
99 /* Read and discard fractional part */
100 readl_relaxed(base
+ 20);
101 readl_relaxed(base
+ 24);
104 static void mvpp2_tai_write_tlv(const struct timespec64
*ts
, u32 frac
,
107 mvpp2_tai_write(ts
->tv_sec
>> 32, base
+ MVPP22_TAI_TLV_SEC_HIGH
);
108 mvpp2_tai_write(ts
->tv_sec
>> 16, base
+ MVPP22_TAI_TLV_SEC_MED
);
109 mvpp2_tai_write(ts
->tv_sec
, base
+ MVPP22_TAI_TLV_SEC_LOW
);
110 mvpp2_tai_write(ts
->tv_nsec
>> 16, base
+ MVPP22_TAI_TLV_NANO_HIGH
);
111 mvpp2_tai_write(ts
->tv_nsec
, base
+ MVPP22_TAI_TLV_NANO_LOW
);
112 mvpp2_tai_write(frac
>> 16, base
+ MVPP22_TAI_TLV_FRAC_HIGH
);
113 mvpp2_tai_write(frac
, base
+ MVPP22_TAI_TLV_FRAC_LOW
);
116 static void mvpp2_tai_op(u32 op
, void __iomem
*base
)
118 /* Trigger the operation. Note that an external unmaskable
119 * event on PTP_EVENT_REQ will also trigger this action.
121 mvpp2_tai_modify(base
+ MVPP22_TAI_TCFCR0
,
122 TCFCR0_TCF_MASK
| TCFCR0_TCF_TRIGGER
,
123 op
| TCFCR0_TCF_TRIGGER
);
124 mvpp2_tai_modify(base
+ MVPP22_TAI_TCFCR0
, TCFCR0_TCF_MASK
,
128 /* The adjustment has a range of +0.5ns to -0.5ns in 2^32 steps, so has units
131 * units(s) = 1 / (2^32 * 10^9)
132 * fractional = abs_scaled_ppm / (2^16 * 10^6)
134 * What we want to achieve:
135 * freq_adjusted = freq_nominal * (1 + fractional)
136 * freq_delta = freq_adjusted - freq_nominal => positive = faster
137 * freq_delta = freq_nominal * (1 + fractional) - freq_nominal
138 * So: freq_delta = freq_nominal * fractional
140 * However, we are dealing with periods, so:
141 * period_adjusted = period_nominal / (1 + fractional)
142 * period_delta = period_nominal - period_adjusted => positive = faster
143 * period_delta = period_nominal * fractional / (1 + fractional)
146 * period_delta = period_nominal * abs_scaled_ppm /
147 * (2^16 * 10^6 + abs_scaled_ppm)
149 * To avoid overflow, we reduce both sides of the divide operation by a factor
152 static u64
mvpp22_calc_frac_ppm(struct mvpp2_tai
*tai
, long abs_scaled_ppm
)
154 u64 val
= tai
->period
* abs_scaled_ppm
>> 4;
156 return div_u64(val
, (1000000 << 12) + (abs_scaled_ppm
>> 4));
159 static s32
mvpp22_calc_max_adj(struct mvpp2_tai
*tai
)
164 static int mvpp22_tai_adjfine(struct ptp_clock_info
*ptp
, long scaled_ppm
)
166 struct mvpp2_tai
*tai
= ptp_to_tai(ptp
);
173 neg_adj
= scaled_ppm
< 0;
175 scaled_ppm
= -scaled_ppm
;
177 val
= mvpp22_calc_frac_ppm(tai
, scaled_ppm
);
179 /* Convert to a signed 32-bit adjustment */
181 /* -S32_MIN warns, -val < S32_MIN fails, so go for the easy
184 if (val
> 0x80000000)
196 spin_lock_irqsave(&tai
->lock
, flags
);
197 mvpp2_tai_write(frac
>> 16, base
+ MVPP22_TAI_TLV_FRAC_HIGH
);
198 mvpp2_tai_write(frac
, base
+ MVPP22_TAI_TLV_FRAC_LOW
);
199 mvpp2_tai_op(TCFCR0_TCF_FREQUPDATE
, base
);
200 spin_unlock_irqrestore(&tai
->lock
, flags
);
205 static int mvpp22_tai_adjtime(struct ptp_clock_info
*ptp
, s64 delta
)
207 struct mvpp2_tai
*tai
= ptp_to_tai(ptp
);
208 struct timespec64 ts
;
213 /* We can't deal with S64_MIN */
214 if (delta
== S64_MIN
)
219 tcf
= TCFCR0_TCF_DECREMENT
;
221 tcf
= TCFCR0_TCF_INCREMENT
;
224 ts
= ns_to_timespec64(delta
);
227 spin_lock_irqsave(&tai
->lock
, flags
);
228 mvpp2_tai_write_tlv(&ts
, 0, base
);
229 mvpp2_tai_op(tcf
, base
);
230 spin_unlock_irqrestore(&tai
->lock
, flags
);
235 static int mvpp22_tai_gettimex64(struct ptp_clock_info
*ptp
,
236 struct timespec64
*ts
,
237 struct ptp_system_timestamp
*sts
)
239 struct mvpp2_tai
*tai
= ptp_to_tai(ptp
);
246 spin_lock_irqsave(&tai
->lock
, flags
);
247 /* XXX: the only way to read the PTP time is for the CPU to trigger
248 * an event. However, there is no way to distinguish between the CPU
249 * triggered event, and an external event on PTP_EVENT_REQ. So this
250 * is incompatible with external use of PTP_EVENT_REQ.
252 ptp_read_system_prets(sts
);
253 mvpp2_tai_modify(base
+ MVPP22_TAI_TCFCR0
,
254 TCFCR0_TCF_MASK
| TCFCR0_TCF_TRIGGER
,
255 TCFCR0_TCF_CAPTURE
| TCFCR0_TCF_TRIGGER
);
256 ptp_read_system_postts(sts
);
257 mvpp2_tai_modify(base
+ MVPP22_TAI_TCFCR0
, TCFCR0_TCF_MASK
,
260 tcsr
= readl(base
+ MVPP22_TAI_TCSR
);
261 if (tcsr
& TCSR_CAPTURE_1_VALID
) {
262 mvpp22_tai_read_ts(ts
, base
+ MVPP22_TAI_TCV1_SEC_HIGH
);
264 } else if (tcsr
& TCSR_CAPTURE_0_VALID
) {
265 mvpp22_tai_read_ts(ts
, base
+ MVPP22_TAI_TCV0_SEC_HIGH
);
268 /* We don't seem to have a reading... */
271 spin_unlock_irqrestore(&tai
->lock
, flags
);
276 static int mvpp22_tai_settime64(struct ptp_clock_info
*ptp
,
277 const struct timespec64
*ts
)
279 struct mvpp2_tai
*tai
= ptp_to_tai(ptp
);
284 spin_lock_irqsave(&tai
->lock
, flags
);
285 mvpp2_tai_write_tlv(ts
, 0, base
);
287 /* Trigger an update to load the value from the TLV registers
288 * into the TOD counter. Note that an external unmaskable event on
289 * PTP_EVENT_REQ will also trigger this action.
291 mvpp2_tai_modify(base
+ MVPP22_TAI_TCFCR0
,
292 TCFCR0_PHASE_UPDATE_ENABLE
|
293 TCFCR0_TCF_MASK
| TCFCR0_TCF_TRIGGER
,
294 TCFCR0_TCF_UPDATE
| TCFCR0_TCF_TRIGGER
);
295 mvpp2_tai_modify(base
+ MVPP22_TAI_TCFCR0
, TCFCR0_TCF_MASK
,
297 spin_unlock_irqrestore(&tai
->lock
, flags
);
302 static long mvpp22_tai_aux_work(struct ptp_clock_info
*ptp
)
304 struct mvpp2_tai
*tai
= ptp_to_tai(ptp
);
306 mvpp22_tai_gettimex64(ptp
, &tai
->stamp
, NULL
);
308 return msecs_to_jiffies(2000);
311 static void mvpp22_tai_set_step(struct mvpp2_tai
*tai
)
313 void __iomem
*base
= tai
->base
;
316 nano
= upper_32_bits(tai
->period
);
317 frac
= lower_32_bits(tai
->period
);
319 /* As the fractional nanosecond is a signed offset, if the MSB (sign)
320 * bit is set, we have to increment the whole nanoseconds.
322 if (frac
>= 0x80000000)
325 mvpp2_tai_write(nano
, base
+ MVPP22_TAI_TOD_STEP_NANO_CR
);
326 mvpp2_tai_write(frac
>> 16, base
+ MVPP22_TAI_TOD_STEP_FRAC_HIGH
);
327 mvpp2_tai_write(frac
, base
+ MVPP22_TAI_TOD_STEP_FRAC_LOW
);
330 static void mvpp22_tai_init(struct mvpp2_tai
*tai
)
332 void __iomem
*base
= tai
->base
;
334 mvpp22_tai_set_step(tai
);
336 /* Release the TAI reset */
337 mvpp2_tai_modify(base
+ MVPP22_TAI_CR0
, CR0_SW_NRESET
, CR0_SW_NRESET
);
340 int mvpp22_tai_ptp_clock_index(struct mvpp2_tai
*tai
)
342 return ptp_clock_index(tai
->ptp_clock
);
345 void mvpp22_tai_tstamp(struct mvpp2_tai
*tai
, u32 tstamp
,
346 struct skb_shared_hwtstamps
*hwtstamp
)
348 struct timespec64 ts
;
351 /* The tstamp consists of 2 bits of seconds and 30 bits of nanoseconds.
352 * We use our stored timestamp (tai->stamp) to form a full timestamp,
353 * and we must read the seconds exactly once.
355 ts
.tv_sec
= READ_ONCE(tai
->stamp
.tv_sec
);
356 ts
.tv_nsec
= tstamp
& 0x3fffffff;
358 /* Calculate the delta in seconds between our stored timestamp and
359 * the value read from the queue. Allow timestamps one second in the
360 * past, otherwise consider them to be in the future.
362 delta
= ((tstamp
>> 30) - (ts
.tv_sec
& 3)) & 3;
367 memset(hwtstamp
, 0, sizeof(*hwtstamp
));
368 hwtstamp
->hwtstamp
= timespec64_to_ktime(ts
);
371 void mvpp22_tai_start(struct mvpp2_tai
*tai
)
375 delay
= mvpp22_tai_aux_work(&tai
->caps
);
377 ptp_schedule_worker(tai
->ptp_clock
, delay
);
380 void mvpp22_tai_stop(struct mvpp2_tai
*tai
)
382 ptp_cancel_worker_sync(tai
->ptp_clock
);
385 static void mvpp22_tai_remove(void *priv
)
387 struct mvpp2_tai
*tai
= priv
;
389 if (!IS_ERR(tai
->ptp_clock
))
390 ptp_clock_unregister(tai
->ptp_clock
);
393 int mvpp22_tai_probe(struct device
*dev
, struct mvpp2
*priv
)
395 struct mvpp2_tai
*tai
;
398 tai
= devm_kzalloc(dev
, sizeof(*tai
), GFP_KERNEL
);
402 spin_lock_init(&tai
->lock
);
404 tai
->base
= priv
->iface_base
;
406 /* The step size consists of three registers - a 16-bit nanosecond step
407 * size, and a 32-bit fractional nanosecond step size split over two
408 * registers. The fractional nanosecond step size has units of 2^-32ns.
410 * To calculate this, we calculate:
411 * (10^9 + freq / 2) / (freq * 2^-32)
412 * which gives us the nanosecond step to the nearest integer in 16.32
413 * fixed point format, and the fractional part of the step size with
414 * the MSB inverted. With rounding of the fractional nanosecond, and
415 * simplification, this becomes:
416 * (10^9 << 32 + freq << 31 + (freq + 1) >> 1) / freq
419 * div = (10^9 << 32 + freq << 31 + (freq + 1) >> 1) / freq
420 * nano = upper_32_bits(div);
421 * frac = lower_32_bits(div) ^ 0x80000000;
422 * Will give the values for the registers.
424 * This is all seems perfect, but alas it is not when considering the
425 * whole story. The system is clocked from 25MHz, which is multiplied
426 * by a PLL to 1GHz, and then divided by three, giving 333333333Hz
427 * (recurring). This gives exactly 3ns, but using 333333333Hz with
428 * the above gives an error of 13*2^-32ns.
430 * Consequently, we use the period rather than calculating from the
433 tai
->period
= 3ULL << 32;
435 mvpp22_tai_init(tai
);
437 tai
->caps
.owner
= THIS_MODULE
;
438 strscpy(tai
->caps
.name
, "Marvell PP2.2", sizeof(tai
->caps
.name
));
439 tai
->caps
.max_adj
= mvpp22_calc_max_adj(tai
);
440 tai
->caps
.adjfine
= mvpp22_tai_adjfine
;
441 tai
->caps
.adjtime
= mvpp22_tai_adjtime
;
442 tai
->caps
.gettimex64
= mvpp22_tai_gettimex64
;
443 tai
->caps
.settime64
= mvpp22_tai_settime64
;
444 tai
->caps
.do_aux_work
= mvpp22_tai_aux_work
;
446 ret
= devm_add_action(dev
, mvpp22_tai_remove
, tai
);
450 tai
->ptp_clock
= ptp_clock_register(&tai
->caps
, dev
);
451 if (IS_ERR(tai
->ptp_clock
))
452 return PTR_ERR(tai
->ptp_clock
);