net: ethernet: ti: am65-cpsw/ethtool: Enable RX HW timestamp only for PTP packets
[linux-2.6-block.git] / drivers / net / ethernet / ti / am65-cpts.c
CommitLineData
f6bd5952
GS
1// SPDX-License-Identifier: GPL-2.0
2/* TI K3 AM65x Common Platform Time Sync
3 *
4 * Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com
5 *
6 */
7
8#include <linux/clk.h>
9#include <linux/clk-provider.h>
10#include <linux/err.h>
11#include <linux/if_vlan.h>
12#include <linux/interrupt.h>
13#include <linux/module.h>
14#include <linux/netdevice.h>
15#include <linux/net_tstamp.h>
16#include <linux/of.h>
17#include <linux/of_irq.h>
18#include <linux/platform_device.h>
19#include <linux/pm_runtime.h>
20#include <linux/ptp_classify.h>
21#include <linux/ptp_clock_kernel.h>
22
23#include "am65-cpts.h"
24
25struct am65_genf_regs {
26 u32 comp_lo; /* Comparison Low Value 0:31 */
27 u32 comp_hi; /* Comparison High Value 32:63 */
28 u32 control; /* control */
29 u32 length; /* Length */
30 u32 ppm_low; /* PPM Load Low Value 0:31 */
31 u32 ppm_hi; /* PPM Load High Value 32:63 */
32 u32 ts_nudge; /* Nudge value */
33} __aligned(32) __packed;
34
35#define AM65_CPTS_GENF_MAX_NUM 9
36#define AM65_CPTS_ESTF_MAX_NUM 8
37
38struct am65_cpts_regs {
39 u32 idver; /* Identification and version */
40 u32 control; /* Time sync control */
41 u32 rftclk_sel; /* Reference Clock Select Register */
42 u32 ts_push; /* Time stamp event push */
43 u32 ts_load_val_lo; /* Time Stamp Load Low Value 0:31 */
44 u32 ts_load_en; /* Time stamp load enable */
45 u32 ts_comp_lo; /* Time Stamp Comparison Low Value 0:31 */
46 u32 ts_comp_length; /* Time Stamp Comparison Length */
47 u32 intstat_raw; /* Time sync interrupt status raw */
48 u32 intstat_masked; /* Time sync interrupt status masked */
49 u32 int_enable; /* Time sync interrupt enable */
50 u32 ts_comp_nudge; /* Time Stamp Comparison Nudge Value */
51 u32 event_pop; /* Event interrupt pop */
52 u32 event_0; /* Event Time Stamp lo 0:31 */
53 u32 event_1; /* Event Type Fields */
54 u32 event_2; /* Event Type Fields domain */
55 u32 event_3; /* Event Time Stamp hi 32:63 */
56 u32 ts_load_val_hi; /* Time Stamp Load High Value 32:63 */
57 u32 ts_comp_hi; /* Time Stamp Comparison High Value 32:63 */
58 u32 ts_add_val; /* Time Stamp Add value */
59 u32 ts_ppm_low; /* Time Stamp PPM Load Low Value 0:31 */
60 u32 ts_ppm_hi; /* Time Stamp PPM Load High Value 32:63 */
61 u32 ts_nudge; /* Time Stamp Nudge value */
62 u32 reserv[33];
63 struct am65_genf_regs genf[AM65_CPTS_GENF_MAX_NUM];
64 struct am65_genf_regs estf[AM65_CPTS_ESTF_MAX_NUM];
65};
66
67/* CONTROL_REG */
68#define AM65_CPTS_CONTROL_EN BIT(0)
69#define AM65_CPTS_CONTROL_INT_TEST BIT(1)
70#define AM65_CPTS_CONTROL_TS_COMP_POLARITY BIT(2)
71#define AM65_CPTS_CONTROL_TSTAMP_EN BIT(3)
72#define AM65_CPTS_CONTROL_SEQUENCE_EN BIT(4)
73#define AM65_CPTS_CONTROL_64MODE BIT(5)
74#define AM65_CPTS_CONTROL_TS_COMP_TOG BIT(6)
75#define AM65_CPTS_CONTROL_TS_PPM_DIR BIT(7)
76#define AM65_CPTS_CONTROL_HW1_TS_PUSH_EN BIT(8)
77#define AM65_CPTS_CONTROL_HW2_TS_PUSH_EN BIT(9)
78#define AM65_CPTS_CONTROL_HW3_TS_PUSH_EN BIT(10)
79#define AM65_CPTS_CONTROL_HW4_TS_PUSH_EN BIT(11)
80#define AM65_CPTS_CONTROL_HW5_TS_PUSH_EN BIT(12)
81#define AM65_CPTS_CONTROL_HW6_TS_PUSH_EN BIT(13)
82#define AM65_CPTS_CONTROL_HW7_TS_PUSH_EN BIT(14)
83#define AM65_CPTS_CONTROL_HW8_TS_PUSH_EN BIT(15)
84#define AM65_CPTS_CONTROL_HW1_TS_PUSH_OFFSET (8)
85
4d4dce31
GS
86#define AM65_CPTS_CONTROL_TX_GENF_CLR_EN BIT(17)
87
f6bd5952
GS
88#define AM65_CPTS_CONTROL_TS_SYNC_SEL_MASK (0xF)
89#define AM65_CPTS_CONTROL_TS_SYNC_SEL_SHIFT (28)
90
91/* RFTCLK_SEL_REG */
92#define AM65_CPTS_RFTCLK_SEL_MASK (0x1F)
93
94/* TS_PUSH_REG */
95#define AM65_CPTS_TS_PUSH BIT(0)
96
97/* TS_LOAD_EN_REG */
98#define AM65_CPTS_TS_LOAD_EN BIT(0)
99
100/* INTSTAT_RAW_REG */
101#define AM65_CPTS_INTSTAT_RAW_TS_PEND BIT(0)
102
103/* INTSTAT_MASKED_REG */
104#define AM65_CPTS_INTSTAT_MASKED_TS_PEND BIT(0)
105
106/* INT_ENABLE_REG */
107#define AM65_CPTS_INT_ENABLE_TS_PEND_EN BIT(0)
108
109/* TS_COMP_NUDGE_REG */
110#define AM65_CPTS_TS_COMP_NUDGE_MASK (0xFF)
111
112/* EVENT_POP_REG */
113#define AM65_CPTS_EVENT_POP BIT(0)
114
115/* EVENT_1_REG */
116#define AM65_CPTS_EVENT_1_SEQUENCE_ID_MASK GENMASK(15, 0)
117
118#define AM65_CPTS_EVENT_1_MESSAGE_TYPE_MASK GENMASK(19, 16)
119#define AM65_CPTS_EVENT_1_MESSAGE_TYPE_SHIFT (16)
120
121#define AM65_CPTS_EVENT_1_EVENT_TYPE_MASK GENMASK(23, 20)
122#define AM65_CPTS_EVENT_1_EVENT_TYPE_SHIFT (20)
123
124#define AM65_CPTS_EVENT_1_PORT_NUMBER_MASK GENMASK(28, 24)
125#define AM65_CPTS_EVENT_1_PORT_NUMBER_SHIFT (24)
126
127/* EVENT_2_REG */
128#define AM65_CPTS_EVENT_2_REG_DOMAIN_MASK (0xFF)
129#define AM65_CPTS_EVENT_2_REG_DOMAIN_SHIFT (0)
130
131enum {
132 AM65_CPTS_EV_PUSH, /* Time Stamp Push Event */
133 AM65_CPTS_EV_ROLL, /* Time Stamp Rollover Event */
134 AM65_CPTS_EV_HALF, /* Time Stamp Half Rollover Event */
135 AM65_CPTS_EV_HW, /* Hardware Time Stamp Push Event */
136 AM65_CPTS_EV_RX, /* Ethernet Receive Event */
137 AM65_CPTS_EV_TX, /* Ethernet Transmit Event */
138 AM65_CPTS_EV_TS_COMP, /* Time Stamp Compare Event */
139 AM65_CPTS_EV_HOST, /* Host Transmit Event */
140};
141
142struct am65_cpts_event {
143 struct list_head list;
144 unsigned long tmo;
145 u32 event1;
146 u32 event2;
147 u64 timestamp;
148};
149
150#define AM65_CPTS_FIFO_DEPTH (16)
151#define AM65_CPTS_MAX_EVENTS (32)
152#define AM65_CPTS_EVENT_RX_TX_TIMEOUT (20) /* ms */
153#define AM65_CPTS_SKB_TX_WORK_TIMEOUT 1 /* jiffies */
154#define AM65_CPTS_MIN_PPM 0x400
155
156struct am65_cpts {
157 struct device *dev;
158 struct am65_cpts_regs __iomem *reg;
159 struct ptp_clock_info ptp_info;
160 struct ptp_clock *ptp_clock;
161 int phc_index;
162 struct clk_hw *clk_mux_hw;
163 struct device_node *clk_mux_np;
164 struct clk *refclk;
165 u32 refclk_freq;
166 struct list_head events;
167 struct list_head pool;
168 struct am65_cpts_event pool_data[AM65_CPTS_MAX_EVENTS];
169 spinlock_t lock; /* protects events lists*/
170 u32 ext_ts_inputs;
171 u32 genf_num;
172 u32 ts_add_val;
173 int irq;
174 struct mutex ptp_clk_lock; /* PHC access sync */
175 u64 timestamp;
176 u32 genf_enable;
177 u32 hw_ts_enable;
7849c42d 178 u32 estf_enable;
f6bd5952 179 struct sk_buff_head txq;
b6d78712
GS
180 bool pps_enabled;
181 bool pps_present;
182 u32 pps_hw_ts_idx;
183 u32 pps_genf_idx;
cef122d4
RQ
184 /* context save/restore */
185 u64 sr_cpts_ns;
186 u64 sr_ktime_ns;
187 u32 sr_control;
188 u32 sr_int_enable;
189 u32 sr_rftclk_sel;
190 u32 sr_ts_ppm_hi;
191 u32 sr_ts_ppm_low;
192 struct am65_genf_regs sr_genf[AM65_CPTS_GENF_MAX_NUM];
193 struct am65_genf_regs sr_estf[AM65_CPTS_ESTF_MAX_NUM];
f6bd5952
GS
194};
195
196struct am65_cpts_skb_cb_data {
197 unsigned long tmo;
198 u32 skb_mtype_seqid;
199};
200
201#define am65_cpts_write32(c, v, r) writel(v, &(c)->reg->r)
202#define am65_cpts_read32(c, r) readl(&(c)->reg->r)
203
204static void am65_cpts_settime(struct am65_cpts *cpts, u64 start_tstamp)
205{
206 u32 val;
207
208 val = upper_32_bits(start_tstamp);
209 am65_cpts_write32(cpts, val, ts_load_val_hi);
210 val = lower_32_bits(start_tstamp);
211 am65_cpts_write32(cpts, val, ts_load_val_lo);
212
213 am65_cpts_write32(cpts, AM65_CPTS_TS_LOAD_EN, ts_load_en);
214}
215
216static void am65_cpts_set_add_val(struct am65_cpts *cpts)
217{
218 /* select coefficient according to the rate */
219 cpts->ts_add_val = (NSEC_PER_SEC / cpts->refclk_freq - 1) & 0x7;
220
221 am65_cpts_write32(cpts, cpts->ts_add_val, ts_add_val);
222}
223
224static void am65_cpts_disable(struct am65_cpts *cpts)
225{
226 am65_cpts_write32(cpts, 0, control);
227 am65_cpts_write32(cpts, 0, int_enable);
228}
229
230static int am65_cpts_event_get_port(struct am65_cpts_event *event)
231{
232 return (event->event1 & AM65_CPTS_EVENT_1_PORT_NUMBER_MASK) >>
233 AM65_CPTS_EVENT_1_PORT_NUMBER_SHIFT;
234}
235
236static int am65_cpts_event_get_type(struct am65_cpts_event *event)
237{
238 return (event->event1 & AM65_CPTS_EVENT_1_EVENT_TYPE_MASK) >>
239 AM65_CPTS_EVENT_1_EVENT_TYPE_SHIFT;
240}
241
242static int am65_cpts_cpts_purge_events(struct am65_cpts *cpts)
243{
244 struct list_head *this, *next;
245 struct am65_cpts_event *event;
246 int removed = 0;
247
248 list_for_each_safe(this, next, &cpts->events) {
249 event = list_entry(this, struct am65_cpts_event, list);
250 if (time_after(jiffies, event->tmo)) {
251 list_del_init(&event->list);
252 list_add(&event->list, &cpts->pool);
253 ++removed;
254 }
255 }
256
257 if (removed)
258 dev_dbg(cpts->dev, "event pool cleaned up %d\n", removed);
259 return removed ? 0 : -1;
260}
261
262static bool am65_cpts_fifo_pop_event(struct am65_cpts *cpts,
263 struct am65_cpts_event *event)
264{
265 u32 r = am65_cpts_read32(cpts, intstat_raw);
266
267 if (r & AM65_CPTS_INTSTAT_RAW_TS_PEND) {
268 event->timestamp = am65_cpts_read32(cpts, event_0);
269 event->event1 = am65_cpts_read32(cpts, event_1);
270 event->event2 = am65_cpts_read32(cpts, event_2);
271 event->timestamp |= (u64)am65_cpts_read32(cpts, event_3) << 32;
272 am65_cpts_write32(cpts, AM65_CPTS_EVENT_POP, event_pop);
273 return false;
274 }
275 return true;
276}
277
c459f606 278static int __am65_cpts_fifo_read(struct am65_cpts *cpts)
f6bd5952
GS
279{
280 struct ptp_clock_event pevent;
281 struct am65_cpts_event *event;
282 bool schedule = false;
283 int i, type, ret = 0;
f6bd5952 284
f6bd5952
GS
285 for (i = 0; i < AM65_CPTS_FIFO_DEPTH; i++) {
286 event = list_first_entry_or_null(&cpts->pool,
287 struct am65_cpts_event, list);
288
289 if (!event) {
290 if (am65_cpts_cpts_purge_events(cpts)) {
291 dev_err(cpts->dev, "cpts: event pool empty\n");
292 ret = -1;
293 goto out;
294 }
295 continue;
296 }
297
298 if (am65_cpts_fifo_pop_event(cpts, event))
299 break;
300
301 type = am65_cpts_event_get_type(event);
302 switch (type) {
303 case AM65_CPTS_EV_PUSH:
304 cpts->timestamp = event->timestamp;
305 dev_dbg(cpts->dev, "AM65_CPTS_EV_PUSH t:%llu\n",
306 cpts->timestamp);
307 break;
308 case AM65_CPTS_EV_RX:
309 case AM65_CPTS_EV_TX:
310 event->tmo = jiffies +
311 msecs_to_jiffies(AM65_CPTS_EVENT_RX_TX_TIMEOUT);
312
c459f606 313 list_move_tail(&event->list, &cpts->events);
f6bd5952
GS
314
315 dev_dbg(cpts->dev,
316 "AM65_CPTS_EV_TX e1:%08x e2:%08x t:%lld\n",
317 event->event1, event->event2,
318 event->timestamp);
319 schedule = true;
320 break;
321 case AM65_CPTS_EV_HW:
322 pevent.index = am65_cpts_event_get_port(event) - 1;
323 pevent.timestamp = event->timestamp;
b6d78712
GS
324 if (cpts->pps_enabled && pevent.index == cpts->pps_hw_ts_idx) {
325 pevent.type = PTP_CLOCK_PPSUSR;
326 pevent.pps_times.ts_real = ns_to_timespec64(pevent.timestamp);
327 } else {
328 pevent.type = PTP_CLOCK_EXTTS;
329 }
330 dev_dbg(cpts->dev, "AM65_CPTS_EV_HW:%s p:%d t:%llu\n",
331 pevent.type == PTP_CLOCK_EXTTS ?
332 "extts" : "pps",
f6bd5952
GS
333 pevent.index, event->timestamp);
334
335 ptp_clock_event(cpts->ptp_clock, &pevent);
336 break;
337 case AM65_CPTS_EV_HOST:
338 break;
339 case AM65_CPTS_EV_ROLL:
340 case AM65_CPTS_EV_HALF:
341 case AM65_CPTS_EV_TS_COMP:
342 dev_dbg(cpts->dev,
343 "AM65_CPTS_EVT: %d e1:%08x e2:%08x t:%lld\n",
344 type,
345 event->event1, event->event2,
346 event->timestamp);
347 break;
348 default:
349 dev_err(cpts->dev, "cpts: unknown event type\n");
350 ret = -1;
351 goto out;
352 }
353 }
354
355out:
f6bd5952
GS
356 if (schedule)
357 ptp_schedule_worker(cpts->ptp_clock, 0);
358
359 return ret;
360}
361
c459f606
CV
362static int am65_cpts_fifo_read(struct am65_cpts *cpts)
363{
364 unsigned long flags;
365 int ret = 0;
366
367 spin_lock_irqsave(&cpts->lock, flags);
368 ret = __am65_cpts_fifo_read(cpts);
369 spin_unlock_irqrestore(&cpts->lock, flags);
370
371 return ret;
372}
373
f6bd5952
GS
374static u64 am65_cpts_gettime(struct am65_cpts *cpts,
375 struct ptp_system_timestamp *sts)
376{
377 unsigned long flags;
378 u64 val = 0;
379
380 /* temporarily disable cpts interrupt to avoid intentional
381 * doubled read. Interrupt can be in-flight - it's Ok.
382 */
383 am65_cpts_write32(cpts, 0, int_enable);
384
385 /* use spin_lock_irqsave() here as it has to run very fast */
386 spin_lock_irqsave(&cpts->lock, flags);
387 ptp_read_system_prets(sts);
388 am65_cpts_write32(cpts, AM65_CPTS_TS_PUSH, ts_push);
389 am65_cpts_read32(cpts, ts_push);
390 ptp_read_system_postts(sts);
391 spin_unlock_irqrestore(&cpts->lock, flags);
392
393 am65_cpts_fifo_read(cpts);
394
395 am65_cpts_write32(cpts, AM65_CPTS_INT_ENABLE_TS_PEND_EN, int_enable);
396
397 val = cpts->timestamp;
398
399 return val;
400}
401
402static irqreturn_t am65_cpts_interrupt(int irq, void *dev_id)
403{
404 struct am65_cpts *cpts = dev_id;
405
406 if (am65_cpts_fifo_read(cpts))
407 dev_dbg(cpts->dev, "cpts: unable to obtain a time stamp\n");
408
409 return IRQ_HANDLED;
410}
411
412/* PTP clock operations */
e2bd9c76 413static int am65_cpts_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
f6bd5952
GS
414{
415 struct am65_cpts *cpts = container_of(ptp, struct am65_cpts, ptp_info);
7849c42d 416 u32 estf_ctrl_val = 0, estf_ppm_hi = 0, estf_ppm_low = 0;
e2bd9c76 417 s32 ppb = scaled_ppm_to_ppb(scaled_ppm);
eb9233ce
GS
418 int pps_index = cpts->pps_genf_idx;
419 u64 adj_period, pps_adj_period;
420 u32 ctrl_val, ppm_hi, ppm_low;
421 unsigned long flags;
7849c42d 422 int neg_adj = 0, i;
f6bd5952
GS
423
424 if (ppb < 0) {
425 neg_adj = 1;
426 ppb = -ppb;
427 }
428
429 /* base freq = 1GHz = 1 000 000 000
430 * ppb_norm = ppb * base_freq / clock_freq;
431 * ppm_norm = ppb_norm / 1000
432 * adj_period = 1 000 000 / ppm_norm
433 * adj_period = 1 000 000 000 / ppb_norm
434 * adj_period = 1 000 000 000 / (ppb * base_freq / clock_freq)
435 * adj_period = (1 000 000 000 * clock_freq) / (ppb * base_freq)
436 * adj_period = clock_freq / ppb
437 */
438 adj_period = div_u64(cpts->refclk_freq, ppb);
439
440 mutex_lock(&cpts->ptp_clk_lock);
441
eb9233ce 442 ctrl_val = am65_cpts_read32(cpts, control);
f6bd5952 443 if (neg_adj)
eb9233ce 444 ctrl_val |= AM65_CPTS_CONTROL_TS_PPM_DIR;
f6bd5952 445 else
eb9233ce
GS
446 ctrl_val &= ~AM65_CPTS_CONTROL_TS_PPM_DIR;
447
448 ppm_hi = upper_32_bits(adj_period) & 0x3FF;
449 ppm_low = lower_32_bits(adj_period);
450
451 if (cpts->pps_enabled) {
7849c42d 452 estf_ctrl_val = am65_cpts_read32(cpts, genf[pps_index].control);
eb9233ce 453 if (neg_adj)
7849c42d 454 estf_ctrl_val &= ~BIT(1);
eb9233ce 455 else
7849c42d 456 estf_ctrl_val |= BIT(1);
eb9233ce
GS
457
458 /* GenF PPM will do correction using cpts refclk tick which is
459 * (cpts->ts_add_val + 1) ns, so GenF length PPM adj period
460 * need to be corrected.
461 */
462 pps_adj_period = adj_period * (cpts->ts_add_val + 1);
7849c42d
GS
463 estf_ppm_hi = upper_32_bits(pps_adj_period) & 0x3FF;
464 estf_ppm_low = lower_32_bits(pps_adj_period);
eb9233ce 465 }
f6bd5952 466
eb9233ce
GS
467 spin_lock_irqsave(&cpts->lock, flags);
468
469 /* All below writes must be done extremely fast:
470 * - delay between PPM dir and PPM value changes can cause err due old
471 * PPM correction applied in wrong direction
472 * - delay between CPTS-clock PPM cfg and GenF PPM cfg can cause err
473 * due CPTS-clock PPM working with new cfg while GenF PPM cfg still
474 * with old for short period of time
475 */
476
477 am65_cpts_write32(cpts, ctrl_val, control);
478 am65_cpts_write32(cpts, ppm_hi, ts_ppm_hi);
479 am65_cpts_write32(cpts, ppm_low, ts_ppm_low);
480
481 if (cpts->pps_enabled) {
7849c42d
GS
482 am65_cpts_write32(cpts, estf_ctrl_val, genf[pps_index].control);
483 am65_cpts_write32(cpts, estf_ppm_hi, genf[pps_index].ppm_hi);
484 am65_cpts_write32(cpts, estf_ppm_low, genf[pps_index].ppm_low);
eb9233ce
GS
485 }
486
7849c42d
GS
487 for (i = 0; i < AM65_CPTS_ESTF_MAX_NUM; i++) {
488 if (cpts->estf_enable & BIT(i)) {
489 am65_cpts_write32(cpts, estf_ctrl_val, estf[i].control);
490 am65_cpts_write32(cpts, estf_ppm_hi, estf[i].ppm_hi);
491 am65_cpts_write32(cpts, estf_ppm_low, estf[i].ppm_low);
492 }
493 }
eb9233ce
GS
494 /* All GenF/EstF can be updated here the same way */
495 spin_unlock_irqrestore(&cpts->lock, flags);
f6bd5952
GS
496
497 mutex_unlock(&cpts->ptp_clk_lock);
498
499 return 0;
500}
501
502static int am65_cpts_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
503{
504 struct am65_cpts *cpts = container_of(ptp, struct am65_cpts, ptp_info);
505 s64 ns;
506
507 mutex_lock(&cpts->ptp_clk_lock);
508 ns = am65_cpts_gettime(cpts, NULL);
509 ns += delta;
510 am65_cpts_settime(cpts, ns);
511 mutex_unlock(&cpts->ptp_clk_lock);
512
513 return 0;
514}
515
516static int am65_cpts_ptp_gettimex(struct ptp_clock_info *ptp,
517 struct timespec64 *ts,
518 struct ptp_system_timestamp *sts)
519{
520 struct am65_cpts *cpts = container_of(ptp, struct am65_cpts, ptp_info);
521 u64 ns;
522
523 mutex_lock(&cpts->ptp_clk_lock);
524 ns = am65_cpts_gettime(cpts, sts);
525 mutex_unlock(&cpts->ptp_clk_lock);
526 *ts = ns_to_timespec64(ns);
527
528 return 0;
529}
530
ec008fa2
IK
531u64 am65_cpts_ns_gettime(struct am65_cpts *cpts)
532{
533 u64 ns;
534
535 /* reuse ptp_clk_lock as it serialize ts push */
536 mutex_lock(&cpts->ptp_clk_lock);
537 ns = am65_cpts_gettime(cpts, NULL);
538 mutex_unlock(&cpts->ptp_clk_lock);
539
540 return ns;
541}
542EXPORT_SYMBOL_GPL(am65_cpts_ns_gettime);
543
f6bd5952
GS
544static int am65_cpts_ptp_settime(struct ptp_clock_info *ptp,
545 const struct timespec64 *ts)
546{
547 struct am65_cpts *cpts = container_of(ptp, struct am65_cpts, ptp_info);
548 u64 ns;
549
550 ns = timespec64_to_ns(ts);
551 mutex_lock(&cpts->ptp_clk_lock);
552 am65_cpts_settime(cpts, ns);
553 mutex_unlock(&cpts->ptp_clk_lock);
554
555 return 0;
556}
557
558static void am65_cpts_extts_enable_hw(struct am65_cpts *cpts, u32 index, int on)
559{
560 u32 v;
561
562 v = am65_cpts_read32(cpts, control);
563 if (on) {
564 v |= BIT(AM65_CPTS_CONTROL_HW1_TS_PUSH_OFFSET + index);
565 cpts->hw_ts_enable |= BIT(index);
566 } else {
567 v &= ~BIT(AM65_CPTS_CONTROL_HW1_TS_PUSH_OFFSET + index);
568 cpts->hw_ts_enable &= ~BIT(index);
569 }
570 am65_cpts_write32(cpts, v, control);
571}
572
573static int am65_cpts_extts_enable(struct am65_cpts *cpts, u32 index, int on)
574{
b6d78712
GS
575 if (index >= cpts->ptp_info.n_ext_ts)
576 return -ENXIO;
577
578 if (cpts->pps_present && index == cpts->pps_hw_ts_idx)
579 return -EINVAL;
580
581 if (((cpts->hw_ts_enable & BIT(index)) >> index) == on)
f6bd5952
GS
582 return 0;
583
584 mutex_lock(&cpts->ptp_clk_lock);
585 am65_cpts_extts_enable_hw(cpts, index, on);
586 mutex_unlock(&cpts->ptp_clk_lock);
587
588 dev_dbg(cpts->dev, "%s: ExtTS:%u %s\n",
589 __func__, index, on ? "enabled" : "disabled");
590
591 return 0;
592}
593
ec008fa2
IK
594int am65_cpts_estf_enable(struct am65_cpts *cpts, int idx,
595 struct am65_cpts_estf_cfg *cfg)
596{
597 u64 cycles;
598 u32 val;
599
600 cycles = cfg->ns_period * cpts->refclk_freq;
601 cycles = DIV_ROUND_UP(cycles, NSEC_PER_SEC);
602 if (cycles > U32_MAX)
603 return -EINVAL;
604
605 /* according to TRM should be zeroed */
606 am65_cpts_write32(cpts, 0, estf[idx].length);
607
608 val = upper_32_bits(cfg->ns_start);
609 am65_cpts_write32(cpts, val, estf[idx].comp_hi);
610 val = lower_32_bits(cfg->ns_start);
611 am65_cpts_write32(cpts, val, estf[idx].comp_lo);
612 val = lower_32_bits(cycles);
613 am65_cpts_write32(cpts, val, estf[idx].length);
7849c42d
GS
614 am65_cpts_write32(cpts, 0, estf[idx].control);
615 am65_cpts_write32(cpts, 0, estf[idx].ppm_hi);
616 am65_cpts_write32(cpts, 0, estf[idx].ppm_low);
617
618 cpts->estf_enable |= BIT(idx);
ec008fa2
IK
619
620 dev_dbg(cpts->dev, "%s: ESTF:%u enabled\n", __func__, idx);
621
622 return 0;
623}
624EXPORT_SYMBOL_GPL(am65_cpts_estf_enable);
625
626void am65_cpts_estf_disable(struct am65_cpts *cpts, int idx)
627{
628 am65_cpts_write32(cpts, 0, estf[idx].length);
7849c42d 629 cpts->estf_enable &= ~BIT(idx);
ec008fa2
IK
630
631 dev_dbg(cpts->dev, "%s: ESTF:%u disabled\n", __func__, idx);
632}
633EXPORT_SYMBOL_GPL(am65_cpts_estf_disable);
634
f6bd5952
GS
635static void am65_cpts_perout_enable_hw(struct am65_cpts *cpts,
636 struct ptp_perout_request *req, int on)
637{
638 u64 ns_period, ns_start, cycles;
639 struct timespec64 ts;
640 u32 val;
641
642 if (on) {
643 ts.tv_sec = req->period.sec;
644 ts.tv_nsec = req->period.nsec;
645 ns_period = timespec64_to_ns(&ts);
646
647 cycles = (ns_period * cpts->refclk_freq) / NSEC_PER_SEC;
648
649 ts.tv_sec = req->start.sec;
650 ts.tv_nsec = req->start.nsec;
651 ns_start = timespec64_to_ns(&ts);
652
653 val = upper_32_bits(ns_start);
654 am65_cpts_write32(cpts, val, genf[req->index].comp_hi);
655 val = lower_32_bits(ns_start);
656 am65_cpts_write32(cpts, val, genf[req->index].comp_lo);
657 val = lower_32_bits(cycles);
658 am65_cpts_write32(cpts, val, genf[req->index].length);
659
3dacc5bb
GS
660 am65_cpts_write32(cpts, 0, genf[req->index].control);
661 am65_cpts_write32(cpts, 0, genf[req->index].ppm_hi);
662 am65_cpts_write32(cpts, 0, genf[req->index].ppm_low);
663
f6bd5952
GS
664 cpts->genf_enable |= BIT(req->index);
665 } else {
666 am65_cpts_write32(cpts, 0, genf[req->index].length);
667
668 cpts->genf_enable &= ~BIT(req->index);
669 }
670}
671
672static int am65_cpts_perout_enable(struct am65_cpts *cpts,
673 struct ptp_perout_request *req, int on)
674{
b6d78712
GS
675 if (req->index >= cpts->ptp_info.n_per_out)
676 return -ENXIO;
677
678 if (cpts->pps_present && req->index == cpts->pps_genf_idx)
679 return -EINVAL;
680
f6bd5952
GS
681 if (!!(cpts->genf_enable & BIT(req->index)) == !!on)
682 return 0;
683
684 mutex_lock(&cpts->ptp_clk_lock);
685 am65_cpts_perout_enable_hw(cpts, req, on);
686 mutex_unlock(&cpts->ptp_clk_lock);
687
688 dev_dbg(cpts->dev, "%s: GenF:%u %s\n",
689 __func__, req->index, on ? "enabled" : "disabled");
690
691 return 0;
692}
693
b6d78712
GS
694static int am65_cpts_pps_enable(struct am65_cpts *cpts, int on)
695{
696 int ret = 0;
697 struct timespec64 ts;
698 struct ptp_clock_request rq;
699 u64 ns;
700
701 if (!cpts->pps_present)
702 return -EINVAL;
703
704 if (cpts->pps_enabled == !!on)
705 return 0;
706
707 mutex_lock(&cpts->ptp_clk_lock);
708
709 if (on) {
710 am65_cpts_extts_enable_hw(cpts, cpts->pps_hw_ts_idx, on);
711
712 ns = am65_cpts_gettime(cpts, NULL);
713 ts = ns_to_timespec64(ns);
714 rq.perout.period.sec = 1;
715 rq.perout.period.nsec = 0;
716 rq.perout.start.sec = ts.tv_sec + 2;
717 rq.perout.start.nsec = 0;
718 rq.perout.index = cpts->pps_genf_idx;
719
720 am65_cpts_perout_enable_hw(cpts, &rq.perout, on);
721 cpts->pps_enabled = true;
722 } else {
723 rq.perout.index = cpts->pps_genf_idx;
724 am65_cpts_perout_enable_hw(cpts, &rq.perout, on);
725 am65_cpts_extts_enable_hw(cpts, cpts->pps_hw_ts_idx, on);
726 cpts->pps_enabled = false;
727 }
728
729 mutex_unlock(&cpts->ptp_clk_lock);
730
731 dev_dbg(cpts->dev, "%s: pps: %s\n",
732 __func__, on ? "enabled" : "disabled");
733 return ret;
734}
735
f6bd5952
GS
736static int am65_cpts_ptp_enable(struct ptp_clock_info *ptp,
737 struct ptp_clock_request *rq, int on)
738{
739 struct am65_cpts *cpts = container_of(ptp, struct am65_cpts, ptp_info);
740
741 switch (rq->type) {
742 case PTP_CLK_REQ_EXTTS:
743 return am65_cpts_extts_enable(cpts, rq->extts.index, on);
744 case PTP_CLK_REQ_PEROUT:
745 return am65_cpts_perout_enable(cpts, &rq->perout, on);
b6d78712
GS
746 case PTP_CLK_REQ_PPS:
747 return am65_cpts_pps_enable(cpts, on);
f6bd5952
GS
748 default:
749 break;
750 }
751
752 return -EOPNOTSUPP;
753}
754
755static long am65_cpts_ts_work(struct ptp_clock_info *ptp);
756
757static struct ptp_clock_info am65_ptp_info = {
758 .owner = THIS_MODULE,
759 .name = "CTPS timer",
e2bd9c76 760 .adjfine = am65_cpts_ptp_adjfine,
f6bd5952
GS
761 .adjtime = am65_cpts_ptp_adjtime,
762 .gettimex64 = am65_cpts_ptp_gettimex,
763 .settime64 = am65_cpts_ptp_settime,
764 .enable = am65_cpts_ptp_enable,
765 .do_aux_work = am65_cpts_ts_work,
766};
767
768static bool am65_cpts_match_tx_ts(struct am65_cpts *cpts,
769 struct am65_cpts_event *event)
770{
771 struct sk_buff_head txq_list;
772 struct sk_buff *skb, *tmp;
773 unsigned long flags;
774 bool found = false;
775 u32 mtype_seqid;
776
777 mtype_seqid = event->event1 &
778 (AM65_CPTS_EVENT_1_MESSAGE_TYPE_MASK |
779 AM65_CPTS_EVENT_1_EVENT_TYPE_MASK |
780 AM65_CPTS_EVENT_1_SEQUENCE_ID_MASK);
781
782 __skb_queue_head_init(&txq_list);
783
784 spin_lock_irqsave(&cpts->txq.lock, flags);
785 skb_queue_splice_init(&cpts->txq, &txq_list);
786 spin_unlock_irqrestore(&cpts->txq.lock, flags);
787
788 /* no need to grab txq.lock as access is always done under cpts->lock */
789 skb_queue_walk_safe(&txq_list, skb, tmp) {
790 struct skb_shared_hwtstamps ssh;
791 struct am65_cpts_skb_cb_data *skb_cb =
792 (struct am65_cpts_skb_cb_data *)skb->cb;
793
794 if (mtype_seqid == skb_cb->skb_mtype_seqid) {
795 u64 ns = event->timestamp;
796
797 memset(&ssh, 0, sizeof(ssh));
798 ssh.hwtstamp = ns_to_ktime(ns);
799 skb_tstamp_tx(skb, &ssh);
800 found = true;
801 __skb_unlink(skb, &txq_list);
802 dev_consume_skb_any(skb);
803 dev_dbg(cpts->dev,
804 "match tx timestamp mtype_seqid %08x\n",
805 mtype_seqid);
806 break;
807 }
808
809 if (time_after(jiffies, skb_cb->tmo)) {
810 /* timeout any expired skbs over 100 ms */
811 dev_dbg(cpts->dev,
812 "expiring tx timestamp mtype_seqid %08x\n",
813 mtype_seqid);
814 __skb_unlink(skb, &txq_list);
815 dev_consume_skb_any(skb);
816 }
817 }
818
819 spin_lock_irqsave(&cpts->txq.lock, flags);
820 skb_queue_splice(&txq_list, &cpts->txq);
821 spin_unlock_irqrestore(&cpts->txq.lock, flags);
822
823 return found;
824}
825
826static void am65_cpts_find_ts(struct am65_cpts *cpts)
827{
828 struct am65_cpts_event *event;
829 struct list_head *this, *next;
830 LIST_HEAD(events_free);
831 unsigned long flags;
832 LIST_HEAD(events);
833
834 spin_lock_irqsave(&cpts->lock, flags);
835 list_splice_init(&cpts->events, &events);
836 spin_unlock_irqrestore(&cpts->lock, flags);
837
838 list_for_each_safe(this, next, &events) {
839 event = list_entry(this, struct am65_cpts_event, list);
840 if (am65_cpts_match_tx_ts(cpts, event) ||
841 time_after(jiffies, event->tmo)) {
842 list_del_init(&event->list);
843 list_add(&event->list, &events_free);
844 }
845 }
846
847 spin_lock_irqsave(&cpts->lock, flags);
848 list_splice_tail(&events, &cpts->events);
849 list_splice_tail(&events_free, &cpts->pool);
850 spin_unlock_irqrestore(&cpts->lock, flags);
851}
852
853static long am65_cpts_ts_work(struct ptp_clock_info *ptp)
854{
855 struct am65_cpts *cpts = container_of(ptp, struct am65_cpts, ptp_info);
856 unsigned long flags;
857 long delay = -1;
858
859 am65_cpts_find_ts(cpts);
860
861 spin_lock_irqsave(&cpts->txq.lock, flags);
862 if (!skb_queue_empty(&cpts->txq))
863 delay = AM65_CPTS_SKB_TX_WORK_TIMEOUT;
864 spin_unlock_irqrestore(&cpts->txq.lock, flags);
865
866 return delay;
867}
868
f6bd5952
GS
869static int am65_skb_get_mtype_seqid(struct sk_buff *skb, u32 *mtype_seqid)
870{
871 unsigned int ptp_class = ptp_classify_raw(skb);
4bccb5d0
KK
872 struct ptp_header *hdr;
873 u8 msgtype;
874 u16 seqid;
f6bd5952
GS
875
876 if (ptp_class == PTP_CLASS_NONE)
877 return 0;
878
4bccb5d0
KK
879 hdr = ptp_parse_header(skb, ptp_class);
880 if (!hdr)
f6bd5952
GS
881 return 0;
882
4bccb5d0
KK
883 msgtype = ptp_get_msgtype(hdr, ptp_class);
884 seqid = ntohs(hdr->sequence_id);
f6bd5952 885
4bccb5d0 886 *mtype_seqid = (msgtype << AM65_CPTS_EVENT_1_MESSAGE_TYPE_SHIFT) &
f6bd5952 887 AM65_CPTS_EVENT_1_MESSAGE_TYPE_MASK;
4bccb5d0 888 *mtype_seqid |= (seqid & AM65_CPTS_EVENT_1_SEQUENCE_ID_MASK);
f6bd5952
GS
889
890 return 1;
891}
892
c459f606
CV
893static u64 am65_cpts_find_rx_ts(struct am65_cpts *cpts, u32 skb_mtype_seqid)
894{
895 struct list_head *this, *next;
896 struct am65_cpts_event *event;
897 unsigned long flags;
898 u32 mtype_seqid;
899 u64 ns = 0;
900
901 spin_lock_irqsave(&cpts->lock, flags);
902 __am65_cpts_fifo_read(cpts);
903 list_for_each_safe(this, next, &cpts->events) {
904 event = list_entry(this, struct am65_cpts_event, list);
905 if (time_after(jiffies, event->tmo)) {
906 list_move(&event->list, &cpts->pool);
907 continue;
908 }
909
910 mtype_seqid = event->event1 &
911 (AM65_CPTS_EVENT_1_MESSAGE_TYPE_MASK |
912 AM65_CPTS_EVENT_1_SEQUENCE_ID_MASK |
913 AM65_CPTS_EVENT_1_EVENT_TYPE_MASK);
914
915 if (mtype_seqid == skb_mtype_seqid) {
916 ns = event->timestamp;
917 list_move(&event->list, &cpts->pool);
918 break;
919 }
920 }
921 spin_unlock_irqrestore(&cpts->lock, flags);
922
923 return ns;
924}
925
926void am65_cpts_rx_timestamp(struct am65_cpts *cpts, struct sk_buff *skb)
927{
928 struct am65_cpts_skb_cb_data *skb_cb = (struct am65_cpts_skb_cb_data *)skb->cb;
929 struct skb_shared_hwtstamps *ssh;
930 int ret;
931 u64 ns;
932
933 /* am65_cpts_rx_timestamp() is called before eth_type_trans(), so
934 * skb MAC Hdr properties are not configured yet. Hence need to
935 * reset skb MAC header here
936 */
937 skb_reset_mac_header(skb);
938 ret = am65_skb_get_mtype_seqid(skb, &skb_cb->skb_mtype_seqid);
939 if (!ret)
940 return; /* if not PTP class packet */
941
942 skb_cb->skb_mtype_seqid |= (AM65_CPTS_EV_RX << AM65_CPTS_EVENT_1_EVENT_TYPE_SHIFT);
943
944 dev_dbg(cpts->dev, "%s mtype seqid %08x\n", __func__, skb_cb->skb_mtype_seqid);
945
946 ns = am65_cpts_find_rx_ts(cpts, skb_cb->skb_mtype_seqid);
947 if (!ns)
948 return;
949
950 ssh = skb_hwtstamps(skb);
951 memset(ssh, 0, sizeof(*ssh));
952 ssh->hwtstamp = ns_to_ktime(ns);
953}
954EXPORT_SYMBOL_GPL(am65_cpts_rx_timestamp);
955
f6bd5952
GS
956/**
957 * am65_cpts_tx_timestamp - save tx packet for timestamping
958 * @cpts: cpts handle
959 * @skb: packet
960 *
961 * This functions saves tx packet for timestamping if packet can be timestamped.
962 * The future processing is done in from PTP auxiliary worker.
963 */
964void am65_cpts_tx_timestamp(struct am65_cpts *cpts, struct sk_buff *skb)
965{
966 struct am65_cpts_skb_cb_data *skb_cb = (void *)skb->cb;
967
968 if (!(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS))
969 return;
970
971 /* add frame to queue for processing later.
972 * The periodic FIFO check will handle this.
973 */
974 skb_get(skb);
975 /* get the timestamp for timeouts */
976 skb_cb->tmo = jiffies + msecs_to_jiffies(100);
977 skb_queue_tail(&cpts->txq, skb);
978 ptp_schedule_worker(cpts->ptp_clock, 0);
979}
980EXPORT_SYMBOL_GPL(am65_cpts_tx_timestamp);
981
982/**
983 * am65_cpts_prep_tx_timestamp - check and prepare tx packet for timestamping
984 * @cpts: cpts handle
985 * @skb: packet
986 *
987 * This functions should be called from .xmit().
988 * It checks if packet can be timestamped, fills internal cpts data
989 * in skb-cb and marks packet as SKBTX_IN_PROGRESS.
990 */
991void am65_cpts_prep_tx_timestamp(struct am65_cpts *cpts, struct sk_buff *skb)
992{
993 struct am65_cpts_skb_cb_data *skb_cb = (void *)skb->cb;
994 int ret;
995
996 if (!(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP))
997 return;
998
999 ret = am65_skb_get_mtype_seqid(skb, &skb_cb->skb_mtype_seqid);
1000 if (!ret)
1001 return;
1002 skb_cb->skb_mtype_seqid |= (AM65_CPTS_EV_TX <<
1003 AM65_CPTS_EVENT_1_EVENT_TYPE_SHIFT);
1004
1005 skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
1006}
1007EXPORT_SYMBOL_GPL(am65_cpts_prep_tx_timestamp);
1008
1009int am65_cpts_phc_index(struct am65_cpts *cpts)
1010{
1011 return cpts->phc_index;
1012}
1013EXPORT_SYMBOL_GPL(am65_cpts_phc_index);
1014
1015static void cpts_free_clk_mux(void *data)
1016{
1017 struct am65_cpts *cpts = data;
1018
1019 of_clk_del_provider(cpts->clk_mux_np);
1020 clk_hw_unregister_mux(cpts->clk_mux_hw);
1021 of_node_put(cpts->clk_mux_np);
1022}
1023
1024static int cpts_of_mux_clk_setup(struct am65_cpts *cpts,
1025 struct device_node *node)
1026{
1027 unsigned int num_parents;
1028 const char **parent_names;
1029 char *clk_mux_name;
1030 void __iomem *reg;
1031 int ret = -EINVAL;
1032
1033 cpts->clk_mux_np = of_get_child_by_name(node, "refclk-mux");
1034 if (!cpts->clk_mux_np)
1035 return 0;
1036
1037 num_parents = of_clk_get_parent_count(cpts->clk_mux_np);
1038 if (num_parents < 1) {
1039 dev_err(cpts->dev, "mux-clock %pOF must have parents\n",
1040 cpts->clk_mux_np);
1041 goto mux_fail;
1042 }
1043
1044 parent_names = devm_kcalloc(cpts->dev, sizeof(char *), num_parents,
1045 GFP_KERNEL);
1046 if (!parent_names) {
1047 ret = -ENOMEM;
1048 goto mux_fail;
1049 }
1050
1051 of_clk_parent_fill(cpts->clk_mux_np, parent_names, num_parents);
1052
1053 clk_mux_name = devm_kasprintf(cpts->dev, GFP_KERNEL, "%s.%pOFn",
1054 dev_name(cpts->dev), cpts->clk_mux_np);
1055 if (!clk_mux_name) {
1056 ret = -ENOMEM;
1057 goto mux_fail;
1058 }
1059
1060 reg = &cpts->reg->rftclk_sel;
1061 /* dev must be NULL to avoid recursive incrementing
1062 * of module refcnt
1063 */
1064 cpts->clk_mux_hw = clk_hw_register_mux(NULL, clk_mux_name,
1065 parent_names, num_parents,
1066 0, reg, 0, 5, 0, NULL);
1067 if (IS_ERR(cpts->clk_mux_hw)) {
1068 ret = PTR_ERR(cpts->clk_mux_hw);
1069 goto mux_fail;
1070 }
1071
1072 ret = of_clk_add_hw_provider(cpts->clk_mux_np, of_clk_hw_simple_get,
1073 cpts->clk_mux_hw);
1074 if (ret)
1075 goto clk_hw_register;
1076
1077 ret = devm_add_action_or_reset(cpts->dev, cpts_free_clk_mux, cpts);
1078 if (ret)
1079 dev_err(cpts->dev, "failed to add clkmux reset action %d", ret);
1080
1081 return ret;
1082
1083clk_hw_register:
1084 clk_hw_unregister_mux(cpts->clk_mux_hw);
1085mux_fail:
1086 of_node_put(cpts->clk_mux_np);
1087 return ret;
1088}
1089
1090static int am65_cpts_of_parse(struct am65_cpts *cpts, struct device_node *node)
1091{
1092 u32 prop[2];
1093
1094 if (!of_property_read_u32(node, "ti,cpts-ext-ts-inputs", &prop[0]))
1095 cpts->ext_ts_inputs = prop[0];
1096
1097 if (!of_property_read_u32(node, "ti,cpts-periodic-outputs", &prop[0]))
1098 cpts->genf_num = prop[0];
1099
b6d78712
GS
1100 if (!of_property_read_u32_array(node, "ti,pps", prop, 2)) {
1101 cpts->pps_present = true;
1102
1103 if (prop[0] > 7) {
1104 dev_err(cpts->dev, "invalid HWx_TS_PUSH index: %u provided\n", prop[0]);
1105 cpts->pps_present = false;
1106 }
1107 if (prop[1] > 1) {
1108 dev_err(cpts->dev, "invalid GENFy index: %u provided\n", prop[1]);
1109 cpts->pps_present = false;
1110 }
1111 if (cpts->pps_present) {
1112 cpts->pps_hw_ts_idx = prop[0];
1113 cpts->pps_genf_idx = prop[1];
1114 }
1115 }
1116
f6bd5952
GS
1117 return cpts_of_mux_clk_setup(cpts, node);
1118}
1119
4ad8766c 1120void am65_cpts_release(struct am65_cpts *cpts)
f6bd5952 1121{
f6bd5952
GS
1122 ptp_clock_unregister(cpts->ptp_clock);
1123 am65_cpts_disable(cpts);
1124 clk_disable_unprepare(cpts->refclk);
1125}
4ad8766c 1126EXPORT_SYMBOL_GPL(am65_cpts_release);
f6bd5952
GS
1127
1128struct am65_cpts *am65_cpts_create(struct device *dev, void __iomem *regs,
1129 struct device_node *node)
1130{
1131 struct am65_cpts *cpts;
1132 int ret, i;
1133
1134 cpts = devm_kzalloc(dev, sizeof(*cpts), GFP_KERNEL);
1135 if (!cpts)
1136 return ERR_PTR(-ENOMEM);
1137
1138 cpts->dev = dev;
1139 cpts->reg = (struct am65_cpts_regs __iomem *)regs;
1140
1141 cpts->irq = of_irq_get_byname(node, "cpts");
1142 if (cpts->irq <= 0) {
1143 ret = cpts->irq ?: -ENXIO;
e2baa126 1144 dev_err_probe(dev, ret, "Failed to get IRQ number\n");
f6bd5952
GS
1145 return ERR_PTR(ret);
1146 }
1147
1148 ret = am65_cpts_of_parse(cpts, node);
1149 if (ret)
1150 return ERR_PTR(ret);
1151
1152 mutex_init(&cpts->ptp_clk_lock);
1153 INIT_LIST_HEAD(&cpts->events);
1154 INIT_LIST_HEAD(&cpts->pool);
1155 spin_lock_init(&cpts->lock);
1156 skb_queue_head_init(&cpts->txq);
1157
1158 for (i = 0; i < AM65_CPTS_MAX_EVENTS; i++)
1159 list_add(&cpts->pool_data[i].list, &cpts->pool);
1160
1161 cpts->refclk = devm_get_clk_from_child(dev, node, "cpts");
1162 if (IS_ERR(cpts->refclk)) {
1163 ret = PTR_ERR(cpts->refclk);
e2baa126 1164 dev_err_probe(dev, ret, "Failed to get refclk\n");
f6bd5952
GS
1165 return ERR_PTR(ret);
1166 }
1167
1168 ret = clk_prepare_enable(cpts->refclk);
1169 if (ret) {
1170 dev_err(dev, "Failed to enable refclk %d\n", ret);
1171 return ERR_PTR(ret);
1172 }
1173
1174 cpts->refclk_freq = clk_get_rate(cpts->refclk);
1175
1176 am65_ptp_info.max_adj = cpts->refclk_freq / AM65_CPTS_MIN_PPM;
1177 cpts->ptp_info = am65_ptp_info;
1178
1179 if (cpts->ext_ts_inputs)
1180 cpts->ptp_info.n_ext_ts = cpts->ext_ts_inputs;
1181 if (cpts->genf_num)
1182 cpts->ptp_info.n_per_out = cpts->genf_num;
b6d78712
GS
1183 if (cpts->pps_present)
1184 cpts->ptp_info.pps = 1;
f6bd5952
GS
1185
1186 am65_cpts_set_add_val(cpts);
1187
4d4dce31
GS
1188 am65_cpts_write32(cpts, AM65_CPTS_CONTROL_EN |
1189 AM65_CPTS_CONTROL_64MODE |
1190 AM65_CPTS_CONTROL_TX_GENF_CLR_EN,
f6bd5952
GS
1191 control);
1192 am65_cpts_write32(cpts, AM65_CPTS_INT_ENABLE_TS_PEND_EN, int_enable);
1193
1194 /* set time to the current system time */
1195 am65_cpts_settime(cpts, ktime_to_ns(ktime_get_real()));
1196
1197 cpts->ptp_clock = ptp_clock_register(&cpts->ptp_info, cpts->dev);
1198 if (IS_ERR_OR_NULL(cpts->ptp_clock)) {
1199 dev_err(dev, "Failed to register ptp clk %ld\n",
1200 PTR_ERR(cpts->ptp_clock));
81e329e9 1201 ret = cpts->ptp_clock ? PTR_ERR(cpts->ptp_clock) : -ENODEV;
f6bd5952
GS
1202 goto refclk_disable;
1203 }
1204 cpts->phc_index = ptp_clock_index(cpts->ptp_clock);
1205
f6bd5952
GS
1206 ret = devm_request_threaded_irq(dev, cpts->irq, NULL,
1207 am65_cpts_interrupt,
1208 IRQF_ONESHOT, dev_name(dev), cpts);
1209 if (ret < 0) {
1210 dev_err(cpts->dev, "error attaching irq %d\n", ret);
4ad8766c 1211 goto reset_ptpclk;
f6bd5952
GS
1212 }
1213
b6d78712 1214 dev_info(dev, "CPTS ver 0x%08x, freq:%u, add_val:%u pps:%d\n",
f6bd5952 1215 am65_cpts_read32(cpts, idver),
b6d78712 1216 cpts->refclk_freq, cpts->ts_add_val, cpts->pps_present);
f6bd5952
GS
1217
1218 return cpts;
1219
4ad8766c
SV
1220reset_ptpclk:
1221 am65_cpts_release(cpts);
f6bd5952
GS
1222refclk_disable:
1223 clk_disable_unprepare(cpts->refclk);
1224 return ERR_PTR(ret);
1225}
1226EXPORT_SYMBOL_GPL(am65_cpts_create);
1227
cef122d4
RQ
1228void am65_cpts_suspend(struct am65_cpts *cpts)
1229{
1230 /* save state and disable CPTS */
1231 cpts->sr_control = am65_cpts_read32(cpts, control);
1232 cpts->sr_int_enable = am65_cpts_read32(cpts, int_enable);
1233 cpts->sr_rftclk_sel = am65_cpts_read32(cpts, rftclk_sel);
1234 cpts->sr_ts_ppm_hi = am65_cpts_read32(cpts, ts_ppm_hi);
1235 cpts->sr_ts_ppm_low = am65_cpts_read32(cpts, ts_ppm_low);
1236 cpts->sr_cpts_ns = am65_cpts_gettime(cpts, NULL);
1237 cpts->sr_ktime_ns = ktime_to_ns(ktime_get_real());
1238 am65_cpts_disable(cpts);
1239 clk_disable(cpts->refclk);
1240
1241 /* Save GENF state */
1242 memcpy_fromio(&cpts->sr_genf, &cpts->reg->genf, sizeof(cpts->sr_genf));
1243
1244 /* Save ESTF state */
1245 memcpy_fromio(&cpts->sr_estf, &cpts->reg->estf, sizeof(cpts->sr_estf));
1246}
1247EXPORT_SYMBOL_GPL(am65_cpts_suspend);
1248
1249void am65_cpts_resume(struct am65_cpts *cpts)
1250{
1251 int i;
1252 s64 ktime_ns;
1253
1254 /* restore state and enable CPTS */
1255 clk_enable(cpts->refclk);
1256 am65_cpts_write32(cpts, cpts->sr_rftclk_sel, rftclk_sel);
1257 am65_cpts_set_add_val(cpts);
1258 am65_cpts_write32(cpts, cpts->sr_control, control);
1259 am65_cpts_write32(cpts, cpts->sr_int_enable, int_enable);
1260
1261 /* Restore time to saved CPTS time + time in suspend/resume */
1262 ktime_ns = ktime_to_ns(ktime_get_real());
1263 ktime_ns -= cpts->sr_ktime_ns;
1264 am65_cpts_settime(cpts, cpts->sr_cpts_ns + ktime_ns);
1265
1266 /* Restore compensation (PPM) */
1267 am65_cpts_write32(cpts, cpts->sr_ts_ppm_hi, ts_ppm_hi);
1268 am65_cpts_write32(cpts, cpts->sr_ts_ppm_low, ts_ppm_low);
1269
1270 /* Restore GENF state */
1271 for (i = 0; i < AM65_CPTS_GENF_MAX_NUM; i++) {
1272 am65_cpts_write32(cpts, 0, genf[i].length); /* TRM sequence */
1273 am65_cpts_write32(cpts, cpts->sr_genf[i].comp_hi, genf[i].comp_hi);
1274 am65_cpts_write32(cpts, cpts->sr_genf[i].comp_lo, genf[i].comp_lo);
1275 am65_cpts_write32(cpts, cpts->sr_genf[i].length, genf[i].length);
1276 am65_cpts_write32(cpts, cpts->sr_genf[i].control, genf[i].control);
1277 am65_cpts_write32(cpts, cpts->sr_genf[i].ppm_hi, genf[i].ppm_hi);
1278 am65_cpts_write32(cpts, cpts->sr_genf[i].ppm_low, genf[i].ppm_low);
1279 }
1280
1281 /* Restore ESTTF state */
1282 for (i = 0; i < AM65_CPTS_ESTF_MAX_NUM; i++) {
1283 am65_cpts_write32(cpts, 0, estf[i].length); /* TRM sequence */
1284 am65_cpts_write32(cpts, cpts->sr_estf[i].comp_hi, estf[i].comp_hi);
1285 am65_cpts_write32(cpts, cpts->sr_estf[i].comp_lo, estf[i].comp_lo);
1286 am65_cpts_write32(cpts, cpts->sr_estf[i].length, estf[i].length);
1287 am65_cpts_write32(cpts, cpts->sr_estf[i].control, estf[i].control);
1288 am65_cpts_write32(cpts, cpts->sr_estf[i].ppm_hi, estf[i].ppm_hi);
1289 am65_cpts_write32(cpts, cpts->sr_estf[i].ppm_low, estf[i].ppm_low);
1290 }
1291}
1292EXPORT_SYMBOL_GPL(am65_cpts_resume);
1293
f6bd5952
GS
1294static int am65_cpts_probe(struct platform_device *pdev)
1295{
1296 struct device_node *node = pdev->dev.of_node;
1297 struct device *dev = &pdev->dev;
1298 struct am65_cpts *cpts;
f6bd5952
GS
1299 void __iomem *base;
1300
e77e2cf4 1301 base = devm_platform_ioremap_resource_byname(pdev, "cpts");
f6bd5952
GS
1302 if (IS_ERR(base))
1303 return PTR_ERR(base);
1304
1305 cpts = am65_cpts_create(dev, base, node);
bbae62e3 1306 return PTR_ERR_OR_ZERO(cpts);
f6bd5952
GS
1307}
1308
1309static const struct of_device_id am65_cpts_of_match[] = {
1310 { .compatible = "ti,am65-cpts", },
1311 { .compatible = "ti,j721e-cpts", },
1312 {},
1313};
1314MODULE_DEVICE_TABLE(of, am65_cpts_of_match);
1315
1316static struct platform_driver am65_cpts_driver = {
1317 .probe = am65_cpts_probe,
1318 .driver = {
1319 .name = "am65-cpts",
1320 .of_match_table = am65_cpts_of_match,
1321 },
1322};
1323module_platform_driver(am65_cpts_driver);
1324
1325MODULE_LICENSE("GPL v2");
1326MODULE_AUTHOR("Grygorii Strashko <grygorii.strashko@ti.com>");
1327MODULE_DESCRIPTION("TI K3 AM65 CPTS driver");