1
2
3
4#include "ice_common.h"
5#include "ice_ptp_hw.h"
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49u8 ice_get_ptp_src_clock_index(struct ice_hw *hw)
50{
51 return hw->func_caps.ts_func_info.tmr_index_assoc;
52}
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68static int ice_read_phy_reg_e810(struct ice_hw *hw, u32 addr, u32 *val)
69{
70 struct ice_sbq_msg_input msg = {0};
71 int status;
72
73 msg.msg_addr_low = lower_16_bits(addr);
74 msg.msg_addr_high = upper_16_bits(addr);
75 msg.opcode = ice_sbq_msg_rd;
76 msg.dest_dev = rmn_0;
77
78 status = ice_sbq_rw_reg(hw, &msg);
79 if (status) {
80 ice_debug(hw, ICE_DBG_PTP, "Failed to send message to PHY, status %d\n",
81 status);
82 return status;
83 }
84
85 *val = msg.data;
86
87 return 0;
88}
89
90
91
92
93
94
95
96
97
98static int ice_write_phy_reg_e810(struct ice_hw *hw, u32 addr, u32 val)
99{
100 struct ice_sbq_msg_input msg = {0};
101 int status;
102
103 msg.msg_addr_low = lower_16_bits(addr);
104 msg.msg_addr_high = upper_16_bits(addr);
105 msg.opcode = ice_sbq_msg_wr;
106 msg.dest_dev = rmn_0;
107 msg.data = val;
108
109 status = ice_sbq_rw_reg(hw, &msg);
110 if (status) {
111 ice_debug(hw, ICE_DBG_PTP, "Failed to send message to PHY, status %d\n",
112 status);
113 return status;
114 }
115
116 return 0;
117}
118
119
120
121
122
123
124
125
126
127
128
129static int
130ice_read_phy_tstamp_e810(struct ice_hw *hw, u8 lport, u8 idx, u64 *tstamp)
131{
132 u32 lo_addr, hi_addr, lo, hi;
133 int status;
134
135 lo_addr = TS_EXT(LOW_TX_MEMORY_BANK_START, lport, idx);
136 hi_addr = TS_EXT(HIGH_TX_MEMORY_BANK_START, lport, idx);
137
138 status = ice_read_phy_reg_e810(hw, lo_addr, &lo);
139 if (status) {
140 ice_debug(hw, ICE_DBG_PTP, "Failed to read low PTP timestamp register, status %d\n",
141 status);
142 return status;
143 }
144
145 status = ice_read_phy_reg_e810(hw, hi_addr, &hi);
146 if (status) {
147 ice_debug(hw, ICE_DBG_PTP, "Failed to read high PTP timestamp register, status %d\n",
148 status);
149 return status;
150 }
151
152
153
154
155 *tstamp = ((u64)hi) << TS_HIGH_S | ((u64)lo & TS_LOW_M);
156
157 return 0;
158}
159
160
161
162
163
164
165
166
167
168
169static int ice_clear_phy_tstamp_e810(struct ice_hw *hw, u8 lport, u8 idx)
170{
171 u32 lo_addr, hi_addr;
172 int status;
173
174 lo_addr = TS_EXT(LOW_TX_MEMORY_BANK_START, lport, idx);
175 hi_addr = TS_EXT(HIGH_TX_MEMORY_BANK_START, lport, idx);
176
177 status = ice_write_phy_reg_e810(hw, lo_addr, 0);
178 if (status) {
179 ice_debug(hw, ICE_DBG_PTP, "Failed to clear low PTP timestamp register, status %d\n",
180 status);
181 return status;
182 }
183
184 status = ice_write_phy_reg_e810(hw, hi_addr, 0);
185 if (status) {
186 ice_debug(hw, ICE_DBG_PTP, "Failed to clear high PTP timestamp register, status %d\n",
187 status);
188 return status;
189 }
190
191 return 0;
192}
193
194
195
196
197
198
199
200
201int ice_ptp_init_phy_e810(struct ice_hw *hw)
202{
203 int status;
204 u8 tmr_idx;
205
206 tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
207 status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_ENA(tmr_idx),
208 GLTSYN_ENA_TSYN_ENA_M);
209 if (status)
210 ice_debug(hw, ICE_DBG_PTP, "PTP failed in ena_phy_time_syn %d\n",
211 status);
212
213 return status;
214}
215
216
217
218
219
220
221
222
223
224
225
226
227
228static int ice_ptp_prep_phy_time_e810(struct ice_hw *hw, u32 time)
229{
230 int status;
231 u8 tmr_idx;
232
233 tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
234 status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHTIME_0(tmr_idx), 0);
235 if (status) {
236 ice_debug(hw, ICE_DBG_PTP, "Failed to write SHTIME_0, status %d\n",
237 status);
238 return status;
239 }
240
241 status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHTIME_L(tmr_idx), time);
242 if (status) {
243 ice_debug(hw, ICE_DBG_PTP, "Failed to write SHTIME_L, status %d\n",
244 status);
245 return status;
246 }
247
248 return 0;
249}
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264static int ice_ptp_prep_phy_adj_e810(struct ice_hw *hw, s32 adj)
265{
266 int status;
267 u8 tmr_idx;
268
269 tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
270
271
272
273
274 status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHADJ_L(tmr_idx), 0);
275 if (status) {
276 ice_debug(hw, ICE_DBG_PTP, "Failed to write adj to PHY SHADJ_L, status %d\n",
277 status);
278 return status;
279 }
280
281 status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHADJ_H(tmr_idx), adj);
282 if (status) {
283 ice_debug(hw, ICE_DBG_PTP, "Failed to write adj to PHY SHADJ_H, status %d\n",
284 status);
285 return status;
286 }
287
288 return 0;
289}
290
291
292
293
294
295
296
297
298
299
300static int ice_ptp_prep_phy_incval_e810(struct ice_hw *hw, u64 incval)
301{
302 u32 high, low;
303 int status;
304 u8 tmr_idx;
305
306 tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
307 low = lower_32_bits(incval);
308 high = upper_32_bits(incval);
309
310 status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHADJ_L(tmr_idx), low);
311 if (status) {
312 ice_debug(hw, ICE_DBG_PTP, "Failed to write incval to PHY SHADJ_L, status %d\n",
313 status);
314 return status;
315 }
316
317 status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHADJ_H(tmr_idx), high);
318 if (status) {
319 ice_debug(hw, ICE_DBG_PTP, "Failed to write incval PHY SHADJ_H, status %d\n",
320 status);
321 return status;
322 }
323
324 return 0;
325}
326
327
328
329
330
331
332
333
334
335static int ice_ptp_port_cmd_e810(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd)
336{
337 u32 cmd_val, val;
338 int status;
339
340 switch (cmd) {
341 case INIT_TIME:
342 cmd_val = GLTSYN_CMD_INIT_TIME;
343 break;
344 case INIT_INCVAL:
345 cmd_val = GLTSYN_CMD_INIT_INCVAL;
346 break;
347 case ADJ_TIME:
348 cmd_val = GLTSYN_CMD_ADJ_TIME;
349 break;
350 case READ_TIME:
351 cmd_val = GLTSYN_CMD_READ_TIME;
352 break;
353 case ADJ_TIME_AT_TIME:
354 cmd_val = GLTSYN_CMD_ADJ_INIT_TIME;
355 break;
356 }
357
358
359 status = ice_read_phy_reg_e810(hw, ETH_GLTSYN_CMD, &val);
360 if (status) {
361 ice_debug(hw, ICE_DBG_PTP, "Failed to read GLTSYN_CMD, status %d\n", status);
362 return status;
363 }
364
365
366 val &= ~TS_CMD_MASK_E810;
367 val |= cmd_val;
368
369 status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_CMD, val);
370 if (status) {
371 ice_debug(hw, ICE_DBG_PTP, "Failed to write back GLTSYN_CMD, status %d\n", status);
372 return status;
373 }
374
375 return 0;
376}
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403bool ice_ptp_lock(struct ice_hw *hw)
404{
405 u32 hw_lock;
406 int i;
407
408#define MAX_TRIES 5
409
410 for (i = 0; i < MAX_TRIES; i++) {
411 hw_lock = rd32(hw, PFTSYN_SEM + (PFTSYN_SEM_BYTES * hw->pf_id));
412 hw_lock = hw_lock & PFTSYN_SEM_BUSY_M;
413 if (!hw_lock)
414 break;
415
416
417 usleep_range(10000, 20000);
418 }
419
420 return !hw_lock;
421}
422
423
424
425
426
427
428
429
430void ice_ptp_unlock(struct ice_hw *hw)
431{
432 wr32(hw, PFTSYN_SEM + (PFTSYN_SEM_BYTES * hw->pf_id), 0);
433}
434
435
436
437
438
439
440
441
442static void ice_ptp_src_cmd(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd)
443{
444 u32 cmd_val;
445 u8 tmr_idx;
446
447 tmr_idx = ice_get_ptp_src_clock_index(hw);
448 cmd_val = tmr_idx << SEL_CPK_SRC;
449
450 switch (cmd) {
451 case INIT_TIME:
452 cmd_val |= GLTSYN_CMD_INIT_TIME;
453 break;
454 case INIT_INCVAL:
455 cmd_val |= GLTSYN_CMD_INIT_INCVAL;
456 break;
457 case ADJ_TIME:
458 cmd_val |= GLTSYN_CMD_ADJ_TIME;
459 break;
460 case ADJ_TIME_AT_TIME:
461 cmd_val |= GLTSYN_CMD_ADJ_INIT_TIME;
462 break;
463 case READ_TIME:
464 cmd_val |= GLTSYN_CMD_READ_TIME;
465 break;
466 }
467
468 wr32(hw, GLTSYN_CMD, cmd_val);
469}
470
471
472
473
474
475
476
477
478
479
480
481static int ice_ptp_tmr_cmd(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd)
482{
483 int status;
484
485
486 ice_ptp_src_cmd(hw, cmd);
487
488
489 status = ice_ptp_port_cmd_e810(hw, cmd);
490 if (status) {
491 ice_debug(hw, ICE_DBG_PTP, "Failed to prepare PHY ports for timer command %u, status %d\n",
492 cmd, status);
493 return status;
494 }
495
496
497
498
499 wr32(hw, GLTSYN_CMD_SYNC, SYNC_EXEC_CMD);
500
501 return 0;
502}
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517int ice_ptp_init_time(struct ice_hw *hw, u64 time)
518{
519 int status;
520 u8 tmr_idx;
521
522 tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
523
524
525 wr32(hw, GLTSYN_SHTIME_L(tmr_idx), lower_32_bits(time));
526 wr32(hw, GLTSYN_SHTIME_H(tmr_idx), upper_32_bits(time));
527 wr32(hw, GLTSYN_SHTIME_0(tmr_idx), 0);
528
529
530
531 status = ice_ptp_prep_phy_time_e810(hw, time & 0xFFFFFFFF);
532 if (status)
533 return status;
534
535 return ice_ptp_tmr_cmd(hw, INIT_TIME);
536}
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552int ice_ptp_write_incval(struct ice_hw *hw, u64 incval)
553{
554 int status;
555 u8 tmr_idx;
556
557 tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
558
559
560 wr32(hw, GLTSYN_SHADJ_L(tmr_idx), lower_32_bits(incval));
561 wr32(hw, GLTSYN_SHADJ_H(tmr_idx), upper_32_bits(incval));
562
563 status = ice_ptp_prep_phy_incval_e810(hw, incval);
564 if (status)
565 return status;
566
567 return ice_ptp_tmr_cmd(hw, INIT_INCVAL);
568}
569
570
571
572
573
574
575
576
577int ice_ptp_write_incval_locked(struct ice_hw *hw, u64 incval)
578{
579 int status;
580
581 if (!ice_ptp_lock(hw))
582 return -EBUSY;
583
584 status = ice_ptp_write_incval(hw, incval);
585
586 ice_ptp_unlock(hw);
587
588 return status;
589}
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604int ice_ptp_adj_clock(struct ice_hw *hw, s32 adj)
605{
606 int status;
607 u8 tmr_idx;
608
609 tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
610
611
612
613
614
615
616 wr32(hw, GLTSYN_SHADJ_L(tmr_idx), 0);
617 wr32(hw, GLTSYN_SHADJ_H(tmr_idx), adj);
618
619 status = ice_ptp_prep_phy_adj_e810(hw, adj);
620 if (status)
621 return status;
622
623 return ice_ptp_tmr_cmd(hw, ADJ_TIME);
624}
625
626
627
628
629
630
631
632
633
634
635int ice_read_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx, u64 *tstamp)
636{
637 return ice_read_phy_tstamp_e810(hw, block, idx, tstamp);
638}
639
640
641
642
643
644
645
646
647
648int ice_clear_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx)
649{
650 return ice_clear_phy_tstamp_e810(hw, block, idx);
651}
652