1
2
3
4
5#include "ice_type.h"
6#include "ice_common.h"
7#include "ice_ptp_hw.h"
8#include "ice_ptp_consts.h"
9#include "ice_cgu_regs.h"
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80u8 ice_get_ptp_src_clock_index(struct ice_hw *hw)
81{
82 return hw->func_caps.ts_func_info.tmr_index_assoc;
83}
84
85
86
87
88
89
90
91u64 ice_ptp_read_src_incval(struct ice_hw *hw)
92{
93 u32 lo, hi;
94 u8 tmr_idx;
95
96 tmr_idx = ice_get_ptp_src_clock_index(hw);
97
98 lo = rd32(hw, GLTSYN_INCVAL_L(tmr_idx));
99 hi = rd32(hw, GLTSYN_INCVAL_H(tmr_idx));
100
101 return ((u64)(hi & INCVAL_HIGH_M) << 32) | lo;
102}
103
104
105
106
107
108
109
110
111
112static void ice_ptp_exec_tmr_cmd(struct ice_hw *hw)
113{
114 wr32(hw, GLTSYN_CMD_SYNC, SYNC_EXEC_CMD);
115 ice_flush(hw);
116}
117
118
119
120
121
122
123
124
125
126
127
128
129static void
130ice_fill_phy_msg_e822(struct ice_sbq_msg_input *msg, u8 port, u16 offset)
131{
132 int phy_port, phy, quadtype;
133
134 phy_port = port % ICE_PORTS_PER_PHY;
135 phy = port / ICE_PORTS_PER_PHY;
136 quadtype = (port / ICE_PORTS_PER_QUAD) % ICE_NUM_QUAD_TYPE;
137
138 if (quadtype == 0) {
139 msg->msg_addr_low = P_Q0_L(P_0_BASE + offset, phy_port);
140 msg->msg_addr_high = P_Q0_H(P_0_BASE + offset, phy_port);
141 } else {
142 msg->msg_addr_low = P_Q1_L(P_4_BASE + offset, phy_port);
143 msg->msg_addr_high = P_Q1_H(P_4_BASE + offset, phy_port);
144 }
145
146 if (phy == 0)
147 msg->dest_dev = rmn_0;
148 else if (phy == 1)
149 msg->dest_dev = rmn_1;
150 else
151 msg->dest_dev = rmn_2;
152}
153
154
155
156
157
158
159
160
161
162
163static bool ice_is_64b_phy_reg_e822(u16 low_addr, u16 *high_addr)
164{
165 switch (low_addr) {
166 case P_REG_PAR_PCS_TX_OFFSET_L:
167 *high_addr = P_REG_PAR_PCS_TX_OFFSET_U;
168 return true;
169 case P_REG_PAR_PCS_RX_OFFSET_L:
170 *high_addr = P_REG_PAR_PCS_RX_OFFSET_U;
171 return true;
172 case P_REG_PAR_TX_TIME_L:
173 *high_addr = P_REG_PAR_TX_TIME_U;
174 return true;
175 case P_REG_PAR_RX_TIME_L:
176 *high_addr = P_REG_PAR_RX_TIME_U;
177 return true;
178 case P_REG_TOTAL_TX_OFFSET_L:
179 *high_addr = P_REG_TOTAL_TX_OFFSET_U;
180 return true;
181 case P_REG_TOTAL_RX_OFFSET_L:
182 *high_addr = P_REG_TOTAL_RX_OFFSET_U;
183 return true;
184 case P_REG_UIX66_10G_40G_L:
185 *high_addr = P_REG_UIX66_10G_40G_U;
186 return true;
187 case P_REG_UIX66_25G_100G_L:
188 *high_addr = P_REG_UIX66_25G_100G_U;
189 return true;
190 case P_REG_TX_CAPTURE_L:
191 *high_addr = P_REG_TX_CAPTURE_U;
192 return true;
193 case P_REG_RX_CAPTURE_L:
194 *high_addr = P_REG_RX_CAPTURE_U;
195 return true;
196 case P_REG_TX_TIMER_INC_PRE_L:
197 *high_addr = P_REG_TX_TIMER_INC_PRE_U;
198 return true;
199 case P_REG_RX_TIMER_INC_PRE_L:
200 *high_addr = P_REG_RX_TIMER_INC_PRE_U;
201 return true;
202 default:
203 return false;
204 }
205}
206
207
208
209
210
211
212
213
214
215
216
217static bool ice_is_40b_phy_reg_e822(u16 low_addr, u16 *high_addr)
218{
219 switch (low_addr) {
220 case P_REG_TIMETUS_L:
221 *high_addr = P_REG_TIMETUS_U;
222 return true;
223 case P_REG_PAR_RX_TUS_L:
224 *high_addr = P_REG_PAR_RX_TUS_U;
225 return true;
226 case P_REG_PAR_TX_TUS_L:
227 *high_addr = P_REG_PAR_TX_TUS_U;
228 return true;
229 case P_REG_PCS_RX_TUS_L:
230 *high_addr = P_REG_PCS_RX_TUS_U;
231 return true;
232 case P_REG_PCS_TX_TUS_L:
233 *high_addr = P_REG_PCS_TX_TUS_U;
234 return true;
235 case P_REG_DESK_PAR_RX_TUS_L:
236 *high_addr = P_REG_DESK_PAR_RX_TUS_U;
237 return true;
238 case P_REG_DESK_PAR_TX_TUS_L:
239 *high_addr = P_REG_DESK_PAR_TX_TUS_U;
240 return true;
241 case P_REG_DESK_PCS_RX_TUS_L:
242 *high_addr = P_REG_DESK_PCS_RX_TUS_U;
243 return true;
244 case P_REG_DESK_PCS_TX_TUS_L:
245 *high_addr = P_REG_DESK_PCS_TX_TUS_U;
246 return true;
247 default:
248 return false;
249 }
250}
251
252
253
254
255
256
257
258
259
260
261
262static enum ice_status
263ice_read_phy_reg_e822_lp(struct ice_hw *hw, u8 port, u16 offset, u32 *val,
264 bool lock_sbq)
265{
266 struct ice_sbq_msg_input msg = {0};
267 enum ice_status status;
268
269 ice_fill_phy_msg_e822(&msg, port, offset);
270 msg.opcode = ice_sbq_msg_rd;
271
272 status = ice_sbq_rw_reg_lp(hw, &msg, lock_sbq);
273 if (status) {
274 ice_debug(hw, ICE_DBG_PTP, "Failed to send message to phy, status %d\n",
275 status);
276 return status;
277 }
278
279 *val = msg.data;
280
281 return ICE_SUCCESS;
282}
283
284enum ice_status
285ice_read_phy_reg_e822(struct ice_hw *hw, u8 port, u16 offset, u32 *val)
286{
287 return ice_read_phy_reg_e822_lp(hw, port, offset, val, true);
288}
289
290
291
292
293
294
295
296
297
298
299
300
301
302static enum ice_status
303ice_read_40b_phy_reg_e822(struct ice_hw *hw, u8 port, u16 low_addr, u64 *val)
304{
305 enum ice_status status;
306 u32 low, high;
307 u16 high_addr;
308
309
310
311
312 if (!ice_is_40b_phy_reg_e822(low_addr, &high_addr)) {
313 ice_debug(hw, ICE_DBG_PTP, "Invalid 64b register addr 0x%08x\n",
314 low_addr);
315 return ICE_ERR_PARAM;
316 }
317
318 status = ice_read_phy_reg_e822(hw, port, low_addr, &low);
319 if (status) {
320 ice_debug(hw, ICE_DBG_PTP, "Failed to read from low register 0x%08x\n, status %d",
321 low_addr, status);
322 return status;
323 }
324
325 status = ice_read_phy_reg_e822(hw, port, high_addr, &high);
326 if (status) {
327 ice_debug(hw, ICE_DBG_PTP, "Failed to read from high register 0x%08x\n, status %d",
328 high_addr, status);
329 return status;
330 }
331
332 *val = (u64)high << P_REG_40B_HIGH_S | (low & P_REG_40B_LOW_M);
333
334 return ICE_SUCCESS;
335}
336
337
338
339
340
341
342
343
344
345
346
347
348
349static enum ice_status
350ice_read_64b_phy_reg_e822(struct ice_hw *hw, u8 port, u16 low_addr, u64 *val)
351{
352 enum ice_status status;
353 u32 low, high;
354 u16 high_addr;
355
356
357
358
359 if (!ice_is_64b_phy_reg_e822(low_addr, &high_addr)) {
360 ice_debug(hw, ICE_DBG_PTP, "Invalid 64b register addr 0x%08x\n",
361 low_addr);
362 return ICE_ERR_PARAM;
363 }
364
365 status = ice_read_phy_reg_e822(hw, port, low_addr, &low);
366 if (status) {
367 ice_debug(hw, ICE_DBG_PTP, "Failed to read from low register 0x%08x\n, status %d",
368 low_addr, status);
369 return status;
370 }
371
372 status = ice_read_phy_reg_e822(hw, port, high_addr, &high);
373 if (status) {
374 ice_debug(hw, ICE_DBG_PTP, "Failed to read from high register 0x%08x\n, status %d",
375 high_addr, status);
376 return status;
377 }
378
379 *val = (u64)high << 32 | low;
380
381 return ICE_SUCCESS;
382}
383
384
385
386
387
388
389
390
391
392
393
394static enum ice_status
395ice_write_phy_reg_e822_lp(struct ice_hw *hw, u8 port, u16 offset, u32 val,
396 bool lock_sbq)
397{
398 struct ice_sbq_msg_input msg = {0};
399 enum ice_status status;
400
401 ice_fill_phy_msg_e822(&msg, port, offset);
402 msg.opcode = ice_sbq_msg_wr;
403 msg.data = val;
404
405 status = ice_sbq_rw_reg_lp(hw, &msg, lock_sbq);
406 if (status) {
407 ice_debug(hw, ICE_DBG_PTP, "Failed to send message to phy, status %d\n",
408 status);
409 return status;
410 }
411
412 return ICE_SUCCESS;
413}
414
415enum ice_status
416ice_write_phy_reg_e822(struct ice_hw *hw, u8 port, u16 offset, u32 val)
417{
418 return ice_write_phy_reg_e822_lp(hw, port, offset, val, true);
419}
420
421
422
423
424
425
426
427
428
429
430
431static enum ice_status
432ice_write_40b_phy_reg_e822(struct ice_hw *hw, u8 port, u16 low_addr, u64 val)
433{
434 enum ice_status status;
435 u32 low, high;
436 u16 high_addr;
437
438
439
440
441 if (!ice_is_40b_phy_reg_e822(low_addr, &high_addr)) {
442 ice_debug(hw, ICE_DBG_PTP, "Invalid 40b register addr 0x%08x\n",
443 low_addr);
444 return ICE_ERR_PARAM;
445 }
446
447 low = (u32)(val & P_REG_40B_LOW_M);
448 high = (u32)(val >> P_REG_40B_HIGH_S);
449
450 status = ice_write_phy_reg_e822(hw, port, low_addr, low);
451 if (status) {
452 ice_debug(hw, ICE_DBG_PTP, "Failed to write to low register 0x%08x\n, status %d",
453 low_addr, status);
454 return status;
455 }
456
457 status = ice_write_phy_reg_e822(hw, port, high_addr, high);
458 if (status) {
459 ice_debug(hw, ICE_DBG_PTP, "Failed to write to high register 0x%08x\n, status %d",
460 high_addr, status);
461 return status;
462 }
463
464 return ICE_SUCCESS;
465}
466
467
468
469
470
471
472
473
474
475
476
477
478
479static enum ice_status
480ice_write_64b_phy_reg_e822(struct ice_hw *hw, u8 port, u16 low_addr, u64 val)
481{
482 enum ice_status status;
483 u32 low, high;
484 u16 high_addr;
485
486
487
488
489 if (!ice_is_64b_phy_reg_e822(low_addr, &high_addr)) {
490 ice_debug(hw, ICE_DBG_PTP, "Invalid 64b register addr 0x%08x\n",
491 low_addr);
492 return ICE_ERR_PARAM;
493 }
494
495 low = ICE_LO_DWORD(val);
496 high = ICE_HI_DWORD(val);
497
498 status = ice_write_phy_reg_e822(hw, port, low_addr, low);
499 if (status) {
500 ice_debug(hw, ICE_DBG_PTP, "Failed to write to low register 0x%08x\n, status %d",
501 low_addr, status);
502 return status;
503 }
504
505 status = ice_write_phy_reg_e822(hw, port, high_addr, high);
506 if (status) {
507 ice_debug(hw, ICE_DBG_PTP, "Failed to write to high register 0x%08x\n, status %d",
508 high_addr, status);
509 return status;
510 }
511
512 return ICE_SUCCESS;
513}
514
515
516
517
518
519
520
521
522
523
524static void
525ice_fill_quad_msg_e822(struct ice_sbq_msg_input *msg, u8 quad, u16 offset)
526{
527 u32 addr;
528
529 msg->dest_dev = rmn_0;
530
531 if ((quad % ICE_NUM_QUAD_TYPE) == 0)
532 addr = Q_0_BASE + offset;
533 else
534 addr = Q_1_BASE + offset;
535
536 msg->msg_addr_low = ICE_LO_WORD(addr);
537 msg->msg_addr_high = ICE_HI_WORD(addr);
538}
539
540
541
542
543
544
545
546
547
548
549
550
551static enum ice_status
552ice_read_quad_reg_e822_lp(struct ice_hw *hw, u8 quad, u16 offset, u32 *val,
553 bool lock_sbq)
554{
555 struct ice_sbq_msg_input msg = {0};
556 enum ice_status status;
557
558 if (quad >= ICE_MAX_QUAD)
559 return ICE_ERR_PARAM;
560
561 ice_fill_quad_msg_e822(&msg, quad, offset);
562 msg.opcode = ice_sbq_msg_rd;
563
564 status = ice_sbq_rw_reg_lp(hw, &msg, lock_sbq);
565 if (status) {
566 ice_debug(hw, ICE_DBG_PTP, "Failed to send message to phy, status %d\n",
567 status);
568 return status;
569 }
570
571 *val = msg.data;
572
573 return ICE_SUCCESS;
574}
575
576enum ice_status
577ice_read_quad_reg_e822(struct ice_hw *hw, u8 quad, u16 offset, u32 *val)
578{
579 return ice_read_quad_reg_e822_lp(hw, quad, offset, val, true);
580}
581
582
583
584
585
586
587
588
589
590
591
592
593static enum ice_status
594ice_write_quad_reg_e822_lp(struct ice_hw *hw, u8 quad, u16 offset, u32 val,
595 bool lock_sbq)
596{
597 struct ice_sbq_msg_input msg = {0};
598 enum ice_status status;
599
600 if (quad >= ICE_MAX_QUAD)
601 return ICE_ERR_PARAM;
602
603 ice_fill_quad_msg_e822(&msg, quad, offset);
604 msg.opcode = ice_sbq_msg_wr;
605 msg.data = val;
606
607 status = ice_sbq_rw_reg_lp(hw, &msg, lock_sbq);
608 if (status) {
609 ice_debug(hw, ICE_DBG_PTP, "Failed to send message to phy, status %d\n",
610 status);
611 return status;
612 }
613
614 return ICE_SUCCESS;
615}
616
617enum ice_status
618ice_write_quad_reg_e822(struct ice_hw *hw, u8 quad, u16 offset, u32 val)
619{
620 return ice_write_quad_reg_e822_lp(hw, quad, offset, val, true);
621}
622
623
624
625
626
627
628
629
630
631
632
633
634static enum ice_status
635ice_read_phy_tstamp_e822(struct ice_hw *hw, u8 quad, u8 idx, u64 *tstamp)
636{
637 enum ice_status status;
638 u16 lo_addr, hi_addr;
639 u32 lo, hi;
640
641 lo_addr = (u16)TS_L(Q_REG_TX_MEMORY_BANK_START, idx);
642 hi_addr = (u16)TS_H(Q_REG_TX_MEMORY_BANK_START, idx);
643
644 status = ice_read_quad_reg_e822(hw, quad, lo_addr, &lo);
645 if (status) {
646 ice_debug(hw, ICE_DBG_PTP, "Failed to read low PTP timestamp register, status %d\n",
647 status);
648 return status;
649 }
650
651 status = ice_read_quad_reg_e822(hw, quad, hi_addr, &hi);
652 if (status) {
653 ice_debug(hw, ICE_DBG_PTP, "Failed to read high PTP timestamp register, status %d\n",
654 status);
655 return status;
656 }
657
658
659
660
661
662 *tstamp = ((u64)hi) << TS_PHY_HIGH_S | ((u64)lo & TS_PHY_LOW_M);
663
664 return ICE_SUCCESS;
665}
666
667
668
669
670
671
672
673
674
675
676static enum ice_status
677ice_clear_phy_tstamp_e822(struct ice_hw *hw, u8 quad, u8 idx)
678{
679 enum ice_status status;
680 u16 lo_addr, hi_addr;
681
682 lo_addr = (u16)TS_L(Q_REG_TX_MEMORY_BANK_START, idx);
683 hi_addr = (u16)TS_H(Q_REG_TX_MEMORY_BANK_START, idx);
684
685 status = ice_write_quad_reg_e822(hw, quad, lo_addr, 0);
686 if (status) {
687 ice_debug(hw, ICE_DBG_PTP, "Failed to clear low PTP timestamp register, status %d\n",
688 status);
689 return status;
690 }
691
692 status = ice_write_quad_reg_e822(hw, quad, hi_addr, 0);
693 if (status) {
694 ice_debug(hw, ICE_DBG_PTP, "Failed to clear high PTP timestamp register, status %d\n",
695 status);
696 return status;
697 }
698
699 return ICE_SUCCESS;
700}
701
702
703
704
705
706
707
708
709
710
711static enum ice_status
712ice_read_cgu_reg_e822(struct ice_hw *hw, u16 addr, u32 *val)
713{
714 struct ice_sbq_msg_input cgu_msg;
715 enum ice_status status;
716
717 cgu_msg.opcode = ice_sbq_msg_rd;
718 cgu_msg.dest_dev = cgu;
719 cgu_msg.msg_addr_low = addr;
720 cgu_msg.msg_addr_high = 0x0;
721
722 status = ice_sbq_rw_reg_lp(hw, &cgu_msg, true);
723 if (status) {
724 ice_debug(hw, ICE_DBG_PTP, "Failed to read CGU register 0x%04x, status %d\n",
725 addr, status);
726 return status;
727 }
728
729 *val = cgu_msg.data;
730
731 return status;
732}
733
734
735
736
737
738
739
740
741
742
743static enum ice_status
744ice_write_cgu_reg_e822(struct ice_hw *hw, u16 addr, u32 val)
745{
746 struct ice_sbq_msg_input cgu_msg;
747 enum ice_status status;
748
749 cgu_msg.opcode = ice_sbq_msg_wr;
750 cgu_msg.dest_dev = cgu;
751 cgu_msg.msg_addr_low = addr;
752 cgu_msg.msg_addr_high = 0x0;
753 cgu_msg.data = val;
754
755 status = ice_sbq_rw_reg_lp(hw, &cgu_msg, true);
756 if (status) {
757 ice_debug(hw, ICE_DBG_PTP, "Failed to write CGU register 0x%04x, status %d\n",
758 addr, status);
759 return status;
760 }
761
762 return status;
763}
764
765
766
767
768
769
770
771static const char *ice_clk_freq_str(u8 clk_freq)
772{
773 switch ((enum ice_time_ref_freq)clk_freq) {
774 case ICE_TIME_REF_FREQ_25_000:
775 return "25 MHz";
776 case ICE_TIME_REF_FREQ_122_880:
777 return "122.88 MHz";
778 case ICE_TIME_REF_FREQ_125_000:
779 return "125 MHz";
780 case ICE_TIME_REF_FREQ_153_600:
781 return "153.6 MHz";
782 case ICE_TIME_REF_FREQ_156_250:
783 return "156.25 MHz";
784 case ICE_TIME_REF_FREQ_245_760:
785 return "245.76 MHz";
786 default:
787 return "Unknown";
788 }
789}
790
791
792
793
794
795
796
797static const char *ice_clk_src_str(u8 clk_src)
798{
799 switch ((enum ice_clk_src)clk_src) {
800 case ICE_CLK_SRC_TCX0:
801 return "TCX0";
802 case ICE_CLK_SRC_TIME_REF:
803 return "TIME_REF";
804 default:
805 return "Unknown";
806 }
807}
808
809
810
811
812
813
814
815
816
817
818enum ice_status
819ice_cfg_cgu_pll_e822(struct ice_hw *hw, enum ice_time_ref_freq clk_freq,
820 enum ice_clk_src clk_src)
821{
822 union tspll_ro_bwm_lf bwm_lf;
823 union nac_cgu_dword19 dw19;
824 union nac_cgu_dword22 dw22;
825 union nac_cgu_dword24 dw24;
826 union nac_cgu_dword9 dw9;
827 enum ice_status status;
828
829 if (clk_freq >= NUM_ICE_TIME_REF_FREQ) {
830 ice_warn(hw, "Invalid TIME_REF frequency %u\n", clk_freq);
831 return ICE_ERR_PARAM;
832 }
833
834 if (clk_src >= NUM_ICE_CLK_SRC) {
835 ice_warn(hw, "Invalid clock source %u\n", clk_src);
836 return ICE_ERR_PARAM;
837 }
838
839 if (clk_src == ICE_CLK_SRC_TCX0 &&
840 clk_freq != ICE_TIME_REF_FREQ_25_000) {
841 ice_warn(hw, "TCX0 only supports 25 MHz frequency\n");
842 return ICE_ERR_PARAM;
843 }
844
845 status = ice_read_cgu_reg_e822(hw, NAC_CGU_DWORD9, &dw9.val);
846 if (status)
847 return status;
848
849 status = ice_read_cgu_reg_e822(hw, NAC_CGU_DWORD24, &dw24.val);
850 if (status)
851 return status;
852
853 status = ice_read_cgu_reg_e822(hw, TSPLL_RO_BWM_LF, &bwm_lf.val);
854 if (status)
855 return status;
856
857
858 ice_debug(hw, ICE_DBG_PTP, "Current CGU configuration -- %s, clk_src %s, clk_freq %s, PLL %s\n",
859 dw24.field.ts_pll_enable ? "enabled" : "disabled",
860 ice_clk_src_str(dw24.field.time_ref_sel),
861 ice_clk_freq_str(dw9.field.time_ref_freq_sel),
862 bwm_lf.field.plllock_true_lock_cri ? "locked" : "unlocked");
863
864
865 if (dw24.field.ts_pll_enable) {
866 dw24.field.ts_pll_enable = 0;
867
868 status = ice_write_cgu_reg_e822(hw, NAC_CGU_DWORD24, dw24.val);
869 if (status)
870 return status;
871 }
872
873
874 dw9.field.time_ref_freq_sel = clk_freq;
875 status = ice_write_cgu_reg_e822(hw, NAC_CGU_DWORD9, dw9.val);
876 if (status)
877 return status;
878
879
880 status = ice_read_cgu_reg_e822(hw, NAC_CGU_DWORD19, &dw19.val);
881 if (status)
882 return status;
883
884 dw19.field.tspll_fbdiv_intgr = e822_cgu_params[clk_freq].feedback_div;
885 dw19.field.tspll_ndivratio = 1;
886
887 status = ice_write_cgu_reg_e822(hw, NAC_CGU_DWORD19, dw19.val);
888 if (status)
889 return status;
890
891
892 status = ice_read_cgu_reg_e822(hw, NAC_CGU_DWORD22, &dw22.val);
893 if (status)
894 return status;
895
896 dw22.field.time1588clk_div = e822_cgu_params[clk_freq].post_pll_div;
897 dw22.field.time1588clk_sel_div2 = 0;
898
899 status = ice_write_cgu_reg_e822(hw, NAC_CGU_DWORD22, dw22.val);
900 if (status)
901 return status;
902
903
904 status = ice_read_cgu_reg_e822(hw, NAC_CGU_DWORD24, &dw24.val);
905 if (status)
906 return status;
907
908 dw24.field.ref1588_ck_div = e822_cgu_params[clk_freq].refclk_pre_div;
909 dw24.field.tspll_fbdiv_frac = e822_cgu_params[clk_freq].frac_n_div;
910 dw24.field.time_ref_sel = clk_src;
911
912 status = ice_write_cgu_reg_e822(hw, NAC_CGU_DWORD24, dw24.val);
913 if (status)
914 return status;
915
916
917 dw24.field.ts_pll_enable = 1;
918
919 status = ice_write_cgu_reg_e822(hw, NAC_CGU_DWORD24, dw24.val);
920 if (status)
921 return status;
922
923
924 ice_msec_delay(1, true);
925
926 status = ice_read_cgu_reg_e822(hw, TSPLL_RO_BWM_LF, &bwm_lf.val);
927 if (status)
928 return status;
929
930 if (!bwm_lf.field.plllock_true_lock_cri) {
931 ice_warn(hw, "CGU PLL failed to lock\n");
932 return ICE_ERR_NOT_READY;
933 }
934
935
936 ice_debug(hw, ICE_DBG_PTP, "New CGU configuration -- %s, clk_src %s, clk_freq %s, PLL %s\n",
937 dw24.field.ts_pll_enable ? "enabled" : "disabled",
938 ice_clk_src_str(dw24.field.time_ref_sel),
939 ice_clk_freq_str(dw9.field.time_ref_freq_sel),
940 bwm_lf.field.plllock_true_lock_cri ? "locked" : "unlocked");
941
942
943 return ICE_SUCCESS;
944}
945
946
947
948
949
950
951
952static enum ice_status ice_init_cgu_e822(struct ice_hw *hw)
953{
954 struct ice_ts_func_info *ts_info = &hw->func_caps.ts_func_info;
955 union tspll_cntr_bist_settings cntr_bist;
956 enum ice_status status;
957
958 status = ice_read_cgu_reg_e822(hw, TSPLL_CNTR_BIST_SETTINGS,
959 &cntr_bist.val);
960 if (status)
961 return status;
962
963
964 cntr_bist.field.i_plllock_sel_0 = 0;
965 cntr_bist.field.i_plllock_sel_1 = 0;
966
967 status = ice_write_cgu_reg_e822(hw, TSPLL_CNTR_BIST_SETTINGS,
968 cntr_bist.val);
969 if (status)
970 return status;
971
972
973
974
975 status = ice_cfg_cgu_pll_e822(hw, ts_info->time_ref,
976 (enum ice_clk_src)ts_info->clk_src);
977 if (status)
978 return status;
979
980 return ICE_SUCCESS;
981}
982
983
984
985
986
987
988
989static enum ice_status ice_ptp_init_phc_e822(struct ice_hw *hw)
990{
991 enum ice_status status;
992 u32 regval;
993
994
995#define PF_SB_REM_DEV_CTL_SWITCH_READ BIT(1)
996#define PF_SB_REM_DEV_CTL_PHY0 BIT(2)
997 regval = rd32(hw, PF_SB_REM_DEV_CTL);
998 regval |= (PF_SB_REM_DEV_CTL_SWITCH_READ |
999 PF_SB_REM_DEV_CTL_PHY0);
1000 wr32(hw, PF_SB_REM_DEV_CTL, regval);
1001
1002
1003 status = ice_init_cgu_e822(hw);
1004 if (status)
1005 return status;
1006
1007
1008 return ice_ptp_set_vernier_wl(hw);
1009}
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021static enum ice_status
1022ice_ptp_prep_phy_time_e822(struct ice_hw *hw, u32 time)
1023{
1024 enum ice_status status;
1025 u64 phy_time;
1026 u8 port;
1027
1028
1029
1030
1031 phy_time = (u64)time << 32;
1032
1033 for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
1034
1035
1036 status = ice_write_64b_phy_reg_e822(hw, port,
1037 P_REG_TX_TIMER_INC_PRE_L,
1038 phy_time);
1039 if (status)
1040 goto exit_err;
1041
1042
1043 status = ice_write_64b_phy_reg_e822(hw, port,
1044 P_REG_RX_TIMER_INC_PRE_L,
1045 phy_time);
1046 if (status)
1047 goto exit_err;
1048 }
1049
1050 return ICE_SUCCESS;
1051
1052exit_err:
1053 ice_debug(hw, ICE_DBG_PTP, "Failed to write init time for port %u, status %d\n",
1054 port, status);
1055
1056 return status;
1057}
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076enum ice_status
1077ice_ptp_prep_port_adj_e822(struct ice_hw *hw, u8 port, s64 time,
1078 bool lock_sbq)
1079{
1080 enum ice_status status;
1081 u32 l_time, u_time;
1082
1083 l_time = ICE_LO_DWORD(time);
1084 u_time = ICE_HI_DWORD(time);
1085
1086
1087 status = ice_write_phy_reg_e822_lp(hw, port, P_REG_TX_TIMER_INC_PRE_L,
1088 l_time, lock_sbq);
1089 if (status)
1090 goto exit_err;
1091
1092 status = ice_write_phy_reg_e822_lp(hw, port, P_REG_TX_TIMER_INC_PRE_U,
1093 u_time, lock_sbq);
1094 if (status)
1095 goto exit_err;
1096
1097
1098 status = ice_write_phy_reg_e822_lp(hw, port, P_REG_RX_TIMER_INC_PRE_L,
1099 l_time, lock_sbq);
1100 if (status)
1101 goto exit_err;
1102
1103 status = ice_write_phy_reg_e822_lp(hw, port, P_REG_RX_TIMER_INC_PRE_U,
1104 u_time, lock_sbq);
1105 if (status)
1106 goto exit_err;
1107
1108 return ICE_SUCCESS;
1109
1110exit_err:
1111 ice_debug(hw, ICE_DBG_PTP, "Failed to write time adjust for port %u, status %d\n",
1112 port, status);
1113 return status;
1114}
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127static enum ice_status
1128ice_ptp_prep_phy_adj_e822(struct ice_hw *hw, s32 adj, bool lock_sbq)
1129{
1130 s64 cycles;
1131 u8 port;
1132
1133
1134
1135
1136
1137 if (adj > 0)
1138 cycles = (s64)adj << 32;
1139 else
1140 cycles = -(((s64)-adj) << 32);
1141
1142 for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
1143 enum ice_status status;
1144
1145 status = ice_ptp_prep_port_adj_e822(hw, port, cycles,
1146 lock_sbq);
1147 if (status)
1148 return status;
1149 }
1150
1151 return ICE_SUCCESS;
1152}
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163static enum ice_status
1164ice_ptp_prep_phy_incval_e822(struct ice_hw *hw, u64 incval)
1165{
1166 enum ice_status status;
1167 u8 port;
1168
1169 for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
1170 status = ice_write_40b_phy_reg_e822(hw, port, P_REG_TIMETUS_L,
1171 incval);
1172 if (status)
1173 goto exit_err;
1174 }
1175
1176 return ICE_SUCCESS;
1177
1178exit_err:
1179 ice_debug(hw, ICE_DBG_PTP, "Failed to write incval for port %u, status %d\n",
1180 port, status);
1181
1182 return status;
1183}
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193enum ice_status
1194ice_ptp_read_phy_incval_e822(struct ice_hw *hw, u8 port, u64 *incval)
1195{
1196 enum ice_status status;
1197
1198 status = ice_read_40b_phy_reg_e822(hw, port, P_REG_TIMETUS_L, incval);
1199 if (status) {
1200 ice_debug(hw, ICE_DBG_PTP, "Failed to read TIMETUS_L, status %d\n",
1201 status);
1202 return status;
1203 }
1204
1205 ice_debug(hw, ICE_DBG_PTP, "read INCVAL = 0x%016llx\n",
1206 (unsigned long long)*incval);
1207
1208 return ICE_SUCCESS;
1209}
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224static enum ice_status
1225ice_ptp_prep_phy_adj_target_e822(struct ice_hw *hw, u32 target_time)
1226{
1227 enum ice_status status;
1228 u8 port;
1229
1230 for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
1231
1232
1233
1234 status = ice_write_phy_reg_e822_lp(hw, port,
1235 P_REG_TX_TIMER_CNT_ADJ_L,
1236 0, true);
1237 if (status)
1238 goto exit_err;
1239
1240 status = ice_write_phy_reg_e822_lp(hw, port,
1241 P_REG_TX_TIMER_CNT_ADJ_U,
1242 target_time, true);
1243 if (status)
1244 goto exit_err;
1245
1246
1247
1248 status = ice_write_phy_reg_e822_lp(hw, port,
1249 P_REG_RX_TIMER_CNT_ADJ_L,
1250 0, true);
1251 if (status)
1252 goto exit_err;
1253
1254 status = ice_write_phy_reg_e822_lp(hw, port,
1255 P_REG_RX_TIMER_CNT_ADJ_U,
1256 target_time, true);
1257 if (status)
1258 goto exit_err;
1259 }
1260
1261 return ICE_SUCCESS;
1262
1263exit_err:
1264 ice_debug(hw, ICE_DBG_PTP, "Failed to write target time for port %u, status %d\n",
1265 port, status);
1266
1267 return status;
1268}
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281enum ice_status
1282ice_ptp_read_port_capture(struct ice_hw *hw, u8 port, u64 *tx_ts, u64 *rx_ts)
1283{
1284 enum ice_status status;
1285
1286
1287 status = ice_read_64b_phy_reg_e822(hw, port, P_REG_TX_CAPTURE_L, tx_ts);
1288 if (status) {
1289 ice_debug(hw, ICE_DBG_PTP, "Failed to read REG_TX_CAPTURE, status %d\n",
1290 status);
1291 return status;
1292 }
1293
1294 ice_debug(hw, ICE_DBG_PTP, "tx_init = 0x%016llx\n",
1295 (unsigned long long)*tx_ts);
1296
1297
1298 status = ice_read_64b_phy_reg_e822(hw, port, P_REG_RX_CAPTURE_L, rx_ts);
1299 if (status) {
1300 ice_debug(hw, ICE_DBG_PTP, "Failed to read RX_CAPTURE, status %d\n",
1301 status);
1302 return status;
1303 }
1304
1305 ice_debug(hw, ICE_DBG_PTP, "rx_init = 0x%016llx\n",
1306 (unsigned long long)*rx_ts);
1307
1308 return ICE_SUCCESS;
1309}
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323enum ice_status
1324ice_ptp_one_port_cmd(struct ice_hw *hw, u8 port, enum ice_ptp_tmr_cmd cmd,
1325 bool lock_sbq)
1326{
1327 enum ice_status status;
1328 u32 cmd_val, val;
1329 u8 tmr_idx;
1330
1331 tmr_idx = ice_get_ptp_src_clock_index(hw);
1332 cmd_val = tmr_idx << SEL_PHY_SRC;
1333 switch (cmd) {
1334 case INIT_TIME:
1335 cmd_val |= PHY_CMD_INIT_TIME;
1336 break;
1337 case INIT_INCVAL:
1338 cmd_val |= PHY_CMD_INIT_INCVAL;
1339 break;
1340 case ADJ_TIME:
1341 cmd_val |= PHY_CMD_ADJ_TIME;
1342 break;
1343 case ADJ_TIME_AT_TIME:
1344 cmd_val |= PHY_CMD_ADJ_TIME_AT_TIME;
1345 break;
1346 case READ_TIME:
1347 cmd_val |= PHY_CMD_READ_TIME;
1348 break;
1349 default:
1350 ice_warn(hw, "Unknown timer command %u\n", cmd);
1351 return ICE_ERR_PARAM;
1352 }
1353
1354
1355
1356 status = ice_read_phy_reg_e822_lp(hw, port, P_REG_TX_TMR_CMD, &val,
1357 lock_sbq);
1358 if (status) {
1359 ice_debug(hw, ICE_DBG_PTP, "Failed to read TX_TMR_CMD, status %d\n",
1360 status);
1361 return status;
1362 }
1363
1364
1365 val &= ~TS_CMD_MASK;
1366 val |= cmd_val;
1367
1368 status = ice_write_phy_reg_e822_lp(hw, port, P_REG_TX_TMR_CMD, val,
1369 lock_sbq);
1370 if (status) {
1371 ice_debug(hw, ICE_DBG_PTP, "Failed to write back TX_TMR_CMD, status %d\n",
1372 status);
1373 return status;
1374 }
1375
1376
1377
1378 status = ice_read_phy_reg_e822_lp(hw, port, P_REG_RX_TMR_CMD, &val,
1379 lock_sbq);
1380 if (status) {
1381 ice_debug(hw, ICE_DBG_PTP, "Failed to read RX_TMR_CMD, status %d\n",
1382 status);
1383 return status;
1384 }
1385
1386
1387 val &= ~TS_CMD_MASK;
1388 val |= cmd_val;
1389
1390 status = ice_write_phy_reg_e822_lp(hw, port, P_REG_RX_TMR_CMD, val,
1391 lock_sbq);
1392 if (status) {
1393 ice_debug(hw, ICE_DBG_PTP, "Failed to write back RX_TMR_CMD, status %d\n",
1394 status);
1395 return status;
1396 }
1397
1398 return ICE_SUCCESS;
1399}
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410static enum ice_status
1411ice_ptp_port_cmd_e822(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd,
1412 bool lock_sbq)
1413{
1414 u8 port;
1415
1416 for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
1417 enum ice_status status;
1418
1419 status = ice_ptp_one_port_cmd(hw, port, cmd, lock_sbq);
1420 if (status)
1421 return status;
1422 }
1423
1424 return ICE_SUCCESS;
1425}
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440enum ice_status ice_ptp_set_vernier_wl(struct ice_hw *hw)
1441{
1442 u8 port;
1443
1444 for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
1445 enum ice_status status;
1446
1447 status = ice_write_phy_reg_e822_lp(hw, port, P_REG_WL,
1448 PTP_VERNIER_WL, true);
1449 if (status) {
1450 ice_debug(hw, ICE_DBG_PTP, "Failed to set vernier window length for port %u, status %d\n",
1451 port, status);
1452 return status;
1453 }
1454 }
1455
1456 return ICE_SUCCESS;
1457}
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469enum ice_status
1470ice_phy_get_speed_and_fec_e822(struct ice_hw *hw, u8 port,
1471 enum ice_ptp_link_spd *link_out,
1472 enum ice_ptp_fec_mode *fec_out)
1473{
1474 enum ice_ptp_link_spd link;
1475 enum ice_ptp_fec_mode fec;
1476 enum ice_status status;
1477 u32 serdes;
1478
1479 status = ice_read_phy_reg_e822(hw, port, P_REG_LINK_SPEED, &serdes);
1480 if (status) {
1481 ice_debug(hw, ICE_DBG_PTP, "Failed to read serdes info\n");
1482 return status;
1483 }
1484
1485
1486 fec = (enum ice_ptp_fec_mode)P_REG_LINK_SPEED_FEC_MODE(serdes);
1487
1488 serdes &= P_REG_LINK_SPEED_SERDES_M;
1489
1490
1491 if (fec == ICE_PTP_FEC_MODE_RS_FEC) {
1492 switch (serdes) {
1493 case ICE_PTP_SERDES_25G:
1494 link = ICE_PTP_LNK_SPD_25G_RS;
1495 break;
1496 case ICE_PTP_SERDES_50G:
1497 link = ICE_PTP_LNK_SPD_50G_RS;
1498 break;
1499 case ICE_PTP_SERDES_100G:
1500 link = ICE_PTP_LNK_SPD_100G_RS;
1501 break;
1502 default:
1503 return ICE_ERR_OUT_OF_RANGE;
1504 }
1505 } else {
1506 switch (serdes) {
1507 case ICE_PTP_SERDES_1G:
1508 link = ICE_PTP_LNK_SPD_1G;
1509 break;
1510 case ICE_PTP_SERDES_10G:
1511 link = ICE_PTP_LNK_SPD_10G;
1512 break;
1513 case ICE_PTP_SERDES_25G:
1514 link = ICE_PTP_LNK_SPD_25G;
1515 break;
1516 case ICE_PTP_SERDES_40G:
1517 link = ICE_PTP_LNK_SPD_40G;
1518 break;
1519 case ICE_PTP_SERDES_50G:
1520 link = ICE_PTP_LNK_SPD_50G;
1521 break;
1522 default:
1523 return ICE_ERR_OUT_OF_RANGE;
1524 }
1525 }
1526
1527 if (link_out)
1528 *link_out = link;
1529 if (fec_out)
1530 *fec_out = fec;
1531
1532 return ICE_SUCCESS;
1533}
1534
1535
1536
1537
1538
1539
1540void ice_phy_cfg_lane_e822(struct ice_hw *hw, u8 port)
1541{
1542 enum ice_ptp_link_spd link_spd;
1543 enum ice_status status;
1544 u32 val;
1545 u8 quad;
1546
1547 status = ice_phy_get_speed_and_fec_e822(hw, port, &link_spd, NULL);
1548 if (status) {
1549 ice_debug(hw, ICE_DBG_PTP, "Failed to get PHY link speed, status %d\n",
1550 status);
1551 return;
1552 }
1553
1554 quad = port / ICE_PORTS_PER_QUAD;
1555
1556 status = ice_read_quad_reg_e822(hw, quad, Q_REG_TX_MEM_GBL_CFG, &val);
1557 if (status) {
1558 ice_debug(hw, ICE_DBG_PTP, "Failed to read TX_MEM_GLB_CFG, status %d\n",
1559 status);
1560 return;
1561 }
1562
1563 if (link_spd >= ICE_PTP_LNK_SPD_40G)
1564 val &= ~Q_REG_TX_MEM_GBL_CFG_LANE_TYPE_M;
1565 else
1566 val |= Q_REG_TX_MEM_GBL_CFG_LANE_TYPE_M;
1567
1568 status = ice_write_quad_reg_e822(hw, quad, Q_REG_TX_MEM_GBL_CFG, val);
1569 if (status) {
1570 ice_debug(hw, ICE_DBG_PTP, "Failed to write back TX_MEM_GBL_CFG, status %d\n",
1571 status);
1572 return;
1573 }
1574}
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622static enum ice_status ice_phy_cfg_uix_e822(struct ice_hw *hw, u8 port)
1623{
1624 u64 cur_freq, clk_incval, tu_per_sec, uix;
1625 enum ice_status status;
1626
1627 cur_freq = ice_e822_pll_freq(ice_e822_time_ref(hw));
1628 clk_incval = ice_ptp_read_src_incval(hw);
1629
1630
1631 tu_per_sec = (cur_freq * clk_incval) >> 8;
1632
1633#define LINE_UI_10G_40G 640
1634#define LINE_UI_25G_100G 256
1635
1636
1637 uix = DIV_64BIT(tu_per_sec * LINE_UI_10G_40G, 390625000);
1638
1639 status = ice_write_64b_phy_reg_e822(hw, port, P_REG_UIX66_10G_40G_L,
1640 uix);
1641 if (status) {
1642 ice_debug(hw, ICE_DBG_PTP, "Failed to write UIX66_10G_40G, status %d\n",
1643 status);
1644 return status;
1645 }
1646
1647
1648 uix = DIV_64BIT(tu_per_sec * LINE_UI_25G_100G, 390625000);
1649
1650 status = ice_write_64b_phy_reg_e822(hw, port, P_REG_UIX66_25G_100G_L,
1651 uix);
1652 if (status) {
1653 ice_debug(hw, ICE_DBG_PTP, "Failed to write UIX66_25G_100G, status %d\n",
1654 status);
1655 return status;
1656 }
1657
1658 return ICE_SUCCESS;
1659}
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704static enum ice_status ice_phy_cfg_parpcs_e822(struct ice_hw *hw, u8 port)
1705{
1706 u64 cur_freq, clk_incval, tu_per_sec, phy_tus;
1707 enum ice_ptp_link_spd link_spd;
1708 enum ice_ptp_fec_mode fec_mode;
1709 enum ice_status status;
1710
1711 status = ice_phy_get_speed_and_fec_e822(hw, port, &link_spd, &fec_mode);
1712 if (status)
1713 return status;
1714
1715 cur_freq = ice_e822_pll_freq(ice_e822_time_ref(hw));
1716 clk_incval = ice_ptp_read_src_incval(hw);
1717
1718
1719 tu_per_sec = cur_freq * clk_incval;
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729 if (e822_vernier[link_spd].tx_par_clk)
1730 phy_tus = DIV_64BIT(tu_per_sec,
1731 e822_vernier[link_spd].tx_par_clk);
1732 else
1733 phy_tus = 0;
1734
1735 status = ice_write_40b_phy_reg_e822(hw, port, P_REG_PAR_TX_TUS_L,
1736 phy_tus);
1737 if (status)
1738 return status;
1739
1740
1741 if (e822_vernier[link_spd].rx_par_clk)
1742 phy_tus = DIV_64BIT(tu_per_sec,
1743 e822_vernier[link_spd].rx_par_clk);
1744 else
1745 phy_tus = 0;
1746
1747 status = ice_write_40b_phy_reg_e822(hw, port, P_REG_PAR_RX_TUS_L,
1748 phy_tus);
1749 if (status)
1750 return status;
1751
1752
1753 if (e822_vernier[link_spd].tx_pcs_clk)
1754 phy_tus = DIV_64BIT(tu_per_sec,
1755 e822_vernier[link_spd].tx_pcs_clk);
1756 else
1757 phy_tus = 0;
1758
1759 status = ice_write_40b_phy_reg_e822(hw, port, P_REG_PCS_TX_TUS_L,
1760 phy_tus);
1761 if (status)
1762 return status;
1763
1764
1765 if (e822_vernier[link_spd].rx_pcs_clk)
1766 phy_tus = DIV_64BIT(tu_per_sec,
1767 e822_vernier[link_spd].rx_pcs_clk);
1768 else
1769 phy_tus = 0;
1770
1771 status = ice_write_40b_phy_reg_e822(hw, port, P_REG_PCS_RX_TUS_L,
1772 phy_tus);
1773 if (status)
1774 return status;
1775
1776
1777 if (e822_vernier[link_spd].tx_desk_rsgb_par)
1778 phy_tus = DIV_64BIT(tu_per_sec,
1779 e822_vernier[link_spd].tx_desk_rsgb_par);
1780 else
1781 phy_tus = 0;
1782
1783 status = ice_write_40b_phy_reg_e822(hw, port, P_REG_DESK_PAR_TX_TUS_L,
1784 phy_tus);
1785 if (status)
1786 return status;
1787
1788
1789 if (e822_vernier[link_spd].rx_desk_rsgb_par)
1790 phy_tus = DIV_64BIT(tu_per_sec,
1791 e822_vernier[link_spd].rx_desk_rsgb_par);
1792 else
1793 phy_tus = 0;
1794
1795 status = ice_write_40b_phy_reg_e822(hw, port, P_REG_DESK_PAR_RX_TUS_L,
1796 phy_tus);
1797 if (status)
1798 return status;
1799
1800
1801 if (e822_vernier[link_spd].tx_desk_rsgb_pcs)
1802 phy_tus = DIV_64BIT(tu_per_sec,
1803 e822_vernier[link_spd].tx_desk_rsgb_pcs);
1804 else
1805 phy_tus = 0;
1806
1807 status = ice_write_40b_phy_reg_e822(hw, port, P_REG_DESK_PCS_TX_TUS_L,
1808 phy_tus);
1809 if (status)
1810 return status;
1811
1812
1813 if (e822_vernier[link_spd].rx_desk_rsgb_pcs)
1814 phy_tus = DIV_64BIT(tu_per_sec,
1815 e822_vernier[link_spd].rx_desk_rsgb_pcs);
1816 else
1817 phy_tus = 0;
1818
1819 return ice_write_40b_phy_reg_e822(hw, port, P_REG_DESK_PCS_RX_TUS_L,
1820 phy_tus);
1821}
1822
1823
1824
1825
1826
1827
1828
1829
1830static u64
1831ice_calc_fixed_tx_offset_e822(struct ice_hw *hw, enum ice_ptp_link_spd link_spd)
1832{
1833 u64 cur_freq, clk_incval, tu_per_sec, fixed_offset;
1834
1835 cur_freq = ice_e822_pll_freq(ice_e822_time_ref(hw));
1836 clk_incval = ice_ptp_read_src_incval(hw);
1837
1838
1839 tu_per_sec = cur_freq * clk_incval;
1840
1841
1842
1843
1844
1845
1846
1847 fixed_offset = DIV_64BIT(tu_per_sec, 10000);
1848 fixed_offset *= e822_vernier[link_spd].tx_fixed_delay;
1849 fixed_offset = DIV_64BIT(fixed_offset, 10000000);
1850
1851 return fixed_offset;
1852}
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872enum ice_status ice_phy_cfg_tx_offset_e822(struct ice_hw *hw, u8 port)
1873{
1874 enum ice_ptp_link_spd link_spd;
1875 enum ice_ptp_fec_mode fec_mode;
1876 enum ice_status status;
1877 u64 total_offset, val;
1878
1879 status = ice_phy_get_speed_and_fec_e822(hw, port, &link_spd, &fec_mode);
1880 if (status)
1881 return status;
1882
1883 total_offset = ice_calc_fixed_tx_offset_e822(hw, link_spd);
1884
1885
1886
1887
1888 if (link_spd == ICE_PTP_LNK_SPD_1G ||
1889 link_spd == ICE_PTP_LNK_SPD_10G ||
1890 link_spd == ICE_PTP_LNK_SPD_25G ||
1891 link_spd == ICE_PTP_LNK_SPD_25G_RS ||
1892 link_spd == ICE_PTP_LNK_SPD_40G ||
1893 link_spd == ICE_PTP_LNK_SPD_50G) {
1894 status = ice_read_64b_phy_reg_e822(hw, port,
1895 P_REG_PAR_PCS_TX_OFFSET_L,
1896 &val);
1897 if (status)
1898 return status;
1899
1900 total_offset += val;
1901 }
1902
1903
1904
1905
1906
1907 if (link_spd == ICE_PTP_LNK_SPD_50G_RS ||
1908 link_spd == ICE_PTP_LNK_SPD_100G_RS) {
1909 status = ice_read_64b_phy_reg_e822(hw, port,
1910 P_REG_PAR_TX_TIME_L,
1911 &val);
1912 if (status)
1913 return status;
1914
1915 total_offset += val;
1916 }
1917
1918
1919
1920
1921
1922 status = ice_write_64b_phy_reg_e822(hw, port, P_REG_TOTAL_TX_OFFSET_L,
1923 total_offset);
1924 if (status)
1925 return status;
1926
1927 status = ice_write_phy_reg_e822(hw, port, P_REG_TX_OR, 1);
1928 if (status)
1929 return status;
1930
1931 return ICE_SUCCESS;
1932}
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942static enum ice_status
1943ice_phy_cfg_fixed_tx_offset_e822(struct ice_hw *hw, u8 port)
1944{
1945 enum ice_ptp_link_spd link_spd;
1946 enum ice_ptp_fec_mode fec_mode;
1947 enum ice_status status;
1948 u64 total_offset;
1949
1950 status = ice_phy_get_speed_and_fec_e822(hw, port, &link_spd, &fec_mode);
1951 if (status)
1952 return status;
1953
1954 total_offset = ice_calc_fixed_tx_offset_e822(hw, link_spd);
1955
1956
1957
1958
1959
1960
1961
1962
1963 status = ice_write_64b_phy_reg_e822(hw, port, P_REG_TOTAL_TX_OFFSET_L,
1964 total_offset);
1965 if (status)
1966 return status;
1967
1968 status = ice_write_phy_reg_e822(hw, port, P_REG_TX_OR, 1);
1969 if (status)
1970 return status;
1971
1972 return ICE_SUCCESS;
1973}
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987static enum ice_status
1988ice_phy_calc_pmd_adj_e822(struct ice_hw *hw, u8 port,
1989 enum ice_ptp_link_spd link_spd,
1990 enum ice_ptp_fec_mode fec_mode, u64 *pmd_adj)
1991{
1992 u64 cur_freq, clk_incval, tu_per_sec, mult, adj;
1993 u32 pmd_adj_divisor, val;
1994 enum ice_status status;
1995 u8 pmd_align;
1996
1997 status = ice_read_phy_reg_e822(hw, port, P_REG_PMD_ALIGNMENT, &val);
1998 if (status) {
1999 ice_debug(hw, ICE_DBG_PTP, "Failed to read PMD alignment, status %d\n",
2000 status);
2001 return status;
2002 }
2003
2004 pmd_align = (u8)val;
2005
2006 cur_freq = ice_e822_pll_freq(ice_e822_time_ref(hw));
2007 clk_incval = ice_ptp_read_src_incval(hw);
2008
2009
2010 tu_per_sec = cur_freq * clk_incval;
2011
2012
2013 pmd_adj_divisor = e822_vernier[link_spd].pmd_adj_divisor;
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039 if (link_spd == ICE_PTP_LNK_SPD_1G) {
2040 if (pmd_align == 4)
2041 mult = 10;
2042 else
2043 mult = (pmd_align + 6) % 10;
2044 } else if (link_spd == ICE_PTP_LNK_SPD_10G ||
2045 link_spd == ICE_PTP_LNK_SPD_25G ||
2046 link_spd == ICE_PTP_LNK_SPD_40G ||
2047 link_spd == ICE_PTP_LNK_SPD_50G) {
2048
2049 if (pmd_align != 65 || fec_mode == ICE_PTP_FEC_MODE_CLAUSE74)
2050 mult = pmd_align;
2051 else
2052 mult = 0;
2053 } else if (link_spd == ICE_PTP_LNK_SPD_25G_RS ||
2054 link_spd == ICE_PTP_LNK_SPD_50G_RS ||
2055 link_spd == ICE_PTP_LNK_SPD_100G_RS) {
2056 if (pmd_align < 17)
2057 mult = pmd_align + 40;
2058 else
2059 mult = pmd_align;
2060 } else {
2061 ice_debug(hw, ICE_DBG_PTP, "Unknown link speed %d, skipping PMD adjustment\n",
2062 link_spd);
2063 mult = 0;
2064 }
2065
2066
2067 if (!mult) {
2068 *pmd_adj = 0;
2069 return ICE_SUCCESS;
2070 }
2071
2072
2073
2074
2075
2076
2077 adj = DIV_64BIT(tu_per_sec, 125);
2078 adj *= mult;
2079 adj = DIV_64BIT(adj, pmd_adj_divisor);
2080
2081
2082
2083
2084 if (link_spd == ICE_PTP_LNK_SPD_25G_RS) {
2085 u64 cycle_adj;
2086 u8 rx_cycle;
2087
2088 status = ice_read_phy_reg_e822(hw, port, P_REG_RX_40_TO_160_CNT,
2089 &val);
2090 if (status) {
2091 ice_debug(hw, ICE_DBG_PTP, "Failed to read 25G-RS Rx cycle count, status %d\n",
2092 status);
2093 return status;
2094 }
2095
2096 rx_cycle = val & P_REG_RX_40_TO_160_CNT_RXCYC_M;
2097 if (rx_cycle) {
2098 mult = (4 - rx_cycle) * 40;
2099
2100 cycle_adj = DIV_64BIT(tu_per_sec, 125);
2101 cycle_adj *= mult;
2102 cycle_adj = DIV_64BIT(cycle_adj, pmd_adj_divisor);
2103
2104 adj += cycle_adj;
2105 }
2106 } else if (link_spd == ICE_PTP_LNK_SPD_50G_RS) {
2107 u64 cycle_adj;
2108 u8 rx_cycle;
2109
2110 status = ice_read_phy_reg_e822(hw, port, P_REG_RX_80_TO_160_CNT,
2111 &val);
2112 if (status) {
2113 ice_debug(hw, ICE_DBG_PTP, "Failed to read 50G-RS Rx cycle count, status %d\n",
2114 status);
2115 return status;
2116 }
2117
2118 rx_cycle = val & P_REG_RX_80_TO_160_CNT_RXCYC_M;
2119 if (rx_cycle) {
2120 mult = rx_cycle * 40;
2121
2122 cycle_adj = DIV_64BIT(tu_per_sec, 125);
2123 cycle_adj *= mult;
2124 cycle_adj = DIV_64BIT(cycle_adj, pmd_adj_divisor);
2125
2126 adj += cycle_adj;
2127 }
2128 }
2129
2130
2131 *pmd_adj = adj;
2132
2133 return ICE_SUCCESS;
2134}
2135
2136
2137
2138
2139
2140
2141
2142
2143static u64
2144ice_calc_fixed_rx_offset_e822(struct ice_hw *hw, enum ice_ptp_link_spd link_spd)
2145{
2146 u64 cur_freq, clk_incval, tu_per_sec, fixed_offset;
2147
2148 cur_freq = ice_e822_pll_freq(ice_e822_time_ref(hw));
2149 clk_incval = ice_ptp_read_src_incval(hw);
2150
2151
2152 tu_per_sec = cur_freq * clk_incval;
2153
2154
2155
2156
2157
2158
2159
2160 fixed_offset = DIV_64BIT(tu_per_sec, 10000);
2161 fixed_offset *= e822_vernier[link_spd].rx_fixed_delay;
2162 fixed_offset = DIV_64BIT(fixed_offset, 10000000);
2163
2164 return fixed_offset;
2165}
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186enum ice_status ice_phy_cfg_rx_offset_e822(struct ice_hw *hw, u8 port)
2187{
2188 enum ice_ptp_link_spd link_spd;
2189 enum ice_ptp_fec_mode fec_mode;
2190 u64 total_offset, pmd, val;
2191 enum ice_status status;
2192
2193 status = ice_phy_get_speed_and_fec_e822(hw, port, &link_spd, &fec_mode);
2194 if (status)
2195 return status;
2196
2197 total_offset = ice_calc_fixed_rx_offset_e822(hw, link_spd);
2198
2199
2200
2201
2202 status = ice_read_64b_phy_reg_e822(hw, port,
2203 P_REG_PAR_PCS_RX_OFFSET_L,
2204 &val);
2205 if (status)
2206 return status;
2207
2208 total_offset += val;
2209
2210
2211
2212
2213 if (link_spd == ICE_PTP_LNK_SPD_40G ||
2214 link_spd == ICE_PTP_LNK_SPD_50G ||
2215 link_spd == ICE_PTP_LNK_SPD_50G_RS ||
2216 link_spd == ICE_PTP_LNK_SPD_100G_RS) {
2217 status = ice_read_64b_phy_reg_e822(hw, port,
2218 P_REG_PAR_RX_TIME_L,
2219 &val);
2220 if (status)
2221 return status;
2222
2223 total_offset += val;
2224 }
2225
2226
2227 status = ice_phy_calc_pmd_adj_e822(hw, port, link_spd, fec_mode, &pmd);
2228 if (status)
2229 return status;
2230
2231
2232
2233
2234 if (fec_mode == ICE_PTP_FEC_MODE_RS_FEC)
2235 total_offset += pmd;
2236 else
2237 total_offset -= pmd;
2238
2239
2240
2241
2242
2243 status = ice_write_64b_phy_reg_e822(hw, port, P_REG_TOTAL_RX_OFFSET_L,
2244 total_offset);
2245 if (status)
2246 return status;
2247
2248 status = ice_write_phy_reg_e822(hw, port, P_REG_RX_OR, 1);
2249 if (status)
2250 return status;
2251
2252 return ICE_SUCCESS;
2253}
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263static enum ice_status
2264ice_phy_cfg_fixed_rx_offset_e822(struct ice_hw *hw, u8 port)
2265{
2266 enum ice_ptp_link_spd link_spd;
2267 enum ice_ptp_fec_mode fec_mode;
2268 enum ice_status status;
2269 u64 total_offset;
2270
2271 status = ice_phy_get_speed_and_fec_e822(hw, port, &link_spd, &fec_mode);
2272 if (status)
2273 return status;
2274
2275 total_offset = ice_calc_fixed_rx_offset_e822(hw, link_spd);
2276
2277
2278
2279
2280
2281
2282
2283
2284 status = ice_write_64b_phy_reg_e822(hw, port, P_REG_TOTAL_RX_OFFSET_L,
2285 total_offset);
2286 if (status)
2287 return status;
2288
2289 status = ice_write_phy_reg_e822(hw, port, P_REG_RX_OR, 1);
2290 if (status)
2291 return status;
2292
2293 return ICE_SUCCESS;
2294}
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306static enum ice_status
2307ice_read_phy_and_phc_time_e822(struct ice_hw *hw, u8 port, u64 *phy_time,
2308 u64 *phc_time)
2309{
2310 enum ice_status status;
2311 u64 tx_time, rx_time;
2312 u32 zo, lo;
2313 u8 tmr_idx;
2314
2315 tmr_idx = ice_get_ptp_src_clock_index(hw);
2316
2317
2318 ice_ptp_src_cmd(hw, READ_TIME);
2319
2320
2321 status = ice_ptp_one_port_cmd(hw, port, READ_TIME, true);
2322 if (status)
2323 return status;
2324
2325
2326 ice_ptp_exec_tmr_cmd(hw);
2327
2328
2329 zo = rd32(hw, GLTSYN_SHTIME_0(tmr_idx));
2330 lo = rd32(hw, GLTSYN_SHTIME_L(tmr_idx));
2331 *phc_time = (u64)lo << 32 | zo;
2332
2333
2334 status = ice_ptp_read_port_capture(hw, port, &tx_time, &rx_time);
2335 if (status)
2336 return status;
2337
2338
2339
2340
2341
2342 if (tx_time != rx_time)
2343 ice_warn(hw, "PHY port %u Tx and Rx timers do not match, tx_time 0x%016llX, rx_time 0x%016llX\n",
2344 port, (unsigned long long)tx_time,
2345 (unsigned long long)rx_time);
2346
2347 *phy_time = tx_time;
2348
2349 return ICE_SUCCESS;
2350}
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363static enum ice_status ice_sync_phy_timer_e822(struct ice_hw *hw, u8 port)
2364{
2365 u64 phc_time, phy_time, difference;
2366 enum ice_status status;
2367
2368 if (!ice_ptp_lock(hw)) {
2369 ice_debug(hw, ICE_DBG_PTP, "Failed to acquire PTP semaphore\n");
2370 return ICE_ERR_NOT_READY;
2371 }
2372
2373 status = ice_read_phy_and_phc_time_e822(hw, port, &phy_time, &phc_time);
2374 if (status)
2375 goto err_unlock;
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385 difference = phc_time - phy_time;
2386
2387 status = ice_ptp_prep_port_adj_e822(hw, port, (s64)difference, true);
2388 if (status)
2389 goto err_unlock;
2390
2391 status = ice_ptp_one_port_cmd(hw, port, ADJ_TIME, true);
2392 if (status)
2393 goto err_unlock;
2394
2395
2396 ice_ptp_exec_tmr_cmd(hw);
2397
2398
2399
2400
2401 status = ice_read_phy_and_phc_time_e822(hw, port, &phy_time, &phc_time);
2402 if (status)
2403 goto err_unlock;
2404
2405 ice_info(hw, "Port %u PHY time synced to PHC: 0x%016llX, 0x%016llX\n",
2406 port, (unsigned long long)phy_time,
2407 (unsigned long long)phc_time);
2408
2409 ice_ptp_unlock(hw);
2410
2411 return ICE_SUCCESS;
2412
2413err_unlock:
2414 ice_ptp_unlock(hw);
2415 return status;
2416}
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428enum ice_status
2429ice_stop_phy_timer_e822(struct ice_hw *hw, u8 port, bool soft_reset)
2430{
2431 enum ice_status status;
2432 u32 val;
2433
2434 status = ice_write_phy_reg_e822(hw, port, P_REG_TX_OR, 0);
2435 if (status)
2436 return status;
2437
2438 status = ice_write_phy_reg_e822(hw, port, P_REG_RX_OR, 0);
2439 if (status)
2440 return status;
2441
2442 status = ice_read_phy_reg_e822(hw, port, P_REG_PS, &val);
2443 if (status)
2444 return status;
2445
2446 val &= ~P_REG_PS_START_M;
2447 status = ice_write_phy_reg_e822(hw, port, P_REG_PS, val);
2448 if (status)
2449 return status;
2450
2451 val &= ~P_REG_PS_ENA_CLK_M;
2452 status = ice_write_phy_reg_e822(hw, port, P_REG_PS, val);
2453 if (status)
2454 return status;
2455
2456 if (soft_reset) {
2457 val |= P_REG_PS_SFT_RESET_M;
2458 status = ice_write_phy_reg_e822(hw, port, P_REG_PS, val);
2459 if (status)
2460 return status;
2461 }
2462
2463 ice_debug(hw, ICE_DBG_PTP, "Disabled clock on PHY port %u\n", port);
2464
2465 return ICE_SUCCESS;
2466}
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484enum ice_status
2485ice_start_phy_timer_e822(struct ice_hw *hw, u8 port, bool bypass)
2486{
2487 enum ice_status status;
2488 u32 lo, hi, val;
2489 u64 incval;
2490 u8 tmr_idx;
2491
2492 tmr_idx = ice_get_ptp_src_clock_index(hw);
2493
2494 status = ice_stop_phy_timer_e822(hw, port, false);
2495 if (status)
2496 return status;
2497
2498 ice_phy_cfg_lane_e822(hw, port);
2499
2500 status = ice_phy_cfg_uix_e822(hw, port);
2501 if (status)
2502 return status;
2503
2504 status = ice_phy_cfg_parpcs_e822(hw, port);
2505 if (status)
2506 return status;
2507
2508 lo = rd32(hw, GLTSYN_INCVAL_L(tmr_idx));
2509 hi = rd32(hw, GLTSYN_INCVAL_H(tmr_idx));
2510 incval = (u64)hi << 32 | lo;
2511
2512 status = ice_write_40b_phy_reg_e822(hw, port, P_REG_TIMETUS_L, incval);
2513 if (status)
2514 return status;
2515
2516 status = ice_ptp_one_port_cmd(hw, port, INIT_INCVAL, true);
2517 if (status)
2518 return status;
2519
2520 ice_ptp_exec_tmr_cmd(hw);
2521
2522 status = ice_read_phy_reg_e822(hw, port, P_REG_PS, &val);
2523 if (status)
2524 return status;
2525
2526 val |= P_REG_PS_SFT_RESET_M;
2527 status = ice_write_phy_reg_e822(hw, port, P_REG_PS, val);
2528 if (status)
2529 return status;
2530
2531 val |= P_REG_PS_START_M;
2532 status = ice_write_phy_reg_e822(hw, port, P_REG_PS, val);
2533 if (status)
2534 return status;
2535
2536 val &= ~P_REG_PS_SFT_RESET_M;
2537 status = ice_write_phy_reg_e822(hw, port, P_REG_PS, val);
2538 if (status)
2539 return status;
2540
2541 status = ice_ptp_one_port_cmd(hw, port, INIT_INCVAL, true);
2542 if (status)
2543 return status;
2544
2545 ice_ptp_exec_tmr_cmd(hw);
2546
2547 val |= P_REG_PS_ENA_CLK_M;
2548 status = ice_write_phy_reg_e822(hw, port, P_REG_PS, val);
2549 if (status)
2550 return status;
2551
2552 val |= P_REG_PS_LOAD_OFFSET_M;
2553 status = ice_write_phy_reg_e822(hw, port, P_REG_PS, val);
2554 if (status)
2555 return status;
2556
2557 ice_ptp_exec_tmr_cmd(hw);
2558
2559 status = ice_sync_phy_timer_e822(hw, port);
2560 if (status)
2561 return status;
2562
2563 if (bypass) {
2564 val |= P_REG_PS_BYPASS_MODE_M;
2565
2566 status = ice_write_phy_reg_e822(hw, port, P_REG_PS, val);
2567 if (status)
2568 return status;
2569
2570
2571 status = ice_phy_cfg_fixed_tx_offset_e822(hw, port);
2572 if (status)
2573 return status;
2574
2575
2576 status = ice_phy_cfg_fixed_rx_offset_e822(hw, port);
2577 if (status)
2578 return status;
2579 }
2580
2581 ice_debug(hw, ICE_DBG_PTP, "Enabled clock on PHY port %u\n", port);
2582
2583 return ICE_SUCCESS;
2584}
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600enum ice_status ice_phy_exit_bypass_e822(struct ice_hw *hw, u8 port)
2601{
2602 enum ice_status status;
2603 u32 val;
2604
2605 status = ice_read_phy_reg_e822(hw, port, P_REG_TX_OV_STATUS, &val);
2606 if (status) {
2607 ice_debug(hw, ICE_DBG_PTP, "Failed to read TX_OV_STATUS for port %u, status %d\n",
2608 port, status);
2609 return status;
2610 }
2611
2612 if (!(val & P_REG_TX_OV_STATUS_OV_M)) {
2613 ice_debug(hw, ICE_DBG_PTP, "Tx offset is not yet valid for port %u\n",
2614 port);
2615 return ICE_ERR_NOT_READY;
2616 }
2617
2618 status = ice_read_phy_reg_e822(hw, port, P_REG_RX_OV_STATUS, &val);
2619 if (status) {
2620 ice_debug(hw, ICE_DBG_PTP, "Failed to read RX_OV_STATUS for port %u, status %d\n",
2621 port, status);
2622 return status;
2623 }
2624
2625 if (!(val & P_REG_TX_OV_STATUS_OV_M)) {
2626 ice_debug(hw, ICE_DBG_PTP, "Rx offset is not yet valid for port %u\n",
2627 port);
2628 return ICE_ERR_NOT_READY;
2629 }
2630
2631 status = ice_phy_cfg_tx_offset_e822(hw, port);
2632 if (status) {
2633 ice_debug(hw, ICE_DBG_PTP, "Failed to program total Tx offset for port %u, status %d\n",
2634 port, status);
2635 return status;
2636 }
2637
2638 status = ice_phy_cfg_rx_offset_e822(hw, port);
2639 if (status) {
2640 ice_debug(hw, ICE_DBG_PTP, "Failed to program total Rx offset for port %u, status %d\n",
2641 port, status);
2642 return status;
2643 }
2644
2645
2646 status = ice_read_phy_reg_e822(hw, port, P_REG_PS, &val);
2647 if (status) {
2648 ice_debug(hw, ICE_DBG_PTP, "Failed to read P_REG_PS for port %u, status %d\n",
2649 port, status);
2650 return status;
2651 }
2652
2653 if (!(val & P_REG_PS_BYPASS_MODE_M))
2654 ice_debug(hw, ICE_DBG_PTP, "Port %u not in bypass mode\n",
2655 port);
2656
2657 val &= ~P_REG_PS_BYPASS_MODE_M;
2658 status = ice_write_phy_reg_e822(hw, port, P_REG_PS, val);
2659 if (status) {
2660 ice_debug(hw, ICE_DBG_PTP, "Failed to disable bypass for port %u, status %d\n",
2661 port, status);
2662 return status;
2663 }
2664
2665 ice_info(hw, "Exiting bypass mode on PHY port %u\n", port);
2666
2667 return ICE_SUCCESS;
2668}
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685static enum ice_status
2686ice_read_phy_reg_e810_lp(struct ice_hw *hw, u32 addr, u32 *val, bool lock_sbq)
2687{
2688 struct ice_sbq_msg_input msg = {0};
2689 enum ice_status status;
2690
2691 msg.msg_addr_low = ICE_LO_WORD(addr);
2692 msg.msg_addr_high = ICE_HI_WORD(addr);
2693 msg.opcode = ice_sbq_msg_rd;
2694 msg.dest_dev = rmn_0;
2695
2696 status = ice_sbq_rw_reg_lp(hw, &msg, lock_sbq);
2697 if (status) {
2698 ice_debug(hw, ICE_DBG_PTP, "Failed to send message to phy, status %d\n",
2699 status);
2700 return status;
2701 }
2702
2703 *val = msg.data;
2704
2705 return ICE_SUCCESS;
2706}
2707
2708static enum ice_status
2709ice_read_phy_reg_e810(struct ice_hw *hw, u32 addr, u32 *val)
2710{
2711 return ice_read_phy_reg_e810_lp(hw, addr, val, true);
2712}
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723static enum ice_status
2724ice_write_phy_reg_e810_lp(struct ice_hw *hw, u32 addr, u32 val, bool lock_sbq)
2725{
2726 struct ice_sbq_msg_input msg = {0};
2727 enum ice_status status;
2728
2729 msg.msg_addr_low = ICE_LO_WORD(addr);
2730 msg.msg_addr_high = ICE_HI_WORD(addr);
2731 msg.opcode = ice_sbq_msg_wr;
2732 msg.dest_dev = rmn_0;
2733 msg.data = val;
2734
2735 status = ice_sbq_rw_reg_lp(hw, &msg, lock_sbq);
2736 if (status) {
2737 ice_debug(hw, ICE_DBG_PTP, "Failed to send message to phy, status %d\n",
2738 status);
2739 return status;
2740 }
2741
2742 return ICE_SUCCESS;
2743}
2744
2745static enum ice_status
2746ice_write_phy_reg_e810(struct ice_hw *hw, u32 addr, u32 val)
2747{
2748 return ice_write_phy_reg_e810_lp(hw, addr, val, true);
2749}
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761static enum ice_status
2762ice_read_phy_tstamp_e810(struct ice_hw *hw, u8 lport, u8 idx, u64 *tstamp)
2763{
2764 enum ice_status status;
2765 u32 lo_addr, hi_addr, lo, hi;
2766
2767 lo_addr = TS_EXT(LOW_TX_MEMORY_BANK_START, lport, idx);
2768 hi_addr = TS_EXT(HIGH_TX_MEMORY_BANK_START, lport, idx);
2769
2770 status = ice_read_phy_reg_e810(hw, lo_addr, &lo);
2771 if (status) {
2772 ice_debug(hw, ICE_DBG_PTP, "Failed to read low PTP timestamp register, status %d\n",
2773 status);
2774 return status;
2775 }
2776
2777 status = ice_read_phy_reg_e810(hw, hi_addr, &hi);
2778 if (status) {
2779 ice_debug(hw, ICE_DBG_PTP, "Failed to read high PTP timestamp register, status %d\n",
2780 status);
2781 return status;
2782 }
2783
2784
2785
2786
2787 *tstamp = ((u64)hi) << TS_HIGH_S | ((u64)lo & TS_LOW_M);
2788
2789 return ICE_SUCCESS;
2790}
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801static enum ice_status
2802ice_clear_phy_tstamp_e810(struct ice_hw *hw, u8 lport, u8 idx)
2803{
2804 enum ice_status status;
2805 u32 lo_addr, hi_addr;
2806
2807 lo_addr = TS_EXT(LOW_TX_MEMORY_BANK_START, lport, idx);
2808 hi_addr = TS_EXT(HIGH_TX_MEMORY_BANK_START, lport, idx);
2809
2810 status = ice_write_phy_reg_e810(hw, lo_addr, 0);
2811 if (status) {
2812 ice_debug(hw, ICE_DBG_PTP, "Failed to clear low PTP timestamp register, status %d\n",
2813 status);
2814 return status;
2815 }
2816
2817 status = ice_write_phy_reg_e810(hw, hi_addr, 0);
2818 if (status) {
2819 ice_debug(hw, ICE_DBG_PTP, "Failed to clear high PTP timestamp register, status %d\n",
2820 status);
2821 return status;
2822 }
2823
2824 return ICE_SUCCESS;
2825}
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836enum ice_status ice_ptp_init_phy_e810(struct ice_hw *hw)
2837{
2838 enum ice_status status;
2839 u8 tmr_idx;
2840
2841 tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
2842 status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_ENA(tmr_idx),
2843 GLTSYN_ENA_TSYN_ENA_M);
2844 if (status)
2845 ice_debug(hw, ICE_DBG_PTP, "PTP failed in ena_phy_time_syn %d\n",
2846 status);
2847
2848 return status;
2849}
2850
2851
2852
2853
2854
2855
2856
2857static enum ice_status ice_ptp_init_phc_e810(struct ice_hw *hw)
2858{
2859
2860 wr32(hw, GLTSYN_SYNC_DLAY, 0);
2861
2862
2863 return ice_ptp_init_phy_e810(hw);
2864}
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878static enum ice_status ice_ptp_prep_phy_time_e810(struct ice_hw *hw, u32 time)
2879{
2880 enum ice_status status;
2881 u8 tmr_idx;
2882
2883 tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
2884 status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHTIME_0(tmr_idx), 0);
2885 if (status) {
2886 ice_debug(hw, ICE_DBG_PTP, "Failed to write SHTIME_0, status %d\n",
2887 status);
2888 return status;
2889 }
2890
2891 status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHTIME_L(tmr_idx), time);
2892 if (status) {
2893 ice_debug(hw, ICE_DBG_PTP, "Failed to write SHTIME_L, status %d\n",
2894 status);
2895 return status;
2896 }
2897
2898 return ICE_SUCCESS;
2899}
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915static enum ice_status
2916ice_ptp_prep_phy_adj_e810(struct ice_hw *hw, s32 adj, bool lock_sbq)
2917{
2918 enum ice_status status;
2919 u8 tmr_idx;
2920
2921 tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
2922
2923
2924
2925
2926 status = ice_write_phy_reg_e810_lp(hw, ETH_GLTSYN_SHADJ_L(tmr_idx),
2927 0, lock_sbq);
2928 if (status) {
2929 ice_debug(hw, ICE_DBG_PTP, "Failed to write adj to PHY SHADJ_L, status %d\n",
2930 status);
2931 return status;
2932 }
2933
2934 status = ice_write_phy_reg_e810_lp(hw, ETH_GLTSYN_SHADJ_H(tmr_idx),
2935 adj, lock_sbq);
2936 if (status) {
2937 ice_debug(hw, ICE_DBG_PTP, "Failed to write adj to PHY SHADJ_H, status %d\n",
2938 status);
2939 return status;
2940 }
2941
2942 return ICE_SUCCESS;
2943}
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954static enum ice_status
2955ice_ptp_prep_phy_incval_e810(struct ice_hw *hw, u64 incval)
2956{
2957 enum ice_status status;
2958 u32 high, low;
2959 u8 tmr_idx;
2960
2961 tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
2962 low = ICE_LO_DWORD(incval);
2963 high = ICE_HI_DWORD(incval);
2964
2965 status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHADJ_L(tmr_idx), low);
2966 if (status) {
2967 ice_debug(hw, ICE_DBG_PTP, "Failed to write incval to PHY SHADJ_L, status %d\n",
2968 status);
2969 return status;
2970 }
2971
2972 status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHADJ_H(tmr_idx), high);
2973 if (status) {
2974 ice_debug(hw, ICE_DBG_PTP, "Failed to write incval PHY SHADJ_H, status %d\n",
2975 status);
2976 return status;
2977 }
2978
2979 return ICE_SUCCESS;
2980}
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996static enum ice_status
2997ice_ptp_prep_phy_adj_target_e810(struct ice_hw *hw, u32 target_time)
2998{
2999 enum ice_status status;
3000 u8 tmr_idx;
3001
3002 tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
3003 status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHTIME_0(tmr_idx), 0);
3004 if (status) {
3005 ice_debug(hw, ICE_DBG_PTP, "Failed to write target time to SHTIME_0, status %d\n",
3006 status);
3007 return status;
3008 }
3009
3010 status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHTIME_L(tmr_idx),
3011 target_time);
3012 if (status) {
3013 ice_debug(hw, ICE_DBG_PTP, "Failed to write target time to SHTIME_L, status %d\n",
3014 status);
3015 return status;
3016 }
3017
3018 return ICE_SUCCESS;
3019}
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030static enum ice_status
3031ice_ptp_port_cmd_e810(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd,
3032 bool lock_sbq)
3033{
3034 enum ice_status status;
3035 u32 cmd_val, val;
3036
3037 switch (cmd) {
3038 case INIT_TIME:
3039 cmd_val = GLTSYN_CMD_INIT_TIME;
3040 break;
3041 case INIT_INCVAL:
3042 cmd_val = GLTSYN_CMD_INIT_INCVAL;
3043 break;
3044 case ADJ_TIME:
3045 cmd_val = GLTSYN_CMD_ADJ_TIME;
3046 break;
3047 case ADJ_TIME_AT_TIME:
3048 cmd_val = GLTSYN_CMD_ADJ_INIT_TIME;
3049 break;
3050 case READ_TIME:
3051 cmd_val = GLTSYN_CMD_READ_TIME;
3052 break;
3053 default:
3054 ice_warn(hw, "Unknown timer command %u\n", cmd);
3055 return ICE_ERR_PARAM;
3056 }
3057
3058
3059 status = ice_read_phy_reg_e810_lp(hw, ETH_GLTSYN_CMD, &val, lock_sbq);
3060 if (status) {
3061 ice_debug(hw, ICE_DBG_PTP, "Failed to read GLTSYN_CMD, status %d\n",
3062 status);
3063 return status;
3064 }
3065
3066
3067 val &= ~TS_CMD_MASK_E810;
3068 val |= cmd_val;
3069
3070 status = ice_write_phy_reg_e810_lp(hw, ETH_GLTSYN_CMD, val, lock_sbq);
3071 if (status) {
3072 ice_debug(hw, ICE_DBG_PTP, "Failed to write back GLTSYN_CMD, status %d\n",
3073 status);
3074 return status;
3075 }
3076
3077 return ICE_SUCCESS;
3078}
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095static enum ice_status
3096ice_get_pca9575_handle(struct ice_hw *hw, __le16 *pca9575_handle)
3097{
3098 struct ice_aqc_get_link_topo *cmd;
3099 struct ice_aq_desc desc;
3100 enum ice_status status;
3101 u8 idx;
3102
3103 if (!hw || !pca9575_handle)
3104 return ICE_ERR_PARAM;
3105
3106
3107 if (hw->io_expander_handle) {
3108 *pca9575_handle = hw->io_expander_handle;
3109 return ICE_SUCCESS;
3110 }
3111
3112
3113 cmd = &desc.params.get_link_topo;
3114 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_link_topo);
3115
3116
3117 cmd->addr.topo_params.node_type_ctx =
3118 (ICE_AQC_LINK_TOPO_NODE_TYPE_M &
3119 ICE_AQC_LINK_TOPO_NODE_TYPE_GPIO_CTRL);
3120
3121#define SW_PCA9575_SFP_TOPO_IDX 2
3122#define SW_PCA9575_QSFP_TOPO_IDX 1
3123
3124
3125 if (hw->device_id == ICE_DEV_ID_E810C_SFP)
3126 idx = SW_PCA9575_SFP_TOPO_IDX;
3127 else if (hw->device_id == ICE_DEV_ID_E810C_QSFP)
3128 idx = SW_PCA9575_QSFP_TOPO_IDX;
3129 else
3130 return ICE_ERR_NOT_SUPPORTED;
3131
3132 cmd->addr.topo_params.index = idx;
3133
3134 status = ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
3135 if (status)
3136 return ICE_ERR_NOT_SUPPORTED;
3137
3138
3139 if (desc.params.get_link_topo.node_part_num !=
3140 ICE_ACQ_GET_LINK_TOPO_NODE_NR_PCA9575)
3141 return ICE_ERR_NOT_SUPPORTED;
3142
3143
3144 hw->io_expander_handle = desc.params.get_link_topo.addr.handle;
3145 *pca9575_handle = hw->io_expander_handle;
3146
3147 return ICE_SUCCESS;
3148}
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158enum ice_status
3159ice_read_e810t_pca9575_reg(struct ice_hw *hw, u8 offset, u8 *data)
3160{
3161 struct ice_aqc_link_topo_addr link_topo;
3162 enum ice_status status;
3163 __le16 addr;
3164
3165 memset(&link_topo, 0, sizeof(link_topo));
3166
3167 status = ice_get_pca9575_handle(hw, &link_topo.handle);
3168 if (status)
3169 return status;
3170
3171 link_topo.topo_params.node_type_ctx =
3172 (ICE_AQC_LINK_TOPO_NODE_CTX_PROVIDED <<
3173 ICE_AQC_LINK_TOPO_NODE_CTX_S);
3174
3175 addr = CPU_TO_LE16((u16)offset);
3176
3177 return ice_aq_read_i2c(hw, link_topo, 0, addr, 1, data, NULL);
3178}
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188enum ice_status
3189ice_write_e810t_pca9575_reg(struct ice_hw *hw, u8 offset, u8 data)
3190{
3191 struct ice_aqc_link_topo_addr link_topo;
3192 enum ice_status status;
3193 __le16 addr;
3194
3195 memset(&link_topo, 0, sizeof(link_topo));
3196
3197 status = ice_get_pca9575_handle(hw, &link_topo.handle);
3198 if (status)
3199 return status;
3200
3201 link_topo.topo_params.node_type_ctx =
3202 (ICE_AQC_LINK_TOPO_NODE_CTX_PROVIDED <<
3203 ICE_AQC_LINK_TOPO_NODE_CTX_S);
3204
3205 addr = CPU_TO_LE16((u16)offset);
3206
3207 return ice_aq_write_i2c(hw, link_topo, 0, addr, 1, &data, NULL);
3208}
3209
3210
3211
3212
3213
3214
3215
3216
3217enum ice_status ice_read_sma_ctrl_e810t(struct ice_hw *hw, u8 *data)
3218{
3219 enum ice_status status;
3220 u16 handle;
3221 u8 i;
3222
3223 status = ice_get_pca9575_handle(hw, &handle);
3224 if (status)
3225 return status;
3226
3227 *data = 0;
3228
3229 for (i = ICE_E810T_SMA_MIN_BIT; i <= ICE_E810T_SMA_MAX_BIT; i++) {
3230 bool pin;
3231
3232 status = ice_aq_get_gpio(hw, handle, i + ICE_E810T_P1_OFFSET,
3233 &pin, NULL);
3234 if (status)
3235 break;
3236 *data |= (u8)(!pin) << i;
3237 }
3238
3239 return status;
3240}
3241
3242
3243
3244
3245
3246
3247
3248
3249enum ice_status ice_write_sma_ctrl_e810t(struct ice_hw *hw, u8 data)
3250{
3251 enum ice_status status;
3252 u16 handle;
3253 u8 i;
3254
3255 status = ice_get_pca9575_handle(hw, &handle);
3256 if (status)
3257 return status;
3258
3259 for (i = ICE_E810T_SMA_MIN_BIT; i <= ICE_E810T_SMA_MAX_BIT; i++) {
3260 bool pin;
3261
3262 pin = !(data & (1 << i));
3263 status = ice_aq_set_gpio(hw, handle, i + ICE_E810T_P1_OFFSET,
3264 pin, NULL);
3265 if (status)
3266 break;
3267 }
3268
3269 return status;
3270}
3271
3272
3273
3274
3275
3276
3277
3278bool ice_e810t_is_pca9575_present(struct ice_hw *hw)
3279{
3280 enum ice_status status;
3281 __le16 handle = 0;
3282
3283 if (!ice_is_e810t(hw))
3284 return false;
3285
3286 status = ice_get_pca9575_handle(hw, &handle);
3287 if (!status && handle)
3288 return true;
3289
3290 return false;
3291}
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315bool ice_ptp_lock(struct ice_hw *hw)
3316{
3317 u32 hw_lock;
3318 int i;
3319
3320#define MAX_TRIES 5
3321
3322 for (i = 0; i < MAX_TRIES; i++) {
3323 hw_lock = rd32(hw, PFTSYN_SEM + (PFTSYN_SEM_BYTES * hw->pf_id));
3324 hw_lock = hw_lock & PFTSYN_SEM_BUSY_M;
3325 if (hw_lock) {
3326
3327 ice_msec_delay(10, true);
3328 continue;
3329 } else {
3330 break;
3331 }
3332 }
3333
3334 return !hw_lock;
3335}
3336
3337
3338
3339
3340
3341
3342
3343
3344void ice_ptp_unlock(struct ice_hw *hw)
3345{
3346 wr32(hw, PFTSYN_SEM + (PFTSYN_SEM_BYTES * hw->pf_id), 0);
3347}
3348
3349
3350
3351
3352
3353
3354
3355
3356void ice_ptp_src_cmd(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd)
3357{
3358 u32 cmd_val;
3359 u8 tmr_idx;
3360
3361 tmr_idx = ice_get_ptp_src_clock_index(hw);
3362 cmd_val = tmr_idx << SEL_CPK_SRC;
3363
3364 switch (cmd) {
3365 case INIT_TIME:
3366 cmd_val |= GLTSYN_CMD_INIT_TIME;
3367 break;
3368 case INIT_INCVAL:
3369 cmd_val |= GLTSYN_CMD_INIT_INCVAL;
3370 break;
3371 case ADJ_TIME:
3372 cmd_val |= GLTSYN_CMD_ADJ_TIME;
3373 break;
3374 case ADJ_TIME_AT_TIME:
3375 cmd_val |= GLTSYN_CMD_ADJ_INIT_TIME;
3376 break;
3377 case READ_TIME:
3378 cmd_val |= GLTSYN_CMD_READ_TIME;
3379 break;
3380 default:
3381 ice_warn(hw, "Unknown timer command %u\n", cmd);
3382 return;
3383 }
3384
3385 wr32(hw, GLTSYN_CMD, cmd_val);
3386}
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399static enum ice_status
3400ice_ptp_tmr_cmd(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd, bool lock_sbq)
3401{
3402 enum ice_status status;
3403
3404
3405 ice_ptp_src_cmd(hw, cmd);
3406
3407
3408 if (ice_is_e810(hw))
3409 status = ice_ptp_port_cmd_e810(hw, cmd, lock_sbq);
3410 else
3411 status = ice_ptp_port_cmd_e822(hw, cmd, lock_sbq);
3412 if (status) {
3413 ice_debug(hw, ICE_DBG_PTP, "Failed to prepare PHY ports for timer command %u, status %d\n",
3414 cmd, status);
3415 return status;
3416 }
3417
3418
3419
3420
3421 ice_ptp_exec_tmr_cmd(hw);
3422
3423 return ICE_SUCCESS;
3424}
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439enum ice_status ice_ptp_init_time(struct ice_hw *hw, u64 time)
3440{
3441 enum ice_status status;
3442 u8 tmr_idx;
3443
3444 tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
3445
3446
3447 wr32(hw, GLTSYN_SHTIME_L(tmr_idx), ICE_LO_DWORD(time));
3448 wr32(hw, GLTSYN_SHTIME_H(tmr_idx), ICE_HI_DWORD(time));
3449 wr32(hw, GLTSYN_SHTIME_0(tmr_idx), 0);
3450
3451
3452
3453 if (ice_is_e810(hw))
3454 status = ice_ptp_prep_phy_time_e810(hw, time & 0xFFFFFFFF);
3455 else
3456 status = ice_ptp_prep_phy_time_e822(hw, time & 0xFFFFFFFF);
3457 if (status)
3458 return status;
3459
3460 return ice_ptp_tmr_cmd(hw, INIT_TIME, true);
3461}
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477enum ice_status ice_ptp_write_incval(struct ice_hw *hw, u64 incval)
3478{
3479 enum ice_status status;
3480 u8 tmr_idx;
3481
3482 tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
3483
3484
3485 wr32(hw, GLTSYN_SHADJ_L(tmr_idx), ICE_LO_DWORD(incval));
3486 wr32(hw, GLTSYN_SHADJ_H(tmr_idx), ICE_HI_DWORD(incval));
3487
3488 if (ice_is_e810(hw))
3489 status = ice_ptp_prep_phy_incval_e810(hw, incval);
3490 else
3491 status = ice_ptp_prep_phy_incval_e822(hw, incval);
3492 if (status)
3493 return status;
3494
3495 return ice_ptp_tmr_cmd(hw, INIT_INCVAL, true);
3496}
3497
3498
3499
3500
3501
3502
3503
3504
3505enum ice_status ice_ptp_write_incval_locked(struct ice_hw *hw, u64 incval)
3506{
3507 enum ice_status status;
3508
3509 if (!ice_ptp_lock(hw))
3510 return ICE_ERR_NOT_READY;
3511
3512 status = ice_ptp_write_incval(hw, incval);
3513
3514 ice_ptp_unlock(hw);
3515
3516 return status;
3517}
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534enum ice_status ice_ptp_adj_clock(struct ice_hw *hw, s32 adj, bool lock_sbq)
3535{
3536 enum ice_status status;
3537 u8 tmr_idx;
3538
3539 tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
3540
3541
3542
3543
3544
3545
3546 wr32(hw, GLTSYN_SHADJ_L(tmr_idx), 0);
3547 wr32(hw, GLTSYN_SHADJ_H(tmr_idx), adj);
3548
3549 if (ice_is_e810(hw))
3550 status = ice_ptp_prep_phy_adj_e810(hw, adj, lock_sbq);
3551 else
3552 status = ice_ptp_prep_phy_adj_e822(hw, adj, lock_sbq);
3553 if (status)
3554 return status;
3555
3556 return ice_ptp_tmr_cmd(hw, ADJ_TIME, lock_sbq);
3557}
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574enum ice_status
3575ice_ptp_adj_clock_at_time(struct ice_hw *hw, u64 at_time, s32 adj)
3576{
3577 enum ice_status status;
3578 u32 time_lo, time_hi;
3579 u8 tmr_idx;
3580
3581 tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
3582 time_lo = ICE_LO_DWORD(at_time);
3583 time_hi = ICE_HI_DWORD(at_time);
3584
3585
3586
3587
3588
3589
3590 wr32(hw, GLTSYN_SHADJ_L(tmr_idx), 0);
3591 wr32(hw, GLTSYN_SHADJ_H(tmr_idx), adj);
3592
3593
3594 wr32(hw, GLTSYN_SHTIME_0(tmr_idx), 0);
3595 wr32(hw, GLTSYN_SHTIME_L(tmr_idx), time_lo);
3596 wr32(hw, GLTSYN_SHTIME_H(tmr_idx), time_hi);
3597
3598
3599 if (ice_is_e810(hw))
3600 status = ice_ptp_prep_phy_adj_e810(hw, adj, true);
3601 else
3602 status = ice_ptp_prep_phy_adj_e822(hw, adj, true);
3603 if (status)
3604 return status;
3605
3606
3607 if (ice_is_e810(hw))
3608 status = ice_ptp_prep_phy_adj_target_e810(hw, time_lo);
3609 else
3610 status = ice_ptp_prep_phy_adj_target_e822(hw, time_lo);
3611 if (status)
3612 return status;
3613
3614 return ice_ptp_tmr_cmd(hw, ADJ_TIME_AT_TIME, true);
3615}
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628enum ice_status
3629ice_read_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx, u64 *tstamp)
3630{
3631 if (ice_is_e810(hw))
3632 return ice_read_phy_tstamp_e810(hw, block, idx, tstamp);
3633 else
3634 return ice_read_phy_tstamp_e822(hw, block, idx, tstamp);
3635}
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647enum ice_status
3648ice_clear_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx)
3649{
3650 if (ice_is_e810(hw))
3651 return ice_clear_phy_tstamp_e810(hw, block, idx);
3652 else
3653 return ice_clear_phy_tstamp_e822(hw, block, idx);
3654}
3655
3656
3657
3658
3659
3660
3661
3662enum ice_status ice_ptp_init_phc(struct ice_hw *hw)
3663{
3664 u8 src_idx = hw->func_caps.ts_func_info.tmr_index_owned;
3665
3666
3667 wr32(hw, GLTSYN_ENA(src_idx), GLTSYN_ENA_TSYN_ENA_M);
3668
3669
3670 (void)rd32(hw, GLTSYN_STAT(src_idx));
3671
3672 if (ice_is_e810(hw))
3673 return ice_ptp_init_phc_e810(hw);
3674 else
3675 return ice_ptp_init_phc_e822(hw);
3676}
3677