1 /* PTP 1588 clock using the Renesas Ethernet AVB
3 * Copyright (C) 2013-2015 Renesas Electronics Corporation
4 * Copyright (C) 2015 Renesas Solutions Corp.
5 * Copyright (C) 2015-2016 Cogent Embedded, Inc. <source@cogentembedded.com>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
15 static int ravb_ptp_tcr_request(struct ravb_private
*priv
, u32 request
)
17 struct net_device
*ndev
= priv
->ndev
;
20 error
= ravb_wait(ndev
, GCCR
, GCCR_TCR
, GCCR_TCR_NOREQ
);
24 ravb_modify(ndev
, GCCR
, request
, request
);
25 return ravb_wait(ndev
, GCCR
, GCCR_TCR
, GCCR_TCR_NOREQ
);
28 /* Caller must hold the lock */
29 static int ravb_ptp_time_read(struct ravb_private
*priv
, struct timespec64
*ts
)
31 struct net_device
*ndev
= priv
->ndev
;
34 error
= ravb_ptp_tcr_request(priv
, GCCR_TCR_CAPTURE
);
38 ts
->tv_nsec
= ravb_read(ndev
, GCT0
);
39 ts
->tv_sec
= ravb_read(ndev
, GCT1
) |
40 ((s64
)ravb_read(ndev
, GCT2
) << 32);
45 /* Caller must hold the lock */
46 static int ravb_ptp_time_write(struct ravb_private
*priv
,
47 const struct timespec64
*ts
)
49 struct net_device
*ndev
= priv
->ndev
;
53 error
= ravb_ptp_tcr_request(priv
, GCCR_TCR_RESET
);
57 gccr
= ravb_read(ndev
, GCCR
);
60 ravb_write(ndev
, ts
->tv_nsec
, GTO0
);
61 ravb_write(ndev
, ts
->tv_sec
, GTO1
);
62 ravb_write(ndev
, (ts
->tv_sec
>> 32) & 0xffff, GTO2
);
63 ravb_write(ndev
, gccr
| GCCR_LTO
, GCCR
);
68 /* Caller must hold the lock */
69 static int ravb_ptp_update_compare(struct ravb_private
*priv
, u32 ns
)
71 struct net_device
*ndev
= priv
->ndev
;
72 /* When the comparison value (GPTC.PTCV) is in range of
73 * [x-1 to x+1] (x is the configured increment value in
74 * GTI.TIV), it may happen that a comparison match is
75 * not detected when the timer wraps around.
77 u32 gti_ns_plus_1
= (priv
->ptp
.current_addend
>> 20) + 1;
80 if (ns
< gti_ns_plus_1
)
82 else if (ns
> 0 - gti_ns_plus_1
)
83 ns
= 0 - gti_ns_plus_1
;
85 gccr
= ravb_read(ndev
, GCCR
);
88 ravb_write(ndev
, ns
, GPTC
);
89 ravb_write(ndev
, gccr
| GCCR_LPTC
, GCCR
);
94 /* PTP clock operations */
95 static int ravb_ptp_adjfreq(struct ptp_clock_info
*ptp
, s32 ppb
)
97 struct ravb_private
*priv
= container_of(ptp
, struct ravb_private
,
99 struct net_device
*ndev
= priv
->ndev
;
102 bool neg_adj
= false;
109 addend
= priv
->ptp
.default_addend
;
110 diff
= div_u64((u64
)addend
* ppb
, NSEC_PER_SEC
);
112 addend
= neg_adj
? addend
- diff
: addend
+ diff
;
114 spin_lock_irqsave(&priv
->lock
, flags
);
116 priv
->ptp
.current_addend
= addend
;
118 gccr
= ravb_read(ndev
, GCCR
);
119 if (gccr
& GCCR_LTI
) {
120 spin_unlock_irqrestore(&priv
->lock
, flags
);
123 ravb_write(ndev
, addend
& GTI_TIV
, GTI
);
124 ravb_write(ndev
, gccr
| GCCR_LTI
, GCCR
);
126 spin_unlock_irqrestore(&priv
->lock
, flags
);
131 static int ravb_ptp_adjtime(struct ptp_clock_info
*ptp
, s64 delta
)
133 struct ravb_private
*priv
= container_of(ptp
, struct ravb_private
,
135 struct timespec64 ts
;
139 spin_lock_irqsave(&priv
->lock
, flags
);
140 error
= ravb_ptp_time_read(priv
, &ts
);
142 u64 now
= ktime_to_ns(timespec64_to_ktime(ts
));
144 ts
= ns_to_timespec64(now
+ delta
);
145 error
= ravb_ptp_time_write(priv
, &ts
);
147 spin_unlock_irqrestore(&priv
->lock
, flags
);
152 static int ravb_ptp_gettime64(struct ptp_clock_info
*ptp
, struct timespec64
*ts
)
154 struct ravb_private
*priv
= container_of(ptp
, struct ravb_private
,
159 spin_lock_irqsave(&priv
->lock
, flags
);
160 error
= ravb_ptp_time_read(priv
, ts
);
161 spin_unlock_irqrestore(&priv
->lock
, flags
);
166 static int ravb_ptp_settime64(struct ptp_clock_info
*ptp
,
167 const struct timespec64
*ts
)
169 struct ravb_private
*priv
= container_of(ptp
, struct ravb_private
,
174 spin_lock_irqsave(&priv
->lock
, flags
);
175 error
= ravb_ptp_time_write(priv
, ts
);
176 spin_unlock_irqrestore(&priv
->lock
, flags
);
181 static int ravb_ptp_extts(struct ptp_clock_info
*ptp
,
182 struct ptp_extts_request
*req
, int on
)
184 struct ravb_private
*priv
= container_of(ptp
, struct ravb_private
,
186 struct net_device
*ndev
= priv
->ndev
;
192 if (priv
->ptp
.extts
[req
->index
] == on
)
194 priv
->ptp
.extts
[req
->index
] = on
;
196 spin_lock_irqsave(&priv
->lock
, flags
);
197 if (priv
->chip_id
== RCAR_GEN2
)
198 ravb_modify(ndev
, GIC
, GIC_PTCE
, on
? GIC_PTCE
: 0);
200 ravb_write(ndev
, GIE_PTCS
, GIE
);
202 ravb_write(ndev
, GID_PTCD
, GID
);
204 spin_unlock_irqrestore(&priv
->lock
, flags
);
209 static int ravb_ptp_perout(struct ptp_clock_info
*ptp
,
210 struct ptp_perout_request
*req
, int on
)
212 struct ravb_private
*priv
= container_of(ptp
, struct ravb_private
,
214 struct net_device
*ndev
= priv
->ndev
;
215 struct ravb_ptp_perout
*perout
;
226 start_ns
= req
->start
.sec
* NSEC_PER_SEC
+ req
->start
.nsec
;
227 period_ns
= req
->period
.sec
* NSEC_PER_SEC
+ req
->period
.nsec
;
229 if (start_ns
> U32_MAX
) {
231 "ptp: start value (nsec) is over limit. Maximum size of start is only 32 bits\n");
235 if (period_ns
> U32_MAX
) {
237 "ptp: period value (nsec) is over limit. Maximum size of period is only 32 bits\n");
241 spin_lock_irqsave(&priv
->lock
, flags
);
243 perout
= &priv
->ptp
.perout
[req
->index
];
244 perout
->target
= (u32
)start_ns
;
245 perout
->period
= (u32
)period_ns
;
246 error
= ravb_ptp_update_compare(priv
, (u32
)start_ns
);
248 /* Unmask interrupt */
249 if (priv
->chip_id
== RCAR_GEN2
)
250 ravb_modify(ndev
, GIC
, GIC_PTME
, GIC_PTME
);
252 ravb_write(ndev
, GIE_PTMS0
, GIE
);
255 spin_lock_irqsave(&priv
->lock
, flags
);
257 perout
= &priv
->ptp
.perout
[req
->index
];
261 if (priv
->chip_id
== RCAR_GEN2
)
262 ravb_modify(ndev
, GIC
, GIC_PTME
, 0);
264 ravb_write(ndev
, GID_PTMD0
, GID
);
267 spin_unlock_irqrestore(&priv
->lock
, flags
);
272 static int ravb_ptp_enable(struct ptp_clock_info
*ptp
,
273 struct ptp_clock_request
*req
, int on
)
276 case PTP_CLK_REQ_EXTTS
:
277 return ravb_ptp_extts(ptp
, &req
->extts
, on
);
278 case PTP_CLK_REQ_PEROUT
:
279 return ravb_ptp_perout(ptp
, &req
->perout
, on
);
285 static const struct ptp_clock_info ravb_ptp_info
= {
286 .owner
= THIS_MODULE
,
287 .name
= "ravb clock",
289 .n_ext_ts
= N_EXT_TS
,
290 .n_per_out
= N_PER_OUT
,
291 .adjfreq
= ravb_ptp_adjfreq
,
292 .adjtime
= ravb_ptp_adjtime
,
293 .gettime64
= ravb_ptp_gettime64
,
294 .settime64
= ravb_ptp_settime64
,
295 .enable
= ravb_ptp_enable
,
298 /* Caller must hold the lock */
299 void ravb_ptp_interrupt(struct net_device
*ndev
)
301 struct ravb_private
*priv
= netdev_priv(ndev
);
302 u32 gis
= ravb_read(ndev
, GIS
);
304 gis
&= ravb_read(ndev
, GIC
);
305 if (gis
& GIS_PTCF
) {
306 struct ptp_clock_event event
;
308 event
.type
= PTP_CLOCK_EXTTS
;
310 event
.timestamp
= ravb_read(ndev
, GCPT
);
311 ptp_clock_event(priv
->ptp
.clock
, &event
);
313 if (gis
& GIS_PTMF
) {
314 struct ravb_ptp_perout
*perout
= priv
->ptp
.perout
;
316 if (perout
->period
) {
317 perout
->target
+= perout
->period
;
318 ravb_ptp_update_compare(priv
, perout
->target
);
322 ravb_write(ndev
, ~gis
, GIS
);
325 void ravb_ptp_init(struct net_device
*ndev
, struct platform_device
*pdev
)
327 struct ravb_private
*priv
= netdev_priv(ndev
);
330 priv
->ptp
.info
= ravb_ptp_info
;
332 priv
->ptp
.default_addend
= ravb_read(ndev
, GTI
);
333 priv
->ptp
.current_addend
= priv
->ptp
.default_addend
;
335 spin_lock_irqsave(&priv
->lock
, flags
);
336 ravb_wait(ndev
, GCCR
, GCCR_TCR
, GCCR_TCR_NOREQ
);
337 ravb_modify(ndev
, GCCR
, GCCR_TCSS
, GCCR_TCSS_ADJGPTP
);
339 spin_unlock_irqrestore(&priv
->lock
, flags
);
341 priv
->ptp
.clock
= ptp_clock_register(&priv
->ptp
.info
, &pdev
->dev
);
344 void ravb_ptp_stop(struct net_device
*ndev
)
346 struct ravb_private
*priv
= netdev_priv(ndev
);
348 ravb_write(ndev
, 0, GIC
);
349 ravb_write(ndev
, 0, GIS
);
351 ptp_clock_unregister(priv
->ptp
.clock
);