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
112
113static enum ice_status
114ice_read_cgu_reg_e822(struct ice_hw *hw, u16 addr, u32 *val)
115{
116 struct ice_sbq_msg_input cgu_msg;
117 enum ice_status status;
118
119 cgu_msg.opcode = ice_sbq_msg_rd;
120 cgu_msg.dest_dev = cgu;
121 cgu_msg.msg_addr_low = addr;
122 cgu_msg.msg_addr_high = 0x0;
123
124 status = ice_sbq_rw_reg_lp(hw, &cgu_msg, true);
125 if (status) {
126 ice_debug(hw, ICE_DBG_PTP, "Failed to read CGU register 0x%04x, status %d\n",
127 addr, status);
128 return status;
129 }
130
131 *val = cgu_msg.data;
132
133 return ICE_SUCCESS;
134}
135
136
137
138
139
140
141
142
143
144
145static enum ice_status
146ice_write_cgu_reg_e822(struct ice_hw *hw, u16 addr, u32 val)
147{
148 struct ice_sbq_msg_input cgu_msg;
149 enum ice_status status;
150
151 cgu_msg.opcode = ice_sbq_msg_wr;
152 cgu_msg.dest_dev = cgu;
153 cgu_msg.msg_addr_low = addr;
154 cgu_msg.msg_addr_high = 0x0;
155 cgu_msg.data = val;
156
157 status = ice_sbq_rw_reg_lp(hw, &cgu_msg, true);
158 if (status) {
159 ice_debug(hw, ICE_DBG_PTP, "Failed to write CGU register 0x%04x, status %d\n",
160 addr, status);
161 return status;
162 }
163
164 return ICE_SUCCESS;
165}
166
167
168
169
170
171
172
173static const char *ice_clk_freq_str(u8 clk_freq)
174{
175 switch ((enum ice_time_ref_freq)clk_freq) {
176 case ICE_TIME_REF_FREQ_25_000:
177 return "25 MHz";
178 case ICE_TIME_REF_FREQ_122_880:
179 return "122.88 MHz";
180 case ICE_TIME_REF_FREQ_125_000:
181 return "125 MHz";
182 case ICE_TIME_REF_FREQ_153_600:
183 return "153.6 MHz";
184 case ICE_TIME_REF_FREQ_156_250:
185 return "156.25 MHz";
186 case ICE_TIME_REF_FREQ_245_760:
187 return "245.76 MHz";
188 default:
189 return "Unknown";
190 }
191}
192
193
194
195
196
197
198
199static const char *ice_clk_src_str(u8 clk_src)
200{
201 switch ((enum ice_clk_src)clk_src) {
202 case ICE_CLK_SRC_TCX0:
203 return "TCX0";
204 case ICE_CLK_SRC_TIME_REF:
205 return "TIME_REF";
206 default:
207 return "Unknown";
208 }
209}
210
211
212
213
214
215
216
217
218
219
220enum ice_status
221ice_cfg_cgu_pll_e822(struct ice_hw *hw, enum ice_time_ref_freq clk_freq,
222 enum ice_clk_src clk_src)
223{
224 union tspll_ro_bwm_lf bwm_lf;
225 union nac_cgu_dword19 dw19;
226 union nac_cgu_dword22 dw22;
227 union nac_cgu_dword24 dw24;
228 union nac_cgu_dword9 dw9;
229 enum ice_status status;
230
231 if (clk_freq >= NUM_ICE_TIME_REF_FREQ) {
232 ice_warn(hw, "Invalid TIME_REF frequency %u\n", clk_freq);
233 return ICE_ERR_PARAM;
234 }
235
236 if (clk_src >= NUM_ICE_CLK_SRC) {
237 ice_warn(hw, "Invalid clock source %u\n", clk_src);
238 return ICE_ERR_PARAM;
239 }
240
241 if (clk_src == ICE_CLK_SRC_TCX0 &&
242 clk_freq != ICE_TIME_REF_FREQ_25_000) {
243 ice_warn(hw, "TCX0 only supports 25 MHz frequency\n");
244 return ICE_ERR_PARAM;
245 }
246
247 status = ice_read_cgu_reg_e822(hw, NAC_CGU_DWORD9, &dw9.val);
248 if (status)
249 return status;
250
251 status = ice_read_cgu_reg_e822(hw, NAC_CGU_DWORD24, &dw24.val);
252 if (status)
253 return status;
254
255 status = ice_read_cgu_reg_e822(hw, TSPLL_RO_BWM_LF, &bwm_lf.val);
256 if (status)
257 return status;
258
259
260 ice_debug(hw, ICE_DBG_PTP, "Current CGU configuration -- %s, clk_src %s, clk_freq %s, PLL %s\n",
261 dw24.field.ts_pll_enable ? "enabled" : "disabled",
262 ice_clk_src_str(dw24.field.time_ref_sel),
263 ice_clk_freq_str(dw9.field.time_ref_freq_sel),
264 bwm_lf.field.plllock_true_lock_cri ? "locked" : "unlocked");
265
266
267 if (dw24.field.ts_pll_enable) {
268 dw24.field.ts_pll_enable = 0;
269
270 status = ice_write_cgu_reg_e822(hw, NAC_CGU_DWORD24, dw24.val);
271 if (status)
272 return status;
273 }
274
275
276 dw9.field.time_ref_freq_sel = clk_freq;
277 status = ice_write_cgu_reg_e822(hw, NAC_CGU_DWORD9, dw9.val);
278 if (status)
279 return status;
280
281
282 status = ice_read_cgu_reg_e822(hw, NAC_CGU_DWORD19, &dw19.val);
283 if (status)
284 return status;
285
286 dw19.field.tspll_fbdiv_intgr = e822_cgu_params[clk_freq].feedback_div;
287 dw19.field.tspll_ndivratio = 1;
288
289 status = ice_write_cgu_reg_e822(hw, NAC_CGU_DWORD19, dw19.val);
290 if (status)
291 return status;
292
293
294 status = ice_read_cgu_reg_e822(hw, NAC_CGU_DWORD22, &dw22.val);
295 if (status)
296 return status;
297
298 dw22.field.time1588clk_div = e822_cgu_params[clk_freq].post_pll_div;
299 dw22.field.time1588clk_sel_div2 = 0;
300
301 status = ice_write_cgu_reg_e822(hw, NAC_CGU_DWORD22, dw22.val);
302 if (status)
303 return status;
304
305
306 status = ice_read_cgu_reg_e822(hw, NAC_CGU_DWORD24, &dw24.val);
307 if (status)
308 return status;
309
310 dw24.field.ref1588_ck_div = e822_cgu_params[clk_freq].refclk_pre_div;
311 dw24.field.tspll_fbdiv_frac = e822_cgu_params[clk_freq].frac_n_div;
312 dw24.field.time_ref_sel = clk_src;
313
314 status = ice_write_cgu_reg_e822(hw, NAC_CGU_DWORD24, dw24.val);
315 if (status)
316 return status;
317
318
319 dw24.field.ts_pll_enable = 1;
320
321 status = ice_write_cgu_reg_e822(hw, NAC_CGU_DWORD24, dw24.val);
322 if (status)
323 return status;
324
325
326 ice_msec_delay(1, true);
327
328 status = ice_read_cgu_reg_e822(hw, TSPLL_RO_BWM_LF, &bwm_lf.val);
329 if (status)
330 return status;
331
332 if (!bwm_lf.field.plllock_true_lock_cri) {
333 ice_warn(hw, "CGU PLL failed to lock\n");
334 return ICE_ERR_NOT_READY;
335 }
336
337
338 ice_debug(hw, ICE_DBG_PTP, "New CGU configuration -- %s, clk_src %s, clk_freq %s, PLL %s\n",
339 dw24.field.ts_pll_enable ? "enabled" : "disabled",
340 ice_clk_src_str(dw24.field.time_ref_sel),
341 ice_clk_freq_str(dw9.field.time_ref_freq_sel),
342 bwm_lf.field.plllock_true_lock_cri ? "locked" : "unlocked");
343
344 return ICE_SUCCESS;
345}
346
347
348
349
350
351
352
353static enum ice_status ice_init_cgu_e822(struct ice_hw *hw)
354{
355 struct ice_ts_func_info *ts_info = &hw->func_caps.ts_func_info;
356 union tspll_cntr_bist_settings cntr_bist;
357 enum ice_status status;
358
359 status = ice_read_cgu_reg_e822(hw, TSPLL_CNTR_BIST_SETTINGS,
360 &cntr_bist.val);
361 if (status)
362 return status;
363
364
365 cntr_bist.field.i_plllock_sel_0 = 0;
366 cntr_bist.field.i_plllock_sel_1 = 0;
367
368 status = ice_write_cgu_reg_e822(hw, TSPLL_CNTR_BIST_SETTINGS,
369 cntr_bist.val);
370 if (status)
371 return status;
372
373
374
375
376 status = ice_cfg_cgu_pll_e822(hw, ts_info->time_ref,
377 (enum ice_clk_src)ts_info->clk_src);
378 if (status)
379 return status;
380
381 return ICE_SUCCESS;
382}
383
384
385
386
387
388
389
390
391void ice_ptp_src_cmd(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd)
392{
393 u32 cmd_val;
394 u8 tmr_idx;
395
396 tmr_idx = ice_get_ptp_src_clock_index(hw);
397 cmd_val = tmr_idx << SEL_CPK_SRC;
398
399 switch (cmd) {
400 case ICE_PTP_INIT_TIME:
401 cmd_val |= GLTSYN_CMD_INIT_TIME;
402 break;
403 case ICE_PTP_INIT_INCVAL:
404 cmd_val |= GLTSYN_CMD_INIT_INCVAL;
405 break;
406 case ICE_PTP_ADJ_TIME:
407 cmd_val |= GLTSYN_CMD_ADJ_TIME;
408 break;
409 case ICE_PTP_ADJ_TIME_AT_TIME:
410 cmd_val |= GLTSYN_CMD_ADJ_INIT_TIME;
411 break;
412 case ICE_PTP_READ_TIME:
413 cmd_val |= GLTSYN_CMD_READ_TIME;
414 break;
415 case ICE_PTP_NOP:
416 break;
417 default:
418 ice_warn(hw, "Unknown timer command %u\n", cmd);
419 return;
420 }
421
422 wr32(hw, GLTSYN_CMD, cmd_val);
423}
424
425
426
427
428
429
430
431
432
433static void ice_ptp_exec_tmr_cmd(struct ice_hw *hw)
434{
435 wr32(hw, GLTSYN_CMD_SYNC, SYNC_EXEC_CMD);
436 ice_flush(hw);
437}
438
439
440
441
442
443
444
445static void ice_ptp_clean_cmd(struct ice_hw *hw)
446{
447 wr32(hw, GLTSYN_CMD, 0);
448 ice_flush(hw);
449}
450
451
452static const u32 eth56g_port_base[ICE_NUM_PHY_PORTS] = {
453 ICE_PHY0_BASE,
454 ICE_PHY1_BASE,
455 ICE_PHY2_BASE,
456 ICE_PHY3_BASE,
457 ICE_PHY4_BASE,
458};
459
460
461
462
463
464
465
466
467static enum ice_status
468ice_write_phy_eth56g_raw_lp(struct ice_hw *hw, u32 reg_addr, u32 val,
469 bool lock_sbq)
470{
471 struct ice_sbq_msg_input phy_msg;
472 enum ice_status status;
473
474 phy_msg.opcode = ice_sbq_msg_wr;
475
476 phy_msg.msg_addr_low = ICE_LO_WORD(reg_addr);
477 phy_msg.msg_addr_high = ICE_HI_WORD(reg_addr);
478
479 phy_msg.data = val;
480 phy_msg.dest_dev = phy_56g;
481
482 status = ice_sbq_rw_reg_lp(hw, &phy_msg, lock_sbq);
483
484 if (status)
485 ice_debug(hw, ICE_DBG_PTP, "PTP failed to send msg to phy %d\n",
486 status);
487
488 return status;
489}
490
491
492
493
494
495
496
497
498static enum ice_status
499ice_read_phy_eth56g_raw_lp(struct ice_hw *hw, u32 reg_addr, u32 *val,
500 bool lock_sbq)
501{
502 struct ice_sbq_msg_input phy_msg;
503 enum ice_status status;
504
505 phy_msg.opcode = ice_sbq_msg_rd;
506
507 phy_msg.msg_addr_low = ICE_LO_WORD(reg_addr);
508 phy_msg.msg_addr_high = ICE_HI_WORD(reg_addr);
509
510 phy_msg.dest_dev = phy_56g;
511
512 status = ice_sbq_rw_reg_lp(hw, &phy_msg, lock_sbq);
513
514 if (status)
515 ice_debug(hw, ICE_DBG_PTP, "PTP failed to send msg to phy %d\n",
516 status);
517 else
518 *val = phy_msg.data;
519
520 return status;
521}
522
523
524
525
526
527
528
529static enum ice_status
530ice_phy_port_reg_address_eth56g(u8 port, u16 offset, u32 *address)
531{
532 u8 phy, lane;
533
534 if (port >= ICE_NUM_EXTERNAL_PORTS)
535 return ICE_ERR_OUT_OF_RANGE;
536
537 phy = port / ICE_PORTS_PER_QUAD;
538 lane = port % ICE_PORTS_PER_QUAD;
539
540 *address = offset + eth56g_port_base[phy] +
541 PHY_PTP_LANE_ADDR_STEP * lane;
542
543 return ICE_SUCCESS;
544}
545
546
547
548
549
550
551
552static enum ice_status
553ice_phy_port_mem_address_eth56g(u8 port, u16 offset, u32 *address)
554{
555 u8 phy, lane;
556
557 if (port >= ICE_NUM_EXTERNAL_PORTS)
558 return ICE_ERR_OUT_OF_RANGE;
559
560 phy = port / ICE_PORTS_PER_QUAD;
561 lane = port % ICE_PORTS_PER_QUAD;
562
563 *address = offset + eth56g_port_base[phy] +
564 PHY_PTP_MEM_START + PHY_PTP_MEM_LANE_STEP * lane;
565
566 return ICE_SUCCESS;
567}
568
569
570
571
572
573
574
575
576
577static enum ice_status
578ice_write_phy_reg_eth56g_lp(struct ice_hw *hw, u8 port, u16 offset, u32 val,
579 bool lock_sbq)
580{
581 enum ice_status status;
582 u32 reg_addr;
583
584 status = ice_phy_port_reg_address_eth56g(port, offset, ®_addr);
585 if (status)
586 return status;
587
588 return ice_write_phy_eth56g_raw_lp(hw, reg_addr, val, lock_sbq);
589}
590
591
592
593
594
595
596
597
598enum ice_status
599ice_write_phy_reg_eth56g(struct ice_hw *hw, u8 port, u16 offset, u32 val)
600{
601 return ice_write_phy_reg_eth56g_lp(hw, port, offset, val, true);
602}
603
604
605
606
607
608
609
610
611
612
613static enum ice_status
614ice_read_phy_reg_eth56g_lp(struct ice_hw *hw, u8 port, u16 offset, u32 *val,
615 bool lock_sbq)
616{
617 enum ice_status status;
618 u32 reg_addr;
619
620 status = ice_phy_port_reg_address_eth56g(port, offset, ®_addr);
621 if (status)
622 return status;
623
624 return ice_read_phy_eth56g_raw_lp(hw, reg_addr, val, lock_sbq);
625}
626
627
628
629
630
631
632
633
634enum ice_status
635ice_read_phy_reg_eth56g(struct ice_hw *hw, u8 port, u16 offset, u32 *val)
636{
637 return ice_read_phy_reg_eth56g_lp(hw, port, offset, val, true);
638}
639
640
641
642
643
644
645
646
647
648
649static enum ice_status
650ice_phy_port_mem_read_eth56g_lp(struct ice_hw *hw, u8 port, u16 offset,
651 u32 *val, bool lock_sbq)
652{
653 enum ice_status status;
654 u32 mem_addr;
655
656 status = ice_phy_port_mem_address_eth56g(port, offset, &mem_addr);
657 if (status)
658 return status;
659
660 return ice_read_phy_eth56g_raw_lp(hw, mem_addr, val, lock_sbq);
661}
662
663
664
665
666
667
668
669
670
671static enum ice_status
672ice_phy_port_mem_read_eth56g(struct ice_hw *hw, u8 port, u16 offset, u32 *val)
673{
674 return ice_phy_port_mem_read_eth56g_lp(hw, port, offset, val, true);
675}
676
677
678
679
680
681
682
683
684
685
686static enum ice_status
687ice_phy_port_mem_write_eth56g_lp(struct ice_hw *hw, u8 port, u16 offset,
688 u32 val, bool lock_sbq)
689{
690 enum ice_status status;
691 u32 mem_addr;
692
693 status = ice_phy_port_mem_address_eth56g(port, offset, &mem_addr);
694 if (status)
695 return status;
696
697 return ice_write_phy_eth56g_raw_lp(hw, mem_addr, val, lock_sbq);
698}
699
700
701
702
703
704
705
706
707
708static enum ice_status
709ice_phy_port_mem_write_eth56g(struct ice_hw *hw, u8 port, u16 offset, u32 val)
710{
711 return ice_phy_port_mem_write_eth56g_lp(hw, port, offset, val, true);
712}
713
714
715
716
717
718
719
720
721static bool ice_is_64b_phy_reg_eth56g(u16 low_addr)
722{
723 switch (low_addr) {
724 case PHY_REG_TX_TIMER_INC_PRE_L:
725 case PHY_REG_RX_TIMER_INC_PRE_L:
726 case PHY_REG_TX_CAPTURE_L:
727 case PHY_REG_RX_CAPTURE_L:
728 case PHY_REG_TOTAL_TX_OFFSET_L:
729 case PHY_REG_TOTAL_RX_OFFSET_L:
730 return true;
731 default:
732 return false;
733 }
734}
735
736
737
738
739
740
741
742
743
744static bool ice_is_40b_phy_reg_eth56g(u16 low_addr)
745{
746 switch (low_addr) {
747 case PHY_REG_TIMETUS_L:
748 return true;
749 default:
750 return false;
751 }
752}
753
754
755
756
757
758
759
760
761
762
763
764
765
766static enum ice_status
767ice_read_40b_phy_reg_eth56g(struct ice_hw *hw, u8 port, u16 low_addr, u64 *val)
768{
769 u16 high_addr = low_addr + sizeof(u32);
770 enum ice_status status;
771 u32 lo, hi;
772
773 if (!ice_is_40b_phy_reg_eth56g(low_addr))
774 return ICE_ERR_PARAM;
775
776 status = ice_read_phy_reg_eth56g(hw, port, low_addr, &lo);
777 if (status) {
778 ice_debug(hw, ICE_DBG_PTP, "Failed to read from low register %#08x\n, status %d",
779 (int)low_addr, status);
780 return status;
781 }
782
783 status = ice_read_phy_reg_eth56g(hw, port, low_addr + sizeof(u32), &hi);
784 if (status) {
785 ice_debug(hw, ICE_DBG_PTP, "Failed to read from high register %08x\n, status %d",
786 high_addr, status);
787 return status;
788 }
789
790 *val = ((u64)hi << P_REG_40B_HIGH_S) | (lo & P_REG_40B_LOW_M);
791
792 return ICE_SUCCESS;
793}
794
795
796
797
798
799
800
801
802
803
804
805
806
807static enum ice_status
808ice_read_64b_phy_reg_eth56g(struct ice_hw *hw, u8 port, u16 low_addr, u64 *val)
809{
810 u16 high_addr = low_addr + sizeof(u32);
811 enum ice_status status;
812 u32 lo, hi;
813
814 if (!ice_is_64b_phy_reg_eth56g(low_addr))
815 return ICE_ERR_PARAM;
816
817 status = ice_read_phy_reg_eth56g(hw, port, low_addr, &lo);
818 if (status) {
819 ice_debug(hw, ICE_DBG_PTP, "Failed to read from low register %#08x\n, status %d",
820 low_addr, status);
821 return status;
822 }
823
824 status = ice_read_phy_reg_eth56g(hw, port, high_addr, &hi);
825 if (status) {
826 ice_debug(hw, ICE_DBG_PTP, "Failed to read from high register %#08x\n, status %d",
827 high_addr, status);
828 return status;
829 }
830
831 *val = ((u64)hi << 32) | lo;
832
833 return ICE_SUCCESS;
834}
835
836
837
838
839
840
841
842
843
844
845
846
847
848static enum ice_status
849ice_write_40b_phy_reg_eth56g(struct ice_hw *hw, u8 port, u16 low_addr, u64 val)
850{
851 u16 high_addr = low_addr + sizeof(u32);
852 enum ice_status status;
853 u32 lo, hi;
854
855 if (!ice_is_40b_phy_reg_eth56g(low_addr))
856 return ICE_ERR_PARAM;
857
858 lo = (u32)(val & P_REG_40B_LOW_M);
859 hi = (u32)(val >> P_REG_40B_HIGH_S);
860
861 status = ice_write_phy_reg_eth56g(hw, port, low_addr, lo);
862 if (status) {
863 ice_debug(hw, ICE_DBG_PTP, "Failed to write to low register 0x%08x\n, status %d",
864 low_addr, status);
865 return status;
866 }
867
868 status = ice_write_phy_reg_eth56g(hw, port, high_addr, hi);
869 if (status) {
870 ice_debug(hw, ICE_DBG_PTP, "Failed to write to high register 0x%08x\n, status %d",
871 high_addr, status);
872 return status;
873 }
874
875 return ICE_SUCCESS;
876}
877
878
879
880
881
882
883
884
885
886
887
888
889static enum ice_status
890ice_write_64b_phy_reg_eth56g(struct ice_hw *hw, u8 port, u16 low_addr, u64 val)
891{
892 u16 high_addr = low_addr + sizeof(u32);
893 enum ice_status status;
894 u32 lo, hi;
895
896 if (!ice_is_64b_phy_reg_eth56g(low_addr))
897 return ICE_ERR_PARAM;
898
899 lo = ICE_LO_DWORD(val);
900 hi = ICE_HI_DWORD(val);
901
902 status = ice_write_phy_reg_eth56g(hw, port, low_addr, lo);
903 if (status) {
904 ice_debug(hw, ICE_DBG_PTP, "Failed to write to low register 0x%08x\n, status %d",
905 low_addr, status);
906 return status;
907 }
908
909 status = ice_write_phy_reg_eth56g(hw, port, high_addr, hi);
910 if (status) {
911 ice_debug(hw, ICE_DBG_PTP, "Failed to write to high register 0x%08x\n, status %d",
912 high_addr, status);
913 return status;
914 }
915
916 return ICE_SUCCESS;
917}
918
919
920
921
922
923
924
925
926
927
928
929static enum ice_status
930ice_read_phy_tstamp_eth56g(struct ice_hw *hw, u8 port, u8 idx, u64 *tstamp)
931{
932 enum ice_status status;
933 u16 lo_addr, hi_addr;
934 u32 lo, hi;
935
936 lo_addr = (u16)PHY_TSTAMP_L(idx);
937 hi_addr = (u16)PHY_TSTAMP_U(idx);
938
939 status = ice_phy_port_mem_read_eth56g(hw, port, lo_addr, &lo);
940 if (status) {
941 ice_debug(hw, ICE_DBG_PTP, "Failed to read low PTP timestamp register, status %d\n",
942 status);
943 return status;
944 }
945
946 status = ice_phy_port_mem_read_eth56g(hw, port, hi_addr, &hi);
947 if (status) {
948 ice_debug(hw, ICE_DBG_PTP, "Failed to read high PTP timestamp register, status %d\n",
949 status);
950 return status;
951 }
952
953
954
955
956
957 *tstamp = ((u64)hi) << TS_PHY_HIGH_S | ((u64)lo & TS_PHY_LOW_M);
958
959 return ICE_SUCCESS;
960}
961
962
963
964
965
966
967
968
969
970
971static enum ice_status
972ice_clear_phy_tstamp_eth56g(struct ice_hw *hw, u8 port, u8 idx)
973{
974 enum ice_status status;
975 u16 lo_addr;
976
977 lo_addr = (u16)PHY_TSTAMP_L(idx);
978
979 status = ice_phy_port_mem_write_eth56g(hw, port, lo_addr, 0);
980 if (status) {
981 ice_debug(hw, ICE_DBG_PTP, "Failed to clear low PTP timestamp register, status %d\n",
982 status);
983 return status;
984 }
985
986 return ICE_SUCCESS;
987}
988
989
990
991
992
993
994
995
996
997static enum ice_status
998ice_ptp_prep_port_phy_time_eth56g(struct ice_hw *hw, u8 port, u64 phy_time)
999{
1000 enum ice_status status;
1001
1002
1003 status = ice_write_64b_phy_reg_eth56g(hw, port,
1004 PHY_REG_TX_TIMER_INC_PRE_L,
1005 phy_time);
1006 if (status)
1007 return status;
1008
1009
1010 return ice_write_64b_phy_reg_eth56g(hw, port,
1011 PHY_REG_RX_TIMER_INC_PRE_L,
1012 phy_time);
1013}
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025static enum ice_status
1026ice_ptp_prep_phy_time_eth56g(struct ice_hw *hw, u32 time)
1027{
1028 enum ice_status status;
1029 u64 phy_time;
1030 u8 port;
1031
1032
1033
1034
1035 phy_time = (u64)time << 32;
1036
1037 for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
1038 if (!(hw->ena_lports & BIT(port)))
1039 continue;
1040 status = ice_ptp_prep_port_phy_time_eth56g(hw, port,
1041 phy_time);
1042
1043 if (status) {
1044 ice_debug(hw, ICE_DBG_PTP, "Failed to write init time for port %u, status %d\n",
1045 port, status);
1046 return status;
1047 }
1048 }
1049
1050 return ICE_SUCCESS;
1051}
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070enum ice_status
1071ice_ptp_prep_port_adj_eth56g(struct ice_hw *hw, u8 port, s64 time,
1072 bool lock_sbq)
1073{
1074 enum ice_status status;
1075 u32 l_time, u_time;
1076
1077 l_time = ICE_LO_DWORD(time);
1078 u_time = ICE_HI_DWORD(time);
1079
1080
1081 status = ice_write_phy_reg_eth56g_lp(hw, port,
1082 PHY_REG_TX_TIMER_INC_PRE_L,
1083 l_time, lock_sbq);
1084 if (status)
1085 goto exit_err;
1086
1087 status = ice_write_phy_reg_eth56g_lp(hw, port,
1088 PHY_REG_TX_TIMER_INC_PRE_U,
1089 u_time, lock_sbq);
1090 if (status)
1091 goto exit_err;
1092
1093
1094 status = ice_write_phy_reg_eth56g_lp(hw, port,
1095 PHY_REG_RX_TIMER_INC_PRE_L,
1096 l_time, lock_sbq);
1097 if (status)
1098 goto exit_err;
1099
1100 status = ice_write_phy_reg_eth56g_lp(hw, port,
1101 PHY_REG_RX_TIMER_INC_PRE_U,
1102 u_time, lock_sbq);
1103 if (status)
1104 goto exit_err;
1105
1106 return ICE_SUCCESS;
1107
1108exit_err:
1109 ice_debug(hw, ICE_DBG_PTP, "Failed to write time adjust for port %u, status %d\n",
1110 port, status);
1111 return status;
1112}
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125static enum ice_status
1126ice_ptp_prep_phy_adj_eth56g(struct ice_hw *hw, s32 adj, bool lock_sbq)
1127{
1128 enum ice_status status = ICE_SUCCESS;
1129 s64 cycles;
1130 u8 port;
1131
1132
1133
1134
1135
1136 cycles = (s64)adj << 32;
1137
1138 for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
1139 if (!(hw->ena_lports & BIT(port)))
1140 continue;
1141
1142 status = ice_ptp_prep_port_adj_eth56g(hw, port, cycles,
1143 lock_sbq);
1144 if (status)
1145 break;
1146 }
1147
1148 return status;
1149}
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160static enum ice_status
1161ice_ptp_prep_phy_incval_eth56g(struct ice_hw *hw, u64 incval)
1162{
1163 enum ice_status status;
1164 u8 port;
1165
1166 for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
1167 if (!(hw->ena_lports & BIT(port)))
1168 continue;
1169 status = ice_write_40b_phy_reg_eth56g(hw, port,
1170 PHY_REG_TIMETUS_L,
1171 incval);
1172 if (status) {
1173 ice_debug(hw, ICE_DBG_PTP, "Failed to write incval for port %u, status %d\n",
1174 port, status);
1175 return status;
1176 }
1177 }
1178
1179 return ICE_SUCCESS;
1180}
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190enum ice_status
1191ice_ptp_read_phy_incval_eth56g(struct ice_hw *hw, u8 port, u64 *incval)
1192{
1193 enum ice_status status;
1194
1195 status = ice_read_40b_phy_reg_eth56g(hw, port, PHY_REG_TIMETUS_L,
1196 incval);
1197 if (status) {
1198 ice_debug(hw, ICE_DBG_PTP, "Failed to read TIMETUS_L, status %d\n",
1199 status);
1200 return status;
1201 }
1202
1203 ice_debug(hw, ICE_DBG_PTP, "read INCVAL = 0x%016llx\n",
1204 (unsigned long long)*incval);
1205
1206 return ICE_SUCCESS;
1207}
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222static enum ice_status
1223ice_ptp_prep_phy_adj_target_eth56g(struct ice_hw *hw, u32 target_time)
1224{
1225 enum ice_status status;
1226 u8 port;
1227
1228 for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
1229 if (!(hw->ena_lports & BIT(port)))
1230 continue;
1231
1232
1233
1234 status = ice_write_phy_reg_eth56g_lp(hw, port,
1235 PHY_REG_TX_TIMER_CNT_ADJ_L,
1236 0, true);
1237 if (status)
1238 goto exit_err;
1239
1240 status = ice_write_phy_reg_eth56g_lp(hw, port,
1241 PHY_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_eth56g_lp(hw, port,
1249 PHY_REG_RX_TIMER_CNT_ADJ_L,
1250 0, true);
1251 if (status)
1252 goto exit_err;
1253
1254 status = ice_write_phy_reg_eth56g_lp(hw, port,
1255 PHY_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
1279enum ice_status
1280ice_ptp_read_port_capture_eth56g(struct ice_hw *hw, u8 port, u64 *tx_ts,
1281 u64 *rx_ts)
1282{
1283 enum ice_status status;
1284
1285
1286 status = ice_read_64b_phy_reg_eth56g(hw, port, PHY_REG_TX_CAPTURE_L,
1287 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 = %#016llx\n",
1295 (unsigned long long)*tx_ts);
1296
1297
1298 status = ice_read_64b_phy_reg_eth56g(hw, port, PHY_REG_RX_CAPTURE_L,
1299 rx_ts);
1300 if (status) {
1301 ice_debug(hw, ICE_DBG_PTP, "Failed to read RX_CAPTURE, status %d\n",
1302 status);
1303 return status;
1304 }
1305
1306 ice_debug(hw, ICE_DBG_PTP, "rx_init = %#016llx\n",
1307 (unsigned long long)*rx_ts);
1308
1309 return ICE_SUCCESS;
1310}
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321enum ice_status
1322ice_ptp_one_port_cmd_eth56g(struct ice_hw *hw, u8 port,
1323 enum ice_ptp_tmr_cmd cmd, bool lock_sbq)
1324{
1325 enum ice_status status;
1326 u32 cmd_val, val;
1327 u8 tmr_idx;
1328
1329 tmr_idx = ice_get_ptp_src_clock_index(hw);
1330 cmd_val = tmr_idx << SEL_PHY_SRC;
1331 switch (cmd) {
1332 case ICE_PTP_INIT_TIME:
1333 cmd_val |= PHY_CMD_INIT_TIME;
1334 break;
1335 case ICE_PTP_INIT_INCVAL:
1336 cmd_val |= PHY_CMD_INIT_INCVAL;
1337 break;
1338 case ICE_PTP_ADJ_TIME:
1339 cmd_val |= PHY_CMD_ADJ_TIME;
1340 break;
1341 case ICE_PTP_ADJ_TIME_AT_TIME:
1342 cmd_val |= PHY_CMD_ADJ_TIME_AT_TIME;
1343 break;
1344 case ICE_PTP_READ_TIME:
1345 cmd_val |= PHY_CMD_READ_TIME;
1346 break;
1347 default:
1348 ice_warn(hw, "Unknown timer command %u\n", cmd);
1349 return ICE_ERR_PARAM;
1350 }
1351
1352
1353
1354 status = ice_read_phy_reg_eth56g_lp(hw, port, PHY_REG_TX_TMR_CMD, &val,
1355 lock_sbq);
1356 if (status) {
1357 ice_debug(hw, ICE_DBG_PTP, "Failed to read TX_TMR_CMD, status %d\n",
1358 status);
1359 return status;
1360 }
1361
1362
1363 val &= ~TS_CMD_MASK;
1364 val |= cmd_val;
1365
1366 status = ice_write_phy_reg_eth56g_lp(hw, port, PHY_REG_TX_TMR_CMD, val,
1367 lock_sbq);
1368 if (status) {
1369 ice_debug(hw, ICE_DBG_PTP, "Failed to write back TX_TMR_CMD, status %d\n",
1370 status);
1371 return status;
1372 }
1373
1374
1375
1376 status = ice_read_phy_reg_eth56g_lp(hw, port, PHY_REG_RX_TMR_CMD, &val,
1377 lock_sbq);
1378 if (status) {
1379 ice_debug(hw, ICE_DBG_PTP, "Failed to read RX_TMR_CMD, status %d\n",
1380 status);
1381 return status;
1382 }
1383
1384
1385 val &= ~TS_CMD_MASK;
1386 val |= cmd_val;
1387
1388 status = ice_write_phy_reg_eth56g_lp(hw, port, PHY_REG_RX_TMR_CMD, val,
1389 lock_sbq);
1390 if (status) {
1391 ice_debug(hw, ICE_DBG_PTP, "Failed to write back RX_TMR_CMD, status %d\n",
1392 status);
1393 return status;
1394 }
1395
1396 return ICE_SUCCESS;
1397}
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408static enum ice_status
1409ice_ptp_port_cmd_eth56g(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd,
1410 bool lock_sbq)
1411{
1412 enum ice_status status;
1413 u8 port;
1414
1415 for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
1416 if (!(hw->ena_lports & BIT(port)))
1417 continue;
1418
1419 status = ice_ptp_one_port_cmd_eth56g(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
1434static u64
1435ice_calc_fixed_tx_offset_eth56g(struct ice_hw *hw,
1436 enum ice_ptp_link_spd link_spd)
1437{
1438 u64 fixed_offset = 0;
1439 return fixed_offset;
1440}
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455enum ice_status ice_phy_cfg_tx_offset_eth56g(struct ice_hw *hw, u8 port)
1456{
1457 enum ice_ptp_link_spd link_spd = ICE_PTP_LNK_SPD_10G;
1458 enum ice_status status;
1459 u64 total_offset;
1460
1461 total_offset = ice_calc_fixed_tx_offset_eth56g(hw, link_spd);
1462
1463
1464
1465
1466
1467 status = ice_write_64b_phy_reg_eth56g(hw, port,
1468 PHY_REG_TOTAL_TX_OFFSET_L,
1469 total_offset);
1470 if (status)
1471 return status;
1472
1473 return ice_write_phy_reg_eth56g(hw, port, PHY_REG_TX_OFFSET_READY, 1);
1474}
1475
1476
1477
1478
1479
1480
1481
1482
1483static u64
1484ice_calc_fixed_rx_offset_eth56g(struct ice_hw *hw,
1485 enum ice_ptp_link_spd link_spd)
1486{
1487 u64 fixed_offset = 0;
1488 return fixed_offset;
1489}
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510enum ice_status ice_phy_cfg_rx_offset_eth56g(struct ice_hw *hw, u8 port)
1511{
1512 enum ice_status status;
1513 u64 total_offset;
1514
1515 total_offset = ice_calc_fixed_rx_offset_eth56g(hw, 0);
1516
1517
1518
1519
1520
1521 status = ice_write_64b_phy_reg_eth56g(hw, port,
1522 PHY_REG_TOTAL_RX_OFFSET_L,
1523 total_offset);
1524 if (status)
1525 return status;
1526
1527 return ice_write_phy_reg_eth56g(hw, port, PHY_REG_RX_OFFSET_READY, 1);
1528}
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540static enum ice_status
1541ice_read_phy_and_phc_time_eth56g(struct ice_hw *hw, u8 port, u64 *phy_time,
1542 u64 *phc_time)
1543{
1544 enum ice_status status;
1545 u64 tx_time, rx_time;
1546 u32 zo, lo;
1547 u8 tmr_idx;
1548
1549 tmr_idx = ice_get_ptp_src_clock_index(hw);
1550
1551
1552 ice_ptp_src_cmd(hw, ICE_PTP_READ_TIME);
1553
1554
1555 status = ice_ptp_one_port_cmd_eth56g(hw, port, ICE_PTP_READ_TIME, true);
1556 if (status)
1557 return status;
1558
1559
1560 ice_ptp_exec_tmr_cmd(hw);
1561 ice_ptp_clean_cmd(hw);
1562
1563
1564 zo = rd32(hw, GLTSYN_SHTIME_0(tmr_idx));
1565 lo = rd32(hw, GLTSYN_SHTIME_L(tmr_idx));
1566 *phc_time = (u64)lo << 32 | zo;
1567
1568
1569 status = ice_ptp_read_port_capture_eth56g(hw, port, &tx_time, &rx_time);
1570 if (status)
1571 return status;
1572
1573
1574
1575
1576
1577 if (tx_time != rx_time)
1578 ice_warn(hw, "PHY port %u Tx and Rx timers do not match, tx_time 0x%016llX, rx_time 0x%016llX\n",
1579 port, (unsigned long long)tx_time,
1580 (unsigned long long)rx_time);
1581
1582 *phy_time = tx_time;
1583
1584 return ICE_SUCCESS;
1585}
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599static enum ice_status ice_sync_phy_timer_eth56g(struct ice_hw *hw, u8 port)
1600{
1601 u64 phc_time, phy_time, difference;
1602 enum ice_status status;
1603
1604 if (!ice_ptp_lock(hw)) {
1605 ice_debug(hw, ICE_DBG_PTP, "Failed to acquire PTP semaphore\n");
1606 return ICE_ERR_NOT_READY;
1607 }
1608
1609 status = ice_read_phy_and_phc_time_eth56g(hw, port, &phy_time,
1610 &phc_time);
1611 if (status)
1612 goto err_unlock;
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623 ice_ptp_src_cmd(hw, ICE_PTP_NOP);
1624 difference = phc_time - phy_time;
1625
1626 status = ice_ptp_prep_port_adj_eth56g(hw, port, (s64)difference, true);
1627 if (status)
1628 goto err_unlock;
1629
1630 status = ice_ptp_one_port_cmd_eth56g(hw, port, ICE_PTP_ADJ_TIME, true);
1631 if (status)
1632 goto err_unlock;
1633
1634
1635 ice_ptp_exec_tmr_cmd(hw);
1636 ice_ptp_clean_cmd(hw);
1637
1638
1639
1640
1641
1642 status = ice_read_phy_and_phc_time_eth56g(hw, port, &phy_time,
1643 &phc_time);
1644 if (status)
1645 goto err_unlock;
1646
1647 ice_info(hw, "Port %u PHY time synced to PHC: 0x%016llX, 0x%016llX\n",
1648 port, (unsigned long long)phy_time,
1649 (unsigned long long)phc_time);
1650
1651err_unlock:
1652 ice_ptp_unlock(hw);
1653 return status;
1654}
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666enum ice_status
1667ice_stop_phy_timer_eth56g(struct ice_hw *hw, u8 port, bool soft_reset)
1668{
1669 enum ice_status status;
1670
1671 status = ice_write_phy_reg_eth56g(hw, port, PHY_REG_TX_OFFSET_READY, 0);
1672 if (status)
1673 return status;
1674
1675 status = ice_write_phy_reg_eth56g(hw, port, PHY_REG_RX_OFFSET_READY, 0);
1676 if (status)
1677 return status;
1678
1679 ice_debug(hw, ICE_DBG_PTP, "Disabled clock on PHY port %u\n", port);
1680
1681 return ICE_SUCCESS;
1682}
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695enum ice_status
1696ice_start_phy_timer_eth56g(struct ice_hw *hw, u8 port, bool bypass)
1697{
1698 enum ice_status status;
1699 u32 lo, hi;
1700 u64 incval;
1701 u8 tmr_idx;
1702
1703 tmr_idx = ice_get_ptp_src_clock_index(hw);
1704
1705 status = ice_stop_phy_timer_eth56g(hw, port, false);
1706 if (status)
1707 return status;
1708
1709 ice_ptp_src_cmd(hw, ICE_PTP_NOP);
1710
1711 lo = rd32(hw, GLTSYN_INCVAL_L(tmr_idx));
1712 hi = rd32(hw, GLTSYN_INCVAL_H(tmr_idx));
1713 incval = (u64)hi << 32 | lo;
1714
1715 status = ice_write_40b_phy_reg_eth56g(hw, port, PHY_REG_TIMETUS_L,
1716 incval);
1717 if (status)
1718 return status;
1719
1720 status = ice_ptp_one_port_cmd_eth56g(hw, port, ICE_PTP_INIT_INCVAL,
1721 true);
1722 if (status)
1723 return status;
1724
1725 ice_ptp_exec_tmr_cmd(hw);
1726
1727 status = ice_sync_phy_timer_eth56g(hw, port);
1728 if (status)
1729 return status;
1730
1731
1732 status = ice_phy_cfg_tx_offset_eth56g(hw, port);
1733 if (status)
1734 return status;
1735
1736
1737 status = ice_phy_cfg_rx_offset_eth56g(hw, port);
1738 if (status)
1739 return status;
1740
1741 ice_debug(hw, ICE_DBG_PTP, "Enabled clock on PHY port %u\n", port);
1742
1743 return ICE_SUCCESS;
1744}
1745
1746
1747
1748
1749
1750
1751
1752static enum ice_status ice_ptp_init_phc_eth56g(struct ice_hw *hw)
1753{
1754 enum ice_status status = ICE_SUCCESS;
1755 u32 regval;
1756
1757
1758#define PF_SB_REM_DEV_CTL_SWITCH_READ BIT(1)
1759#define PF_SB_REM_DEV_CTL_PHY0 BIT(2)
1760 regval = rd32(hw, PF_SB_REM_DEV_CTL);
1761 regval |= (PF_SB_REM_DEV_CTL_SWITCH_READ |
1762 PF_SB_REM_DEV_CTL_PHY0);
1763 wr32(hw, PF_SB_REM_DEV_CTL, regval);
1764
1765
1766 status = ice_init_cgu_e822(hw);
1767
1768 return status;
1769}
1770
1771
1772
1773
1774
1775
1776
1777enum ice_status
1778ice_ptp_read_tx_hwtstamp_status_eth56g(struct ice_hw *hw, u32 *ts_status)
1779{
1780 enum ice_status status;
1781
1782 status = ice_read_phy_eth56g_raw_lp(hw, PHY_PTP_INT_STATUS, ts_status,
1783 true);
1784 if (status)
1785 return status;
1786
1787 ice_debug(hw, ICE_DBG_PTP, "PHY interrupt status: %x\n", *ts_status);
1788
1789 return ICE_SUCCESS;
1790}
1791
1792
1793
1794
1795
1796
1797enum ice_status
1798ice_ptp_init_phy_cfg(struct ice_hw *hw)
1799{
1800 enum ice_status status;
1801 u32 phy_rev;
1802
1803 status = ice_read_phy_eth56g_raw_lp(hw, PHY_REG_REVISION, &phy_rev,
1804 true);
1805 if (status)
1806 return status;
1807
1808 if (phy_rev == PHY_REVISION_ETH56G) {
1809 hw->phy_cfg = ICE_PHY_ETH56G;
1810 return ICE_SUCCESS;
1811 }
1812
1813 if (ice_is_e810(hw))
1814 hw->phy_cfg = ICE_PHY_E810;
1815 else
1816 hw->phy_cfg = ICE_PHY_E822;
1817
1818 return ICE_SUCCESS;
1819}
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833static void
1834ice_fill_phy_msg_e822(struct ice_sbq_msg_input *msg, u8 port, u16 offset)
1835{
1836 int phy_port, phy, quadtype;
1837
1838 phy_port = port % ICE_PORTS_PER_PHY_E822;
1839 phy = port / ICE_PORTS_PER_PHY_E822;
1840 quadtype = (port / ICE_PORTS_PER_QUAD) % ICE_QUADS_PER_PHY_E822;
1841
1842 if (quadtype == 0) {
1843 msg->msg_addr_low = P_Q0_L(P_0_BASE + offset, phy_port);
1844 msg->msg_addr_high = P_Q0_H(P_0_BASE + offset, phy_port);
1845 } else {
1846 msg->msg_addr_low = P_Q1_L(P_4_BASE + offset, phy_port);
1847 msg->msg_addr_high = P_Q1_H(P_4_BASE + offset, phy_port);
1848 }
1849
1850 if (phy == 0)
1851 msg->dest_dev = rmn_0;
1852 else if (phy == 1)
1853 msg->dest_dev = rmn_1;
1854 else
1855 msg->dest_dev = rmn_2;
1856}
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867static bool ice_is_64b_phy_reg_e822(u16 low_addr, u16 *high_addr)
1868{
1869 switch (low_addr) {
1870 case P_REG_PAR_PCS_TX_OFFSET_L:
1871 *high_addr = P_REG_PAR_PCS_TX_OFFSET_U;
1872 return true;
1873 case P_REG_PAR_PCS_RX_OFFSET_L:
1874 *high_addr = P_REG_PAR_PCS_RX_OFFSET_U;
1875 return true;
1876 case P_REG_PAR_TX_TIME_L:
1877 *high_addr = P_REG_PAR_TX_TIME_U;
1878 return true;
1879 case P_REG_PAR_RX_TIME_L:
1880 *high_addr = P_REG_PAR_RX_TIME_U;
1881 return true;
1882 case P_REG_TOTAL_TX_OFFSET_L:
1883 *high_addr = P_REG_TOTAL_TX_OFFSET_U;
1884 return true;
1885 case P_REG_TOTAL_RX_OFFSET_L:
1886 *high_addr = P_REG_TOTAL_RX_OFFSET_U;
1887 return true;
1888 case P_REG_UIX66_10G_40G_L:
1889 *high_addr = P_REG_UIX66_10G_40G_U;
1890 return true;
1891 case P_REG_UIX66_25G_100G_L:
1892 *high_addr = P_REG_UIX66_25G_100G_U;
1893 return true;
1894 case P_REG_TX_CAPTURE_L:
1895 *high_addr = P_REG_TX_CAPTURE_U;
1896 return true;
1897 case P_REG_RX_CAPTURE_L:
1898 *high_addr = P_REG_RX_CAPTURE_U;
1899 return true;
1900 case P_REG_TX_TIMER_INC_PRE_L:
1901 *high_addr = P_REG_TX_TIMER_INC_PRE_U;
1902 return true;
1903 case P_REG_RX_TIMER_INC_PRE_L:
1904 *high_addr = P_REG_RX_TIMER_INC_PRE_U;
1905 return true;
1906 default:
1907 return false;
1908 }
1909}
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921static bool ice_is_40b_phy_reg_e822(u16 low_addr, u16 *high_addr)
1922{
1923 switch (low_addr) {
1924 case P_REG_TIMETUS_L:
1925 *high_addr = P_REG_TIMETUS_U;
1926 return true;
1927 case P_REG_PAR_RX_TUS_L:
1928 *high_addr = P_REG_PAR_RX_TUS_U;
1929 return true;
1930 case P_REG_PAR_TX_TUS_L:
1931 *high_addr = P_REG_PAR_TX_TUS_U;
1932 return true;
1933 case P_REG_PCS_RX_TUS_L:
1934 *high_addr = P_REG_PCS_RX_TUS_U;
1935 return true;
1936 case P_REG_PCS_TX_TUS_L:
1937 *high_addr = P_REG_PCS_TX_TUS_U;
1938 return true;
1939 case P_REG_DESK_PAR_RX_TUS_L:
1940 *high_addr = P_REG_DESK_PAR_RX_TUS_U;
1941 return true;
1942 case P_REG_DESK_PAR_TX_TUS_L:
1943 *high_addr = P_REG_DESK_PAR_TX_TUS_U;
1944 return true;
1945 case P_REG_DESK_PCS_RX_TUS_L:
1946 *high_addr = P_REG_DESK_PCS_RX_TUS_U;
1947 return true;
1948 case P_REG_DESK_PCS_TX_TUS_L:
1949 *high_addr = P_REG_DESK_PCS_TX_TUS_U;
1950 return true;
1951 default:
1952 return false;
1953 }
1954}
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966static enum ice_status
1967ice_read_phy_reg_e822_lp(struct ice_hw *hw, u8 port, u16 offset, u32 *val,
1968 bool lock_sbq)
1969{
1970 struct ice_sbq_msg_input msg = {0};
1971 enum ice_status status;
1972
1973 ice_fill_phy_msg_e822(&msg, port, offset);
1974 msg.opcode = ice_sbq_msg_rd;
1975
1976 status = ice_sbq_rw_reg_lp(hw, &msg, lock_sbq);
1977 if (status) {
1978 ice_debug(hw, ICE_DBG_PTP, "Failed to send message to phy, status %d\n",
1979 status);
1980 return status;
1981 }
1982
1983 *val = msg.data;
1984
1985 return ICE_SUCCESS;
1986}
1987
1988enum ice_status
1989ice_read_phy_reg_e822(struct ice_hw *hw, u8 port, u16 offset, u32 *val)
1990{
1991 return ice_read_phy_reg_e822_lp(hw, port, offset, val, true);
1992}
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006static enum ice_status
2007ice_read_40b_phy_reg_e822(struct ice_hw *hw, u8 port, u16 low_addr, u64 *val)
2008{
2009 enum ice_status status;
2010 u32 low, high;
2011 u16 high_addr;
2012
2013
2014
2015
2016 if (!ice_is_40b_phy_reg_e822(low_addr, &high_addr)) {
2017 ice_debug(hw, ICE_DBG_PTP, "Invalid 64b register addr 0x%08x\n",
2018 low_addr);
2019 return ICE_ERR_PARAM;
2020 }
2021
2022 status = ice_read_phy_reg_e822(hw, port, low_addr, &low);
2023 if (status) {
2024 ice_debug(hw, ICE_DBG_PTP, "Failed to read from low register 0x%08x\n, status %d",
2025 low_addr, status);
2026 return status;
2027 }
2028
2029 status = ice_read_phy_reg_e822(hw, port, high_addr, &high);
2030 if (status) {
2031 ice_debug(hw, ICE_DBG_PTP, "Failed to read from high register 0x%08x\n, status %d",
2032 high_addr, status);
2033 return status;
2034 }
2035
2036 *val = (u64)high << P_REG_40B_HIGH_S | (low & P_REG_40B_LOW_M);
2037
2038 return ICE_SUCCESS;
2039}
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053static enum ice_status
2054ice_read_64b_phy_reg_e822(struct ice_hw *hw, u8 port, u16 low_addr, u64 *val)
2055{
2056 enum ice_status status;
2057 u32 low, high;
2058 u16 high_addr;
2059
2060
2061
2062
2063 if (!ice_is_64b_phy_reg_e822(low_addr, &high_addr)) {
2064 ice_debug(hw, ICE_DBG_PTP, "Invalid 64b register addr 0x%08x\n",
2065 low_addr);
2066 return ICE_ERR_PARAM;
2067 }
2068
2069 status = ice_read_phy_reg_e822(hw, port, low_addr, &low);
2070 if (status) {
2071 ice_debug(hw, ICE_DBG_PTP, "Failed to read from low register 0x%08x\n, status %d",
2072 low_addr, status);
2073 return status;
2074 }
2075
2076 status = ice_read_phy_reg_e822(hw, port, high_addr, &high);
2077 if (status) {
2078 ice_debug(hw, ICE_DBG_PTP, "Failed to read from high register 0x%08x\n, status %d",
2079 high_addr, status);
2080 return status;
2081 }
2082
2083 *val = (u64)high << 32 | low;
2084
2085 return ICE_SUCCESS;
2086}
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098static enum ice_status
2099ice_write_phy_reg_e822_lp(struct ice_hw *hw, u8 port, u16 offset, u32 val,
2100 bool lock_sbq)
2101{
2102 struct ice_sbq_msg_input msg = {0};
2103 enum ice_status status;
2104
2105 ice_fill_phy_msg_e822(&msg, port, offset);
2106 msg.opcode = ice_sbq_msg_wr;
2107 msg.data = val;
2108
2109 status = ice_sbq_rw_reg_lp(hw, &msg, lock_sbq);
2110 if (status) {
2111 ice_debug(hw, ICE_DBG_PTP, "Failed to send message to phy, status %d\n",
2112 status);
2113 return status;
2114 }
2115
2116 return ICE_SUCCESS;
2117}
2118
2119enum ice_status
2120ice_write_phy_reg_e822(struct ice_hw *hw, u8 port, u16 offset, u32 val)
2121{
2122 return ice_write_phy_reg_e822_lp(hw, port, offset, val, true);
2123}
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135static enum ice_status
2136ice_write_40b_phy_reg_e822(struct ice_hw *hw, u8 port, u16 low_addr, u64 val)
2137{
2138 enum ice_status status;
2139 u32 low, high;
2140 u16 high_addr;
2141
2142
2143
2144
2145 if (!ice_is_40b_phy_reg_e822(low_addr, &high_addr)) {
2146 ice_debug(hw, ICE_DBG_PTP, "Invalid 40b register addr 0x%08x\n",
2147 low_addr);
2148 return ICE_ERR_PARAM;
2149 }
2150
2151 low = (u32)(val & P_REG_40B_LOW_M);
2152 high = (u32)(val >> P_REG_40B_HIGH_S);
2153
2154 status = ice_write_phy_reg_e822(hw, port, low_addr, low);
2155 if (status) {
2156 ice_debug(hw, ICE_DBG_PTP, "Failed to write to low register 0x%08x\n, status %d",
2157 low_addr, status);
2158 return status;
2159 }
2160
2161 status = ice_write_phy_reg_e822(hw, port, high_addr, high);
2162 if (status) {
2163 ice_debug(hw, ICE_DBG_PTP, "Failed to write to high register 0x%08x\n, status %d",
2164 high_addr, status);
2165 return status;
2166 }
2167
2168 return ICE_SUCCESS;
2169}
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183static enum ice_status
2184ice_write_64b_phy_reg_e822(struct ice_hw *hw, u8 port, u16 low_addr, u64 val)
2185{
2186 enum ice_status status;
2187 u32 low, high;
2188 u16 high_addr;
2189
2190
2191
2192
2193 if (!ice_is_64b_phy_reg_e822(low_addr, &high_addr)) {
2194 ice_debug(hw, ICE_DBG_PTP, "Invalid 64b register addr 0x%08x\n",
2195 low_addr);
2196 return ICE_ERR_PARAM;
2197 }
2198
2199 low = ICE_LO_DWORD(val);
2200 high = ICE_HI_DWORD(val);
2201
2202 status = ice_write_phy_reg_e822(hw, port, low_addr, low);
2203 if (status) {
2204 ice_debug(hw, ICE_DBG_PTP, "Failed to write to low register 0x%08x\n, status %d",
2205 low_addr, status);
2206 return status;
2207 }
2208
2209 status = ice_write_phy_reg_e822(hw, port, high_addr, high);
2210 if (status) {
2211 ice_debug(hw, ICE_DBG_PTP, "Failed to write to high register 0x%08x\n, status %d",
2212 high_addr, status);
2213 return status;
2214 }
2215
2216 return ICE_SUCCESS;
2217}
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228static enum ice_status
2229ice_fill_quad_msg_e822(struct ice_sbq_msg_input *msg, u8 quad, u16 offset)
2230{
2231 u32 addr;
2232
2233 if (quad >= ICE_MAX_QUAD)
2234 return ICE_ERR_PARAM;
2235
2236 msg->dest_dev = rmn_0;
2237
2238 if ((quad % ICE_QUADS_PER_PHY_E822) == 0)
2239 addr = Q_0_BASE + offset;
2240 else
2241 addr = Q_1_BASE + offset;
2242
2243 msg->msg_addr_low = ICE_LO_WORD(addr);
2244 msg->msg_addr_high = ICE_HI_WORD(addr);
2245
2246 return ICE_SUCCESS;
2247}
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260static enum ice_status
2261ice_read_quad_reg_e822_lp(struct ice_hw *hw, u8 quad, u16 offset, u32 *val,
2262 bool lock_sbq)
2263{
2264 struct ice_sbq_msg_input msg = {0};
2265 enum ice_status status;
2266
2267 status = ice_fill_quad_msg_e822(&msg, quad, offset);
2268 if (status)
2269 goto exit_err;
2270
2271 msg.opcode = ice_sbq_msg_rd;
2272
2273 status = ice_sbq_rw_reg_lp(hw, &msg, lock_sbq);
2274exit_err:
2275 if (status)
2276 ice_debug(hw, ICE_DBG_PTP, "Failed to send message to phy, status %d\n",
2277 status);
2278 else
2279 *val = msg.data;
2280
2281 return status;
2282}
2283
2284enum ice_status
2285ice_read_quad_reg_e822(struct ice_hw *hw, u8 quad, u16 offset, u32 *val)
2286{
2287 return ice_read_quad_reg_e822_lp(hw, quad, offset, val, true);
2288}
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301static enum ice_status
2302ice_write_quad_reg_e822_lp(struct ice_hw *hw, u8 quad, u16 offset, u32 val,
2303 bool lock_sbq)
2304{
2305 struct ice_sbq_msg_input msg = {0};
2306 enum ice_status status;
2307
2308 status = ice_fill_quad_msg_e822(&msg, quad, offset);
2309 if (status)
2310 goto exit_err;
2311
2312 msg.opcode = ice_sbq_msg_wr;
2313 msg.data = val;
2314
2315 status = ice_sbq_rw_reg_lp(hw, &msg, lock_sbq);
2316exit_err:
2317 if (status)
2318 ice_debug(hw, ICE_DBG_PTP, "Failed to send message to phy, status %d\n",
2319 status);
2320
2321 return status;
2322}
2323
2324enum ice_status
2325ice_write_quad_reg_e822(struct ice_hw *hw, u8 quad, u16 offset, u32 val)
2326{
2327 return ice_write_quad_reg_e822_lp(hw, quad, offset, val, true);
2328}
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341static enum ice_status
2342ice_read_phy_tstamp_e822(struct ice_hw *hw, u8 quad, u8 idx, u64 *tstamp)
2343{
2344 enum ice_status status;
2345 u16 lo_addr, hi_addr;
2346 u32 lo, hi;
2347
2348 lo_addr = (u16)TS_L(Q_REG_TX_MEMORY_BANK_START, idx);
2349 hi_addr = (u16)TS_H(Q_REG_TX_MEMORY_BANK_START, idx);
2350
2351 status = ice_read_quad_reg_e822(hw, quad, lo_addr, &lo);
2352 if (status) {
2353 ice_debug(hw, ICE_DBG_PTP, "Failed to read low PTP timestamp register, status %d\n",
2354 status);
2355 return status;
2356 }
2357
2358 status = ice_read_quad_reg_e822(hw, quad, hi_addr, &hi);
2359 if (status) {
2360 ice_debug(hw, ICE_DBG_PTP, "Failed to read high PTP timestamp register, status %d\n",
2361 status);
2362 return status;
2363 }
2364
2365
2366
2367
2368
2369 *tstamp = ((u64)hi) << TS_PHY_HIGH_S | ((u64)lo & TS_PHY_LOW_M);
2370
2371 return ICE_SUCCESS;
2372}
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383static enum ice_status
2384ice_clear_phy_tstamp_e822(struct ice_hw *hw, u8 quad, u8 idx)
2385{
2386 enum ice_status status;
2387 u16 lo_addr, hi_addr;
2388
2389 lo_addr = (u16)TS_L(Q_REG_TX_MEMORY_BANK_START, idx);
2390 hi_addr = (u16)TS_H(Q_REG_TX_MEMORY_BANK_START, idx);
2391
2392 status = ice_write_quad_reg_e822(hw, quad, lo_addr, 0);
2393 if (status) {
2394 ice_debug(hw, ICE_DBG_PTP, "Failed to clear low PTP timestamp register, status %d\n",
2395 status);
2396 return status;
2397 }
2398
2399 status = ice_write_quad_reg_e822(hw, quad, hi_addr, 0);
2400 if (status) {
2401 ice_debug(hw, ICE_DBG_PTP, "Failed to clear high PTP timestamp register, status %d\n",
2402 status);
2403 return status;
2404 }
2405
2406 return ICE_SUCCESS;
2407}
2408
2409
2410
2411
2412
2413
2414
2415enum ice_status ice_ptp_set_vernier_wl(struct ice_hw *hw)
2416{
2417 u8 port;
2418
2419 for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
2420 enum ice_status status;
2421
2422 status = ice_write_phy_reg_e822_lp(hw, port, P_REG_WL,
2423 PTP_VERNIER_WL, true);
2424 if (status) {
2425 ice_debug(hw, ICE_DBG_PTP, "Failed to set vernier window length for port %u, status %d\n",
2426 port, status);
2427 return status;
2428 }
2429 }
2430
2431 return ICE_SUCCESS;
2432}
2433
2434
2435
2436
2437
2438
2439
2440static enum ice_status ice_ptp_init_phc_e822(struct ice_hw *hw)
2441{
2442 enum ice_status status;
2443 u32 regval;
2444
2445
2446#define PF_SB_REM_DEV_CTL_SWITCH_READ BIT(1)
2447#define PF_SB_REM_DEV_CTL_PHY0 BIT(2)
2448 regval = rd32(hw, PF_SB_REM_DEV_CTL);
2449 regval |= (PF_SB_REM_DEV_CTL_SWITCH_READ |
2450 PF_SB_REM_DEV_CTL_PHY0);
2451 wr32(hw, PF_SB_REM_DEV_CTL, regval);
2452
2453
2454 status = ice_init_cgu_e822(hw);
2455 if (status)
2456 return status;
2457
2458
2459 return ice_ptp_set_vernier_wl(hw);
2460}
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472static enum ice_status
2473ice_ptp_prep_phy_time_e822(struct ice_hw *hw, u32 time)
2474{
2475 enum ice_status status;
2476 u64 phy_time;
2477 u8 port;
2478
2479
2480
2481
2482 phy_time = (u64)time << 32;
2483
2484 for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
2485
2486
2487 status = ice_write_64b_phy_reg_e822(hw, port,
2488 P_REG_TX_TIMER_INC_PRE_L,
2489 phy_time);
2490 if (status)
2491 goto exit_err;
2492
2493
2494 status = ice_write_64b_phy_reg_e822(hw, port,
2495 P_REG_RX_TIMER_INC_PRE_L,
2496 phy_time);
2497 if (status)
2498 goto exit_err;
2499 }
2500
2501 return ICE_SUCCESS;
2502
2503exit_err:
2504 ice_debug(hw, ICE_DBG_PTP, "Failed to write init time for port %u, status %d\n",
2505 port, status);
2506
2507 return status;
2508}
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527enum ice_status
2528ice_ptp_prep_port_adj_e822(struct ice_hw *hw, u8 port, s64 time,
2529 bool lock_sbq)
2530{
2531 enum ice_status status;
2532 u32 l_time, u_time;
2533
2534 l_time = ICE_LO_DWORD(time);
2535 u_time = ICE_HI_DWORD(time);
2536
2537
2538 status = ice_write_phy_reg_e822_lp(hw, port, P_REG_TX_TIMER_INC_PRE_L,
2539 l_time, lock_sbq);
2540 if (status)
2541 goto exit_err;
2542
2543 status = ice_write_phy_reg_e822_lp(hw, port, P_REG_TX_TIMER_INC_PRE_U,
2544 u_time, lock_sbq);
2545 if (status)
2546 goto exit_err;
2547
2548
2549 status = ice_write_phy_reg_e822_lp(hw, port, P_REG_RX_TIMER_INC_PRE_L,
2550 l_time, lock_sbq);
2551 if (status)
2552 goto exit_err;
2553
2554 status = ice_write_phy_reg_e822_lp(hw, port, P_REG_RX_TIMER_INC_PRE_U,
2555 u_time, lock_sbq);
2556 if (status)
2557 goto exit_err;
2558
2559 return ICE_SUCCESS;
2560
2561exit_err:
2562 ice_debug(hw, ICE_DBG_PTP, "Failed to write time adjust for port %u, status %d\n",
2563 port, status);
2564 return status;
2565}
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578static enum ice_status
2579ice_ptp_prep_phy_adj_e822(struct ice_hw *hw, s32 adj, bool lock_sbq)
2580{
2581 s64 cycles;
2582 u8 port;
2583
2584
2585
2586
2587
2588 if (adj > 0)
2589 cycles = (s64)adj << 32;
2590 else
2591 cycles = -(((s64)-adj) << 32);
2592
2593 for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
2594 enum ice_status status;
2595
2596 status = ice_ptp_prep_port_adj_e822(hw, port, cycles,
2597 lock_sbq);
2598 if (status)
2599 return status;
2600 }
2601
2602 return ICE_SUCCESS;
2603}
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614static enum ice_status
2615ice_ptp_prep_phy_incval_e822(struct ice_hw *hw, u64 incval)
2616{
2617 enum ice_status status;
2618 u8 port;
2619
2620 for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
2621 status = ice_write_40b_phy_reg_e822(hw, port, P_REG_TIMETUS_L,
2622 incval);
2623 if (status)
2624 goto exit_err;
2625 }
2626
2627 return ICE_SUCCESS;
2628
2629exit_err:
2630 ice_debug(hw, ICE_DBG_PTP, "Failed to write incval for port %u, status %d\n",
2631 port, status);
2632
2633 return status;
2634}
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644enum ice_status
2645ice_ptp_read_phy_incval_e822(struct ice_hw *hw, u8 port, u64 *incval)
2646{
2647 enum ice_status status;
2648
2649 status = ice_read_40b_phy_reg_e822(hw, port, P_REG_TIMETUS_L, incval);
2650 if (status) {
2651 ice_debug(hw, ICE_DBG_PTP, "Failed to read TIMETUS_L, status %d\n",
2652 status);
2653 return status;
2654 }
2655
2656 ice_debug(hw, ICE_DBG_PTP, "read INCVAL = 0x%016llx\n",
2657 (unsigned long long)*incval);
2658
2659 return ICE_SUCCESS;
2660}
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675static enum ice_status
2676ice_ptp_prep_phy_adj_target_e822(struct ice_hw *hw, u32 target_time)
2677{
2678 enum ice_status status;
2679 u8 port;
2680
2681 for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
2682
2683
2684
2685 status = ice_write_phy_reg_e822_lp(hw, port,
2686 P_REG_TX_TIMER_CNT_ADJ_L,
2687 0, true);
2688 if (status)
2689 goto exit_err;
2690
2691 status = ice_write_phy_reg_e822_lp(hw, port,
2692 P_REG_TX_TIMER_CNT_ADJ_U,
2693 target_time, true);
2694 if (status)
2695 goto exit_err;
2696
2697
2698
2699 status = ice_write_phy_reg_e822_lp(hw, port,
2700 P_REG_RX_TIMER_CNT_ADJ_L,
2701 0, true);
2702 if (status)
2703 goto exit_err;
2704
2705 status = ice_write_phy_reg_e822_lp(hw, port,
2706 P_REG_RX_TIMER_CNT_ADJ_U,
2707 target_time, true);
2708 if (status)
2709 goto exit_err;
2710 }
2711
2712 return ICE_SUCCESS;
2713
2714exit_err:
2715 ice_debug(hw, ICE_DBG_PTP, "Failed to write target time for port %u, status %d\n",
2716 port, status);
2717
2718 return status;
2719}
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732enum ice_status
2733ice_ptp_read_port_capture_e822(struct ice_hw *hw, u8 port, u64 *tx_ts,
2734 u64 *rx_ts)
2735{
2736 enum ice_status status;
2737
2738
2739 status = ice_read_64b_phy_reg_e822(hw, port, P_REG_TX_CAPTURE_L, tx_ts);
2740 if (status) {
2741 ice_debug(hw, ICE_DBG_PTP, "Failed to read REG_TX_CAPTURE, status %d\n",
2742 status);
2743 return status;
2744 }
2745
2746 ice_debug(hw, ICE_DBG_PTP, "tx_init = 0x%016llx\n",
2747 (unsigned long long)*tx_ts);
2748
2749
2750 status = ice_read_64b_phy_reg_e822(hw, port, P_REG_RX_CAPTURE_L, rx_ts);
2751 if (status) {
2752 ice_debug(hw, ICE_DBG_PTP, "Failed to read RX_CAPTURE, status %d\n",
2753 status);
2754 return status;
2755 }
2756
2757 ice_debug(hw, ICE_DBG_PTP, "rx_init = 0x%016llx\n",
2758 (unsigned long long)*rx_ts);
2759
2760 return ICE_SUCCESS;
2761}
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775enum ice_status
2776ice_ptp_one_port_cmd_e822(struct ice_hw *hw, u8 port, enum ice_ptp_tmr_cmd cmd,
2777 bool lock_sbq)
2778{
2779 enum ice_status status;
2780 u32 cmd_val, val;
2781 u8 tmr_idx;
2782
2783 tmr_idx = ice_get_ptp_src_clock_index(hw);
2784 cmd_val = tmr_idx << SEL_PHY_SRC;
2785 switch (cmd) {
2786 case ICE_PTP_INIT_TIME:
2787 cmd_val |= PHY_CMD_INIT_TIME;
2788 break;
2789 case ICE_PTP_INIT_INCVAL:
2790 cmd_val |= PHY_CMD_INIT_INCVAL;
2791 break;
2792 case ICE_PTP_ADJ_TIME:
2793 cmd_val |= PHY_CMD_ADJ_TIME;
2794 break;
2795 case ICE_PTP_ADJ_TIME_AT_TIME:
2796 cmd_val |= PHY_CMD_ADJ_TIME_AT_TIME;
2797 break;
2798 case ICE_PTP_READ_TIME:
2799 cmd_val |= PHY_CMD_READ_TIME;
2800 break;
2801 default:
2802 ice_warn(hw, "Unknown timer command %u\n", cmd);
2803 return ICE_ERR_PARAM;
2804 }
2805
2806
2807
2808 status = ice_read_phy_reg_e822_lp(hw, port, P_REG_TX_TMR_CMD, &val,
2809 lock_sbq);
2810 if (status) {
2811 ice_debug(hw, ICE_DBG_PTP, "Failed to read TX_TMR_CMD, status %d\n",
2812 status);
2813 return status;
2814 }
2815
2816
2817 val &= ~TS_CMD_MASK;
2818 val |= cmd_val;
2819
2820 status = ice_write_phy_reg_e822_lp(hw, port, P_REG_TX_TMR_CMD, val,
2821 lock_sbq);
2822 if (status) {
2823 ice_debug(hw, ICE_DBG_PTP, "Failed to write back TX_TMR_CMD, status %d\n",
2824 status);
2825 return status;
2826 }
2827
2828
2829
2830 status = ice_read_phy_reg_e822_lp(hw, port, P_REG_RX_TMR_CMD, &val,
2831 lock_sbq);
2832 if (status) {
2833 ice_debug(hw, ICE_DBG_PTP, "Failed to read RX_TMR_CMD, status %d\n",
2834 status);
2835 return status;
2836 }
2837
2838
2839 val &= ~TS_CMD_MASK;
2840 val |= cmd_val;
2841
2842 status = ice_write_phy_reg_e822_lp(hw, port, P_REG_RX_TMR_CMD, val,
2843 lock_sbq);
2844 if (status) {
2845 ice_debug(hw, ICE_DBG_PTP, "Failed to write back RX_TMR_CMD, status %d\n",
2846 status);
2847 return status;
2848 }
2849
2850 return ICE_SUCCESS;
2851}
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862static enum ice_status
2863ice_ptp_port_cmd_e822(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd,
2864 bool lock_sbq)
2865{
2866 u8 port;
2867
2868 for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
2869 enum ice_status status;
2870
2871 status = ice_ptp_one_port_cmd_e822(hw, port, cmd, lock_sbq);
2872 if (status)
2873 return status;
2874 }
2875
2876 return ICE_SUCCESS;
2877}
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896enum ice_status
2897ice_phy_get_speed_and_fec_e822(struct ice_hw *hw, u8 port,
2898 enum ice_ptp_link_spd *link_out,
2899 enum ice_ptp_fec_mode *fec_out)
2900{
2901 enum ice_ptp_link_spd link;
2902 enum ice_ptp_fec_mode fec;
2903 enum ice_status status;
2904 u32 serdes;
2905
2906 status = ice_read_phy_reg_e822(hw, port, P_REG_LINK_SPEED, &serdes);
2907 if (status) {
2908 ice_debug(hw, ICE_DBG_PTP, "Failed to read serdes info\n");
2909 return status;
2910 }
2911
2912
2913 fec = (enum ice_ptp_fec_mode)P_REG_LINK_SPEED_FEC_MODE(serdes);
2914
2915 serdes &= P_REG_LINK_SPEED_SERDES_M;
2916
2917
2918 if (fec == ICE_PTP_FEC_MODE_RS_FEC) {
2919 switch (serdes) {
2920 case ICE_PTP_SERDES_25G:
2921 link = ICE_PTP_LNK_SPD_25G_RS;
2922 break;
2923 case ICE_PTP_SERDES_50G:
2924 link = ICE_PTP_LNK_SPD_50G_RS;
2925 break;
2926 case ICE_PTP_SERDES_100G:
2927 link = ICE_PTP_LNK_SPD_100G_RS;
2928 break;
2929 default:
2930 return ICE_ERR_OUT_OF_RANGE;
2931 }
2932 } else {
2933 switch (serdes) {
2934 case ICE_PTP_SERDES_1G:
2935 link = ICE_PTP_LNK_SPD_1G;
2936 break;
2937 case ICE_PTP_SERDES_10G:
2938 link = ICE_PTP_LNK_SPD_10G;
2939 break;
2940 case ICE_PTP_SERDES_25G:
2941 link = ICE_PTP_LNK_SPD_25G;
2942 break;
2943 case ICE_PTP_SERDES_40G:
2944 link = ICE_PTP_LNK_SPD_40G;
2945 break;
2946 case ICE_PTP_SERDES_50G:
2947 link = ICE_PTP_LNK_SPD_50G;
2948 break;
2949 default:
2950 return ICE_ERR_OUT_OF_RANGE;
2951 }
2952 }
2953
2954 if (link_out)
2955 *link_out = link;
2956 if (fec_out)
2957 *fec_out = fec;
2958
2959 return ICE_SUCCESS;
2960}
2961
2962
2963
2964
2965
2966
2967void ice_phy_cfg_lane_e822(struct ice_hw *hw, u8 port)
2968{
2969 enum ice_ptp_link_spd link_spd;
2970 enum ice_status status;
2971 u32 val;
2972 u8 quad;
2973
2974 status = ice_phy_get_speed_and_fec_e822(hw, port, &link_spd, NULL);
2975 if (status) {
2976 ice_debug(hw, ICE_DBG_PTP, "Failed to get PHY link speed, status %d\n",
2977 status);
2978 return;
2979 }
2980
2981 quad = port / ICE_PORTS_PER_QUAD;
2982
2983 status = ice_read_quad_reg_e822(hw, quad, Q_REG_TX_MEM_GBL_CFG, &val);
2984 if (status) {
2985 ice_debug(hw, ICE_DBG_PTP, "Failed to read TX_MEM_GLB_CFG, status %d\n",
2986 status);
2987 return;
2988 }
2989
2990 if (link_spd >= ICE_PTP_LNK_SPD_40G)
2991 val &= ~Q_REG_TX_MEM_GBL_CFG_LANE_TYPE_M;
2992 else
2993 val |= Q_REG_TX_MEM_GBL_CFG_LANE_TYPE_M;
2994
2995 status = ice_write_quad_reg_e822(hw, quad, Q_REG_TX_MEM_GBL_CFG, val);
2996 if (status) {
2997 ice_debug(hw, ICE_DBG_PTP, "Failed to write back TX_MEM_GBL_CFG, status %d\n",
2998 status);
2999 return;
3000 }
3001}
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049static enum ice_status ice_phy_cfg_uix_e822(struct ice_hw *hw, u8 port)
3050{
3051 u64 cur_freq, clk_incval, tu_per_sec, uix;
3052 enum ice_status status;
3053
3054 cur_freq = ice_e822_pll_freq(ice_e822_time_ref(hw));
3055 clk_incval = ice_ptp_read_src_incval(hw);
3056
3057
3058 tu_per_sec = (cur_freq * clk_incval) >> 8;
3059
3060#define LINE_UI_10G_40G 640
3061#define LINE_UI_25G_100G 256
3062
3063
3064 uix = DIV_U64(tu_per_sec * LINE_UI_10G_40G, 390625000);
3065
3066 status = ice_write_64b_phy_reg_e822(hw, port, P_REG_UIX66_10G_40G_L,
3067 uix);
3068 if (status) {
3069 ice_debug(hw, ICE_DBG_PTP, "Failed to write UIX66_10G_40G, status %d\n",
3070 status);
3071 return status;
3072 }
3073
3074
3075 uix = DIV_U64(tu_per_sec * LINE_UI_25G_100G, 390625000);
3076
3077 status = ice_write_64b_phy_reg_e822(hw, port, P_REG_UIX66_25G_100G_L,
3078 uix);
3079 if (status) {
3080 ice_debug(hw, ICE_DBG_PTP, "Failed to write UIX66_25G_100G, status %d\n",
3081 status);
3082 return status;
3083 }
3084
3085 return ICE_SUCCESS;
3086}
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131static enum ice_status ice_phy_cfg_parpcs_e822(struct ice_hw *hw, u8 port)
3132{
3133 u64 cur_freq, clk_incval, tu_per_sec, phy_tus;
3134 enum ice_ptp_link_spd link_spd;
3135 enum ice_ptp_fec_mode fec_mode;
3136 enum ice_status status;
3137
3138 status = ice_phy_get_speed_and_fec_e822(hw, port, &link_spd, &fec_mode);
3139 if (status)
3140 return status;
3141
3142 cur_freq = ice_e822_pll_freq(ice_e822_time_ref(hw));
3143 clk_incval = ice_ptp_read_src_incval(hw);
3144
3145
3146 tu_per_sec = cur_freq * clk_incval;
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156 if (e822_vernier[link_spd].tx_par_clk)
3157 phy_tus = DIV_U64(tu_per_sec,
3158 e822_vernier[link_spd].tx_par_clk);
3159 else
3160 phy_tus = 0;
3161
3162 status = ice_write_40b_phy_reg_e822(hw, port, P_REG_PAR_TX_TUS_L,
3163 phy_tus);
3164 if (status)
3165 return status;
3166
3167
3168 if (e822_vernier[link_spd].rx_par_clk)
3169 phy_tus = DIV_U64(tu_per_sec,
3170 e822_vernier[link_spd].rx_par_clk);
3171 else
3172 phy_tus = 0;
3173
3174 status = ice_write_40b_phy_reg_e822(hw, port, P_REG_PAR_RX_TUS_L,
3175 phy_tus);
3176 if (status)
3177 return status;
3178
3179
3180 if (e822_vernier[link_spd].tx_pcs_clk)
3181 phy_tus = DIV_U64(tu_per_sec,
3182 e822_vernier[link_spd].tx_pcs_clk);
3183 else
3184 phy_tus = 0;
3185
3186 status = ice_write_40b_phy_reg_e822(hw, port, P_REG_PCS_TX_TUS_L,
3187 phy_tus);
3188 if (status)
3189 return status;
3190
3191
3192 if (e822_vernier[link_spd].rx_pcs_clk)
3193 phy_tus = DIV_U64(tu_per_sec,
3194 e822_vernier[link_spd].rx_pcs_clk);
3195 else
3196 phy_tus = 0;
3197
3198 status = ice_write_40b_phy_reg_e822(hw, port, P_REG_PCS_RX_TUS_L,
3199 phy_tus);
3200 if (status)
3201 return status;
3202
3203
3204 if (e822_vernier[link_spd].tx_desk_rsgb_par)
3205 phy_tus = DIV_U64(tu_per_sec,
3206 e822_vernier[link_spd].tx_desk_rsgb_par);
3207 else
3208 phy_tus = 0;
3209
3210 status = ice_write_40b_phy_reg_e822(hw, port, P_REG_DESK_PAR_TX_TUS_L,
3211 phy_tus);
3212 if (status)
3213 return status;
3214
3215
3216 if (e822_vernier[link_spd].rx_desk_rsgb_par)
3217 phy_tus = DIV_U64(tu_per_sec,
3218 e822_vernier[link_spd].rx_desk_rsgb_par);
3219 else
3220 phy_tus = 0;
3221
3222 status = ice_write_40b_phy_reg_e822(hw, port, P_REG_DESK_PAR_RX_TUS_L,
3223 phy_tus);
3224 if (status)
3225 return status;
3226
3227
3228 if (e822_vernier[link_spd].tx_desk_rsgb_pcs)
3229 phy_tus = DIV_U64(tu_per_sec,
3230 e822_vernier[link_spd].tx_desk_rsgb_pcs);
3231 else
3232 phy_tus = 0;
3233
3234 status = ice_write_40b_phy_reg_e822(hw, port, P_REG_DESK_PCS_TX_TUS_L,
3235 phy_tus);
3236 if (status)
3237 return status;
3238
3239
3240 if (e822_vernier[link_spd].rx_desk_rsgb_pcs)
3241 phy_tus = DIV_U64(tu_per_sec,
3242 e822_vernier[link_spd].rx_desk_rsgb_pcs);
3243 else
3244 phy_tus = 0;
3245
3246 return ice_write_40b_phy_reg_e822(hw, port, P_REG_DESK_PCS_RX_TUS_L,
3247 phy_tus);
3248}
3249
3250
3251
3252
3253
3254
3255
3256
3257static u64
3258ice_calc_fixed_tx_offset_e822(struct ice_hw *hw, enum ice_ptp_link_spd link_spd)
3259{
3260 u64 cur_freq, clk_incval, tu_per_sec, fixed_offset;
3261
3262 cur_freq = ice_e822_pll_freq(ice_e822_time_ref(hw));
3263 clk_incval = ice_ptp_read_src_incval(hw);
3264
3265
3266 tu_per_sec = cur_freq * clk_incval;
3267
3268
3269
3270
3271
3272
3273
3274 fixed_offset = DIV_U64(tu_per_sec, 10000);
3275 fixed_offset *= e822_vernier[link_spd].tx_fixed_delay;
3276 fixed_offset = DIV_U64(fixed_offset, 10000000);
3277
3278 return fixed_offset;
3279}
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299enum ice_status ice_phy_cfg_tx_offset_e822(struct ice_hw *hw, u8 port)
3300{
3301 enum ice_ptp_link_spd link_spd;
3302 enum ice_ptp_fec_mode fec_mode;
3303 enum ice_status status;
3304 u64 total_offset, val;
3305
3306 status = ice_phy_get_speed_and_fec_e822(hw, port, &link_spd, &fec_mode);
3307 if (status)
3308 return status;
3309
3310 total_offset = ice_calc_fixed_tx_offset_e822(hw, link_spd);
3311
3312
3313
3314
3315 if (link_spd == ICE_PTP_LNK_SPD_1G ||
3316 link_spd == ICE_PTP_LNK_SPD_10G ||
3317 link_spd == ICE_PTP_LNK_SPD_25G ||
3318 link_spd == ICE_PTP_LNK_SPD_25G_RS ||
3319 link_spd == ICE_PTP_LNK_SPD_40G ||
3320 link_spd == ICE_PTP_LNK_SPD_50G) {
3321 status = ice_read_64b_phy_reg_e822(hw, port,
3322 P_REG_PAR_PCS_TX_OFFSET_L,
3323 &val);
3324 if (status)
3325 return status;
3326
3327 total_offset += val;
3328 }
3329
3330
3331
3332
3333
3334 if (link_spd == ICE_PTP_LNK_SPD_50G_RS ||
3335 link_spd == ICE_PTP_LNK_SPD_100G_RS) {
3336 status = ice_read_64b_phy_reg_e822(hw, port,
3337 P_REG_PAR_TX_TIME_L,
3338 &val);
3339 if (status)
3340 return status;
3341
3342 total_offset += val;
3343 }
3344
3345
3346
3347
3348
3349 status = ice_write_64b_phy_reg_e822(hw, port, P_REG_TOTAL_TX_OFFSET_L,
3350 total_offset);
3351 if (status)
3352 return status;
3353
3354 status = ice_write_phy_reg_e822(hw, port, P_REG_TX_OR, 1);
3355 if (status)
3356 return status;
3357
3358 return ICE_SUCCESS;
3359}
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369static enum ice_status
3370ice_phy_cfg_fixed_tx_offset_e822(struct ice_hw *hw, u8 port)
3371{
3372 enum ice_ptp_link_spd link_spd;
3373 enum ice_ptp_fec_mode fec_mode;
3374 enum ice_status status;
3375 u64 total_offset;
3376
3377 status = ice_phy_get_speed_and_fec_e822(hw, port, &link_spd, &fec_mode);
3378 if (status)
3379 return status;
3380
3381 total_offset = ice_calc_fixed_tx_offset_e822(hw, link_spd);
3382
3383
3384
3385
3386
3387
3388
3389
3390 status = ice_write_64b_phy_reg_e822(hw, port, P_REG_TOTAL_TX_OFFSET_L,
3391 total_offset);
3392 if (status)
3393 return status;
3394
3395 status = ice_write_phy_reg_e822(hw, port, P_REG_TX_OR, 1);
3396 if (status)
3397 return status;
3398
3399 return ICE_SUCCESS;
3400}
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414static enum ice_status
3415ice_phy_calc_pmd_adj_e822(struct ice_hw *hw, u8 port,
3416 enum ice_ptp_link_spd link_spd,
3417 enum ice_ptp_fec_mode fec_mode, u64 *pmd_adj)
3418{
3419 u64 cur_freq, clk_incval, tu_per_sec, mult, adj;
3420 u32 pmd_adj_divisor, val;
3421 enum ice_status status;
3422 u8 pmd_align;
3423
3424 status = ice_read_phy_reg_e822(hw, port, P_REG_PMD_ALIGNMENT, &val);
3425 if (status) {
3426 ice_debug(hw, ICE_DBG_PTP, "Failed to read PMD alignment, status %d\n",
3427 status);
3428 return status;
3429 }
3430
3431 pmd_align = (u8)val;
3432
3433 cur_freq = ice_e822_pll_freq(ice_e822_time_ref(hw));
3434 clk_incval = ice_ptp_read_src_incval(hw);
3435
3436
3437 tu_per_sec = cur_freq * clk_incval;
3438
3439
3440 pmd_adj_divisor = e822_vernier[link_spd].pmd_adj_divisor;
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466 if (link_spd == ICE_PTP_LNK_SPD_1G) {
3467 if (pmd_align == 4)
3468 mult = 10;
3469 else
3470 mult = (pmd_align + 6) % 10;
3471 } else if (link_spd == ICE_PTP_LNK_SPD_10G ||
3472 link_spd == ICE_PTP_LNK_SPD_25G ||
3473 link_spd == ICE_PTP_LNK_SPD_40G ||
3474 link_spd == ICE_PTP_LNK_SPD_50G) {
3475
3476 if (pmd_align != 65 || fec_mode == ICE_PTP_FEC_MODE_CLAUSE74)
3477 mult = pmd_align;
3478 else
3479 mult = 0;
3480 } else if (link_spd == ICE_PTP_LNK_SPD_25G_RS ||
3481 link_spd == ICE_PTP_LNK_SPD_50G_RS ||
3482 link_spd == ICE_PTP_LNK_SPD_100G_RS) {
3483 if (pmd_align < 17)
3484 mult = pmd_align + 40;
3485 else
3486 mult = pmd_align;
3487 } else {
3488 ice_debug(hw, ICE_DBG_PTP, "Unknown link speed %d, skipping PMD adjustment\n",
3489 link_spd);
3490 mult = 0;
3491 }
3492
3493
3494 if (!mult) {
3495 *pmd_adj = 0;
3496 return ICE_SUCCESS;
3497 }
3498
3499
3500
3501
3502
3503
3504 adj = DIV_U64(tu_per_sec, 125);
3505 adj *= mult;
3506 adj = DIV_U64(adj, pmd_adj_divisor);
3507
3508
3509
3510
3511 if (link_spd == ICE_PTP_LNK_SPD_25G_RS) {
3512 u64 cycle_adj;
3513 u8 rx_cycle;
3514
3515 status = ice_read_phy_reg_e822(hw, port, P_REG_RX_40_TO_160_CNT,
3516 &val);
3517 if (status) {
3518 ice_debug(hw, ICE_DBG_PTP, "Failed to read 25G-RS Rx cycle count, status %d\n",
3519 status);
3520 return status;
3521 }
3522
3523 rx_cycle = val & P_REG_RX_40_TO_160_CNT_RXCYC_M;
3524 if (rx_cycle) {
3525 mult = (4 - rx_cycle) * 40;
3526
3527 cycle_adj = DIV_U64(tu_per_sec, 125);
3528 cycle_adj *= mult;
3529 cycle_adj = DIV_U64(cycle_adj, pmd_adj_divisor);
3530
3531 adj += cycle_adj;
3532 }
3533 } else if (link_spd == ICE_PTP_LNK_SPD_50G_RS) {
3534 u64 cycle_adj;
3535 u8 rx_cycle;
3536
3537 status = ice_read_phy_reg_e822(hw, port, P_REG_RX_80_TO_160_CNT,
3538 &val);
3539 if (status) {
3540 ice_debug(hw, ICE_DBG_PTP, "Failed to read 50G-RS Rx cycle count, status %d\n",
3541 status);
3542 return status;
3543 }
3544
3545 rx_cycle = val & P_REG_RX_80_TO_160_CNT_RXCYC_M;
3546 if (rx_cycle) {
3547 mult = rx_cycle * 40;
3548
3549 cycle_adj = DIV_U64(tu_per_sec, 125);
3550 cycle_adj *= mult;
3551 cycle_adj = DIV_U64(cycle_adj, pmd_adj_divisor);
3552
3553 adj += cycle_adj;
3554 }
3555 }
3556
3557
3558 *pmd_adj = adj;
3559
3560 return ICE_SUCCESS;
3561}
3562
3563
3564
3565
3566
3567
3568
3569
3570static u64
3571ice_calc_fixed_rx_offset_e822(struct ice_hw *hw, enum ice_ptp_link_spd link_spd)
3572{
3573 u64 cur_freq, clk_incval, tu_per_sec, fixed_offset;
3574
3575 cur_freq = ice_e822_pll_freq(ice_e822_time_ref(hw));
3576 clk_incval = ice_ptp_read_src_incval(hw);
3577
3578
3579 tu_per_sec = cur_freq * clk_incval;
3580
3581
3582
3583
3584
3585
3586
3587 fixed_offset = DIV_U64(tu_per_sec, 10000);
3588 fixed_offset *= e822_vernier[link_spd].rx_fixed_delay;
3589 fixed_offset = DIV_U64(fixed_offset, 10000000);
3590
3591 return fixed_offset;
3592}
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613enum ice_status ice_phy_cfg_rx_offset_e822(struct ice_hw *hw, u8 port)
3614{
3615 enum ice_ptp_link_spd link_spd;
3616 enum ice_ptp_fec_mode fec_mode;
3617 u64 total_offset, pmd, val;
3618 enum ice_status status;
3619
3620 status = ice_phy_get_speed_and_fec_e822(hw, port, &link_spd, &fec_mode);
3621 if (status)
3622 return status;
3623
3624 total_offset = ice_calc_fixed_rx_offset_e822(hw, link_spd);
3625
3626
3627
3628
3629 status = ice_read_64b_phy_reg_e822(hw, port,
3630 P_REG_PAR_PCS_RX_OFFSET_L,
3631 &val);
3632 if (status)
3633 return status;
3634
3635 total_offset += val;
3636
3637
3638
3639
3640 if (link_spd == ICE_PTP_LNK_SPD_40G ||
3641 link_spd == ICE_PTP_LNK_SPD_50G ||
3642 link_spd == ICE_PTP_LNK_SPD_50G_RS ||
3643 link_spd == ICE_PTP_LNK_SPD_100G_RS) {
3644 status = ice_read_64b_phy_reg_e822(hw, port,
3645 P_REG_PAR_RX_TIME_L,
3646 &val);
3647 if (status)
3648 return status;
3649
3650 total_offset += val;
3651 }
3652
3653
3654 status = ice_phy_calc_pmd_adj_e822(hw, port, link_spd, fec_mode, &pmd);
3655 if (status)
3656 return status;
3657
3658
3659
3660
3661 if (fec_mode == ICE_PTP_FEC_MODE_RS_FEC)
3662 total_offset += pmd;
3663 else
3664 total_offset -= pmd;
3665
3666
3667
3668
3669
3670 status = ice_write_64b_phy_reg_e822(hw, port, P_REG_TOTAL_RX_OFFSET_L,
3671 total_offset);
3672 if (status)
3673 return status;
3674
3675 status = ice_write_phy_reg_e822(hw, port, P_REG_RX_OR, 1);
3676 if (status)
3677 return status;
3678
3679 return ICE_SUCCESS;
3680}
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690static enum ice_status
3691ice_phy_cfg_fixed_rx_offset_e822(struct ice_hw *hw, u8 port)
3692{
3693 enum ice_ptp_link_spd link_spd;
3694 enum ice_ptp_fec_mode fec_mode;
3695 enum ice_status status;
3696 u64 total_offset;
3697
3698 status = ice_phy_get_speed_and_fec_e822(hw, port, &link_spd, &fec_mode);
3699 if (status)
3700 return status;
3701
3702 total_offset = ice_calc_fixed_rx_offset_e822(hw, link_spd);
3703
3704
3705
3706
3707
3708
3709
3710
3711 status = ice_write_64b_phy_reg_e822(hw, port, P_REG_TOTAL_RX_OFFSET_L,
3712 total_offset);
3713 if (status)
3714 return status;
3715
3716 status = ice_write_phy_reg_e822(hw, port, P_REG_RX_OR, 1);
3717 if (status)
3718 return status;
3719
3720 return ICE_SUCCESS;
3721}
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733static enum ice_status
3734ice_read_phy_and_phc_time_e822(struct ice_hw *hw, u8 port, u64 *phy_time,
3735 u64 *phc_time)
3736{
3737 enum ice_status status;
3738 u64 tx_time, rx_time;
3739 u32 zo, lo;
3740 u8 tmr_idx;
3741
3742 tmr_idx = ice_get_ptp_src_clock_index(hw);
3743
3744
3745 ice_ptp_src_cmd(hw, ICE_PTP_READ_TIME);
3746
3747
3748 status = ice_ptp_one_port_cmd_e822(hw, port, ICE_PTP_READ_TIME, true);
3749 if (status)
3750 return status;
3751
3752
3753 ice_ptp_exec_tmr_cmd(hw);
3754 ice_ptp_clean_cmd(hw);
3755
3756
3757 zo = rd32(hw, GLTSYN_SHTIME_0(tmr_idx));
3758 lo = rd32(hw, GLTSYN_SHTIME_L(tmr_idx));
3759 *phc_time = (u64)lo << 32 | zo;
3760
3761
3762 status = ice_ptp_read_port_capture_e822(hw, port, &tx_time, &rx_time);
3763 if (status)
3764 return status;
3765
3766
3767
3768
3769
3770 if (tx_time != rx_time)
3771 ice_warn(hw, "PHY port %u Tx and Rx timers do not match, tx_time 0x%016llX, rx_time 0x%016llX\n",
3772 port, (unsigned long long)tx_time,
3773 (unsigned long long)rx_time);
3774
3775 *phy_time = tx_time;
3776
3777 return ICE_SUCCESS;
3778}
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792static enum ice_status ice_sync_phy_timer_e822(struct ice_hw *hw, u8 port)
3793{
3794 u64 phc_time, phy_time, difference;
3795 enum ice_status status;
3796
3797 if (!ice_ptp_lock(hw)) {
3798 ice_debug(hw, ICE_DBG_PTP, "Failed to acquire PTP semaphore\n");
3799 return ICE_ERR_NOT_READY;
3800 }
3801
3802 status = ice_read_phy_and_phc_time_e822(hw, port, &phy_time, &phc_time);
3803 if (status)
3804 goto err_unlock;
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814 difference = phc_time - phy_time;
3815
3816 status = ice_ptp_prep_port_adj_e822(hw, port, (s64)difference, true);
3817 if (status)
3818 goto err_unlock;
3819
3820 status = ice_ptp_one_port_cmd_e822(hw, port, ICE_PTP_ADJ_TIME, true);
3821 if (status)
3822 goto err_unlock;
3823
3824
3825 ice_ptp_src_cmd(hw, ICE_PTP_READ_TIME);
3826
3827
3828 ice_ptp_exec_tmr_cmd(hw);
3829 ice_ptp_clean_cmd(hw);
3830
3831
3832
3833
3834 status = ice_read_phy_and_phc_time_e822(hw, port, &phy_time, &phc_time);
3835 if (status)
3836 goto err_unlock;
3837
3838 ice_info(hw, "Port %u PHY time synced to PHC: 0x%016llX, 0x%016llX\n",
3839 port, (unsigned long long)phy_time,
3840 (unsigned long long)phc_time);
3841
3842 ice_ptp_unlock(hw);
3843
3844 return ICE_SUCCESS;
3845
3846err_unlock:
3847 ice_ptp_unlock(hw);
3848 return status;
3849}
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861enum ice_status
3862ice_stop_phy_timer_e822(struct ice_hw *hw, u8 port, bool soft_reset)
3863{
3864 enum ice_status status;
3865 u32 val;
3866
3867 status = ice_write_phy_reg_e822(hw, port, P_REG_TX_OR, 0);
3868 if (status)
3869 return status;
3870
3871 status = ice_write_phy_reg_e822(hw, port, P_REG_RX_OR, 0);
3872 if (status)
3873 return status;
3874
3875 status = ice_read_phy_reg_e822(hw, port, P_REG_PS, &val);
3876 if (status)
3877 return status;
3878
3879 val &= ~P_REG_PS_START_M;
3880 status = ice_write_phy_reg_e822(hw, port, P_REG_PS, val);
3881 if (status)
3882 return status;
3883
3884 val &= ~P_REG_PS_ENA_CLK_M;
3885 status = ice_write_phy_reg_e822(hw, port, P_REG_PS, val);
3886 if (status)
3887 return status;
3888
3889 if (soft_reset) {
3890 val |= P_REG_PS_SFT_RESET_M;
3891 status = ice_write_phy_reg_e822(hw, port, P_REG_PS, val);
3892 if (status)
3893 return status;
3894 }
3895
3896 ice_debug(hw, ICE_DBG_PTP, "Disabled clock on PHY port %u\n", port);
3897
3898 return ICE_SUCCESS;
3899}
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917enum ice_status
3918ice_start_phy_timer_e822(struct ice_hw *hw, u8 port, bool bypass)
3919{
3920 enum ice_status status;
3921 u32 lo, hi, val;
3922 u64 incval;
3923 u8 tmr_idx;
3924
3925 ice_ptp_clean_cmd(hw);
3926 tmr_idx = ice_get_ptp_src_clock_index(hw);
3927
3928 status = ice_stop_phy_timer_e822(hw, port, false);
3929 if (status)
3930 return status;
3931
3932 ice_phy_cfg_lane_e822(hw, port);
3933
3934 status = ice_phy_cfg_uix_e822(hw, port);
3935 if (status)
3936 return status;
3937
3938 status = ice_phy_cfg_parpcs_e822(hw, port);
3939 if (status)
3940 return status;
3941
3942 lo = rd32(hw, GLTSYN_INCVAL_L(tmr_idx));
3943 hi = rd32(hw, GLTSYN_INCVAL_H(tmr_idx));
3944 incval = (u64)hi << 32 | lo;
3945
3946 status = ice_write_40b_phy_reg_e822(hw, port, P_REG_TIMETUS_L, incval);
3947 if (status)
3948 return status;
3949
3950 status = ice_ptp_one_port_cmd_e822(hw, port, ICE_PTP_INIT_INCVAL, true);
3951 if (status)
3952 return status;
3953
3954
3955 ice_ptp_src_cmd(hw, ICE_PTP_READ_TIME);
3956
3957 ice_ptp_exec_tmr_cmd(hw);
3958
3959 status = ice_read_phy_reg_e822(hw, port, P_REG_PS, &val);
3960 if (status)
3961 return status;
3962
3963 val |= P_REG_PS_SFT_RESET_M;
3964 status = ice_write_phy_reg_e822(hw, port, P_REG_PS, val);
3965 if (status)
3966 return status;
3967
3968 val |= P_REG_PS_START_M;
3969 status = ice_write_phy_reg_e822(hw, port, P_REG_PS, val);
3970 if (status)
3971 return status;
3972
3973 val &= ~P_REG_PS_SFT_RESET_M;
3974 status = ice_write_phy_reg_e822(hw, port, P_REG_PS, val);
3975 if (status)
3976 return status;
3977
3978 status = ice_ptp_one_port_cmd_e822(hw, port, ICE_PTP_INIT_INCVAL, true);
3979 if (status)
3980 return status;
3981
3982 ice_ptp_exec_tmr_cmd(hw);
3983
3984 val |= P_REG_PS_ENA_CLK_M;
3985 status = ice_write_phy_reg_e822(hw, port, P_REG_PS, val);
3986 if (status)
3987 return status;
3988
3989 val |= P_REG_PS_LOAD_OFFSET_M;
3990 status = ice_write_phy_reg_e822(hw, port, P_REG_PS, val);
3991 if (status)
3992 return status;
3993
3994 ice_ptp_exec_tmr_cmd(hw);
3995
3996 status = ice_sync_phy_timer_e822(hw, port);
3997 if (status)
3998 return status;
3999
4000 if (bypass) {
4001 val |= P_REG_PS_BYPASS_MODE_M;
4002
4003 status = ice_write_phy_reg_e822(hw, port, P_REG_PS, val);
4004 if (status)
4005 return status;
4006
4007
4008 status = ice_phy_cfg_fixed_tx_offset_e822(hw, port);
4009 if (status)
4010 return status;
4011
4012
4013 status = ice_phy_cfg_fixed_rx_offset_e822(hw, port);
4014 if (status)
4015 return status;
4016 }
4017
4018 ice_debug(hw, ICE_DBG_PTP, "Enabled clock on PHY port %u\n", port);
4019
4020 return ICE_SUCCESS;
4021}
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037enum ice_status ice_phy_exit_bypass_e822(struct ice_hw *hw, u8 port)
4038{
4039 enum ice_status status;
4040 u32 val;
4041
4042 status = ice_read_phy_reg_e822(hw, port, P_REG_TX_OV_STATUS, &val);
4043 if (status) {
4044 ice_debug(hw, ICE_DBG_PTP, "Failed to read TX_OV_STATUS for port %u, status %d\n",
4045 port, status);
4046 return status;
4047 }
4048
4049 if (!(val & P_REG_TX_OV_STATUS_OV_M)) {
4050 ice_debug(hw, ICE_DBG_PTP, "Tx offset is not yet valid for port %u\n",
4051 port);
4052 return ICE_ERR_NOT_READY;
4053 }
4054
4055 status = ice_read_phy_reg_e822(hw, port, P_REG_RX_OV_STATUS, &val);
4056 if (status) {
4057 ice_debug(hw, ICE_DBG_PTP, "Failed to read RX_OV_STATUS for port %u, status %d\n",
4058 port, status);
4059 return status;
4060 }
4061
4062 if (!(val & P_REG_TX_OV_STATUS_OV_M)) {
4063 ice_debug(hw, ICE_DBG_PTP, "Rx offset is not yet valid for port %u\n",
4064 port);
4065 return ICE_ERR_NOT_READY;
4066 }
4067
4068 status = ice_phy_cfg_tx_offset_e822(hw, port);
4069 if (status) {
4070 ice_debug(hw, ICE_DBG_PTP, "Failed to program total Tx offset for port %u, status %d\n",
4071 port, status);
4072 return status;
4073 }
4074
4075 status = ice_phy_cfg_rx_offset_e822(hw, port);
4076 if (status) {
4077 ice_debug(hw, ICE_DBG_PTP, "Failed to program total Rx offset for port %u, status %d\n",
4078 port, status);
4079 return status;
4080 }
4081
4082
4083 status = ice_read_phy_reg_e822(hw, port, P_REG_PS, &val);
4084 if (status) {
4085 ice_debug(hw, ICE_DBG_PTP, "Failed to read P_REG_PS for port %u, status %d\n",
4086 port, status);
4087 return status;
4088 }
4089
4090 if (!(val & P_REG_PS_BYPASS_MODE_M))
4091 ice_debug(hw, ICE_DBG_PTP, "Port %u not in bypass mode\n",
4092 port);
4093
4094 val &= ~P_REG_PS_BYPASS_MODE_M;
4095 status = ice_write_phy_reg_e822(hw, port, P_REG_PS, val);
4096 if (status) {
4097 ice_debug(hw, ICE_DBG_PTP, "Failed to disable bypass for port %u, status %d\n",
4098 port, status);
4099 return status;
4100 }
4101
4102 ice_info(hw, "Exiting bypass mode on PHY port %u\n", port);
4103
4104 return ICE_SUCCESS;
4105}
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122static enum ice_status
4123ice_read_phy_reg_e810_lp(struct ice_hw *hw, u32 addr, u32 *val, bool lock_sbq)
4124{
4125 struct ice_sbq_msg_input msg = {0};
4126 enum ice_status status;
4127
4128 msg.msg_addr_low = ICE_LO_WORD(addr);
4129 msg.msg_addr_high = ICE_HI_WORD(addr);
4130 msg.opcode = ice_sbq_msg_rd;
4131 msg.dest_dev = rmn_0;
4132
4133 status = ice_sbq_rw_reg_lp(hw, &msg, lock_sbq);
4134 if (status) {
4135 ice_debug(hw, ICE_DBG_PTP, "Failed to send message to phy, status %d\n",
4136 status);
4137 return status;
4138 }
4139
4140 *val = msg.data;
4141
4142 return ICE_SUCCESS;
4143}
4144
4145static enum ice_status
4146ice_read_phy_reg_e810(struct ice_hw *hw, u32 addr, u32 *val)
4147{
4148 return ice_read_phy_reg_e810_lp(hw, addr, val, true);
4149}
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160static enum ice_status
4161ice_write_phy_reg_e810_lp(struct ice_hw *hw, u32 addr, u32 val, bool lock_sbq)
4162{
4163 struct ice_sbq_msg_input msg = {0};
4164 enum ice_status status;
4165
4166 msg.msg_addr_low = ICE_LO_WORD(addr);
4167 msg.msg_addr_high = ICE_HI_WORD(addr);
4168 msg.opcode = ice_sbq_msg_wr;
4169 msg.dest_dev = rmn_0;
4170 msg.data = val;
4171
4172 status = ice_sbq_rw_reg_lp(hw, &msg, lock_sbq);
4173 if (status) {
4174 ice_debug(hw, ICE_DBG_PTP, "Failed to send message to phy, status %d\n",
4175 status);
4176 return status;
4177 }
4178
4179 return ICE_SUCCESS;
4180}
4181
4182static enum ice_status
4183ice_write_phy_reg_e810(struct ice_hw *hw, u32 addr, u32 val)
4184{
4185 return ice_write_phy_reg_e810_lp(hw, addr, val, true);
4186}
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199static enum ice_status
4200ice_read_phy_tstamp_ll_e810(struct ice_hw *hw, u8 idx, u8 *hi, u32 *lo)
4201{
4202 u8 i;
4203
4204
4205 wr32(hw, PF_SB_ATQBAL, TS_LL_READ_TS_IDX(idx));
4206
4207
4208 for (i = TS_LL_READ_RETRIES; i > 0; i--) {
4209 u32 val = rd32(hw, PF_SB_ATQBAL);
4210
4211
4212 if (!(val & TS_LL_READ_TS)) {
4213
4214 *hi = (u8)(val >> TS_LL_READ_TS_HIGH_S);
4215
4216
4217 *lo = rd32(hw, PF_SB_ATQBAH) | TS_VALID;
4218 return ICE_SUCCESS;
4219 }
4220
4221 ice_usec_delay(10, false);
4222 }
4223
4224
4225 ice_debug(hw, ICE_DBG_PTP, "Failed to read PTP timestamp using low latency read\n");
4226 return ICE_ERR_NOT_READY;
4227}
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240static enum ice_status
4241ice_read_phy_tstamp_sbq_e810(struct ice_hw *hw, u8 lport, u8 idx, u8 *hi,
4242 u32 *lo)
4243{
4244 u32 hi_addr = TS_EXT(HIGH_TX_MEMORY_BANK_START, lport, idx);
4245 u32 lo_addr = TS_EXT(LOW_TX_MEMORY_BANK_START, lport, idx);
4246 enum ice_status status;
4247 u32 lo_val, hi_val;
4248
4249 status = ice_read_phy_reg_e810(hw, lo_addr, &lo_val);
4250 if (status) {
4251 ice_debug(hw, ICE_DBG_PTP, "Failed to read low PTP timestamp register, status %d\n",
4252 status);
4253 return status;
4254 }
4255
4256 status = ice_read_phy_reg_e810(hw, hi_addr, &hi_val);
4257 if (status) {
4258 ice_debug(hw, ICE_DBG_PTP, "Failed to read high PTP timestamp register, status %d\n",
4259 status);
4260 return status;
4261 }
4262
4263 *lo = lo_val;
4264 *hi = (u8)hi_val;
4265
4266 return ICE_SUCCESS;
4267}
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279static enum ice_status
4280ice_read_phy_tstamp_e810(struct ice_hw *hw, u8 lport, u8 idx, u64 *tstamp)
4281{
4282 enum ice_status status;
4283 u32 lo = 0;
4284 u8 hi = 0;
4285
4286 if (hw->dev_caps.ts_dev_info.ts_ll_read)
4287 status = ice_read_phy_tstamp_ll_e810(hw, idx, &hi, &lo);
4288 else
4289 status = ice_read_phy_tstamp_sbq_e810(hw, lport, idx, &hi, &lo);
4290
4291 if (status)
4292 return status;
4293
4294
4295
4296
4297 *tstamp = ((u64)hi) << TS_HIGH_S | ((u64)lo & TS_LOW_M);
4298
4299 return ICE_SUCCESS;
4300}
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311static enum ice_status
4312ice_clear_phy_tstamp_e810(struct ice_hw *hw, u8 lport, u8 idx)
4313{
4314 enum ice_status status;
4315 u32 lo_addr, hi_addr;
4316
4317 lo_addr = TS_EXT(LOW_TX_MEMORY_BANK_START, lport, idx);
4318 hi_addr = TS_EXT(HIGH_TX_MEMORY_BANK_START, lport, idx);
4319
4320 status = ice_write_phy_reg_e810(hw, lo_addr, 0);
4321 if (status) {
4322 ice_debug(hw, ICE_DBG_PTP, "Failed to clear low PTP timestamp register, status %d\n",
4323 status);
4324 return status;
4325 }
4326
4327 status = ice_write_phy_reg_e810(hw, hi_addr, 0);
4328 if (status) {
4329 ice_debug(hw, ICE_DBG_PTP, "Failed to clear high PTP timestamp register, status %d\n",
4330 status);
4331 return status;
4332 }
4333
4334 return ICE_SUCCESS;
4335}
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346enum ice_status ice_ptp_init_phy_e810(struct ice_hw *hw)
4347{
4348 enum ice_status status;
4349 u8 tmr_idx;
4350
4351 tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
4352 status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_ENA(tmr_idx),
4353 GLTSYN_ENA_TSYN_ENA_M);
4354 if (status)
4355 ice_debug(hw, ICE_DBG_PTP, "PTP failed in ena_phy_time_syn %d\n",
4356 status);
4357
4358 return status;
4359}
4360
4361
4362
4363
4364
4365
4366
4367static enum ice_status ice_ptp_init_phc_e810(struct ice_hw *hw)
4368{
4369
4370 wr32(hw, GLTSYN_SYNC_DLAY, 0);
4371
4372
4373 return ice_ptp_init_phy_e810(hw);
4374}
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388static enum ice_status ice_ptp_prep_phy_time_e810(struct ice_hw *hw, u32 time)
4389{
4390 enum ice_status status;
4391 u8 tmr_idx;
4392
4393 tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
4394 status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHTIME_0(tmr_idx), 0);
4395 if (status) {
4396 ice_debug(hw, ICE_DBG_PTP, "Failed to write SHTIME_0, status %d\n",
4397 status);
4398 return status;
4399 }
4400
4401 status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHTIME_L(tmr_idx), time);
4402 if (status) {
4403 ice_debug(hw, ICE_DBG_PTP, "Failed to write SHTIME_L, status %d\n",
4404 status);
4405 return status;
4406 }
4407
4408 return ICE_SUCCESS;
4409}
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425static enum ice_status
4426ice_ptp_prep_phy_adj_e810(struct ice_hw *hw, s32 adj, bool lock_sbq)
4427{
4428 enum ice_status status;
4429 u8 tmr_idx;
4430
4431 tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
4432
4433
4434
4435
4436 status = ice_write_phy_reg_e810_lp(hw, ETH_GLTSYN_SHADJ_L(tmr_idx),
4437 0, lock_sbq);
4438 if (status) {
4439 ice_debug(hw, ICE_DBG_PTP, "Failed to write adj to PHY SHADJ_L, status %d\n",
4440 status);
4441 return status;
4442 }
4443
4444 status = ice_write_phy_reg_e810_lp(hw, ETH_GLTSYN_SHADJ_H(tmr_idx),
4445 adj, lock_sbq);
4446 if (status) {
4447 ice_debug(hw, ICE_DBG_PTP, "Failed to write adj to PHY SHADJ_H, status %d\n",
4448 status);
4449 return status;
4450 }
4451
4452 return ICE_SUCCESS;
4453}
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464static enum ice_status
4465ice_ptp_prep_phy_incval_e810(struct ice_hw *hw, u64 incval)
4466{
4467 enum ice_status status;
4468 u32 high, low;
4469 u8 tmr_idx;
4470
4471 tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
4472 low = ICE_LO_DWORD(incval);
4473 high = ICE_HI_DWORD(incval);
4474
4475 status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHADJ_L(tmr_idx), low);
4476 if (status) {
4477 ice_debug(hw, ICE_DBG_PTP, "Failed to write incval to PHY SHADJ_L, status %d\n",
4478 status);
4479 return status;
4480 }
4481
4482 status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHADJ_H(tmr_idx), high);
4483 if (status) {
4484 ice_debug(hw, ICE_DBG_PTP, "Failed to write incval PHY SHADJ_H, status %d\n",
4485 status);
4486 return status;
4487 }
4488
4489 return ICE_SUCCESS;
4490}
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506static enum ice_status
4507ice_ptp_prep_phy_adj_target_e810(struct ice_hw *hw, u32 target_time)
4508{
4509 enum ice_status status;
4510 u8 tmr_idx;
4511
4512 tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
4513 status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHTIME_0(tmr_idx), 0);
4514 if (status) {
4515 ice_debug(hw, ICE_DBG_PTP, "Failed to write target time to SHTIME_0, status %d\n",
4516 status);
4517 return status;
4518 }
4519
4520 status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHTIME_L(tmr_idx),
4521 target_time);
4522 if (status) {
4523 ice_debug(hw, ICE_DBG_PTP, "Failed to write target time to SHTIME_L, status %d\n",
4524 status);
4525 return status;
4526 }
4527
4528 return ICE_SUCCESS;
4529}
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540static enum ice_status
4541ice_ptp_port_cmd_e810(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd,
4542 bool lock_sbq)
4543{
4544 enum ice_status status;
4545 u32 cmd_val, val;
4546
4547 switch (cmd) {
4548 case ICE_PTP_INIT_TIME:
4549 cmd_val = GLTSYN_CMD_INIT_TIME;
4550 break;
4551 case ICE_PTP_INIT_INCVAL:
4552 cmd_val = GLTSYN_CMD_INIT_INCVAL;
4553 break;
4554 case ICE_PTP_ADJ_TIME:
4555 cmd_val = GLTSYN_CMD_ADJ_TIME;
4556 break;
4557 case ICE_PTP_ADJ_TIME_AT_TIME:
4558 cmd_val = GLTSYN_CMD_ADJ_INIT_TIME;
4559 break;
4560 case ICE_PTP_READ_TIME:
4561 cmd_val = GLTSYN_CMD_READ_TIME;
4562 break;
4563 default:
4564 ice_warn(hw, "Unknown timer command %u\n", cmd);
4565 return ICE_ERR_PARAM;
4566 }
4567
4568
4569 status = ice_read_phy_reg_e810_lp(hw, ETH_GLTSYN_CMD, &val, lock_sbq);
4570 if (status) {
4571 ice_debug(hw, ICE_DBG_PTP, "Failed to read GLTSYN_CMD, status %d\n",
4572 status);
4573 return status;
4574 }
4575
4576
4577 val &= ~TS_CMD_MASK_E810;
4578 val |= cmd_val;
4579
4580 status = ice_write_phy_reg_e810_lp(hw, ETH_GLTSYN_CMD, val, lock_sbq);
4581 if (status) {
4582 ice_debug(hw, ICE_DBG_PTP, "Failed to write back GLTSYN_CMD, status %d\n",
4583 status);
4584 return status;
4585 }
4586
4587 return ICE_SUCCESS;
4588}
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605static enum ice_status
4606ice_get_pca9575_handle(struct ice_hw *hw, u16 *pca9575_handle)
4607{
4608 struct ice_aqc_get_link_topo cmd;
4609 u8 node_part_number, idx;
4610 enum ice_status status;
4611 u16 node_handle;
4612
4613 if (!hw || !pca9575_handle)
4614 return ICE_ERR_PARAM;
4615
4616
4617 if (hw->io_expander_handle) {
4618 *pca9575_handle = hw->io_expander_handle;
4619 return ICE_SUCCESS;
4620 }
4621
4622 memset(&cmd, 0, sizeof(cmd));
4623
4624
4625 cmd.addr.topo_params.node_type_ctx =
4626 (ICE_AQC_LINK_TOPO_NODE_TYPE_M &
4627 ICE_AQC_LINK_TOPO_NODE_TYPE_GPIO_CTRL);
4628
4629#define SW_PCA9575_SFP_TOPO_IDX 2
4630#define SW_PCA9575_QSFP_TOPO_IDX 1
4631
4632
4633 if (hw->device_id == ICE_DEV_ID_E810C_SFP)
4634 idx = SW_PCA9575_SFP_TOPO_IDX;
4635 else if (hw->device_id == ICE_DEV_ID_E810C_QSFP)
4636 idx = SW_PCA9575_QSFP_TOPO_IDX;
4637 else
4638 return ICE_ERR_NOT_SUPPORTED;
4639
4640 cmd.addr.topo_params.index = idx;
4641
4642 status = ice_aq_get_netlist_node(hw, &cmd, &node_part_number,
4643 &node_handle);
4644 if (status)
4645 return ICE_ERR_NOT_SUPPORTED;
4646
4647
4648 if (node_part_number != ICE_ACQ_GET_LINK_TOPO_NODE_NR_PCA9575)
4649 return ICE_ERR_NOT_SUPPORTED;
4650
4651
4652 hw->io_expander_handle = node_handle;
4653 *pca9575_handle = hw->io_expander_handle;
4654
4655 return ICE_SUCCESS;
4656}
4657
4658
4659
4660
4661
4662
4663
4664bool ice_is_gps_present_e810t(struct ice_hw *hw)
4665{
4666 if (ice_find_netlist_node(hw, ICE_AQC_LINK_TOPO_NODE_TYPE_GPS,
4667 ICE_ACQ_GET_LINK_TOPO_NODE_NR_GEN_GPS, NULL))
4668 return false;
4669
4670 return true;
4671}
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681enum ice_status
4682ice_read_pca9575_reg_e810t(struct ice_hw *hw, u8 offset, u8 *data)
4683{
4684 struct ice_aqc_link_topo_addr link_topo;
4685 enum ice_status status;
4686 __le16 addr;
4687 u16 handle;
4688
4689 memset(&link_topo, 0, sizeof(link_topo));
4690
4691 status = ice_get_pca9575_handle(hw, &handle);
4692 if (status)
4693 return status;
4694
4695 link_topo.handle = CPU_TO_LE16(handle);
4696 link_topo.topo_params.node_type_ctx =
4697 (ICE_AQC_LINK_TOPO_NODE_CTX_PROVIDED <<
4698 ICE_AQC_LINK_TOPO_NODE_CTX_S);
4699
4700 addr = CPU_TO_LE16((u16)offset);
4701
4702 return ice_aq_read_i2c(hw, link_topo, 0, addr, 1, data, NULL);
4703}
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713enum ice_status
4714ice_write_pca9575_reg_e810t(struct ice_hw *hw, u8 offset, u8 data)
4715{
4716 struct ice_aqc_link_topo_addr link_topo;
4717 enum ice_status status;
4718 __le16 addr;
4719 u16 handle;
4720
4721 memset(&link_topo, 0, sizeof(link_topo));
4722
4723 status = ice_get_pca9575_handle(hw, &handle);
4724 if (status)
4725 return status;
4726
4727 link_topo.handle = CPU_TO_LE16(handle);
4728 link_topo.topo_params.node_type_ctx =
4729 (ICE_AQC_LINK_TOPO_NODE_CTX_PROVIDED <<
4730 ICE_AQC_LINK_TOPO_NODE_CTX_S);
4731
4732 addr = CPU_TO_LE16((u16)offset);
4733
4734 return ice_aq_write_i2c(hw, link_topo, 0, addr, 1, &data, NULL);
4735}
4736
4737
4738
4739
4740
4741
4742
4743
4744enum ice_status ice_read_sma_ctrl_e810t(struct ice_hw *hw, u8 *data)
4745{
4746 enum ice_status status;
4747 u16 handle;
4748 u8 i;
4749
4750 status = ice_get_pca9575_handle(hw, &handle);
4751 if (status)
4752 return status;
4753
4754 *data = 0;
4755
4756 for (i = ICE_E810T_SMA_MIN_BIT; i <= ICE_E810T_SMA_MAX_BIT; i++) {
4757 bool pin;
4758
4759 status = ice_aq_get_gpio(hw, handle, i + ICE_E810T_P1_OFFSET,
4760 &pin, NULL);
4761 if (status)
4762 break;
4763 *data |= (u8)(!pin) << i;
4764 }
4765
4766 return status;
4767}
4768
4769
4770
4771
4772
4773
4774
4775
4776enum ice_status ice_write_sma_ctrl_e810t(struct ice_hw *hw, u8 data)
4777{
4778 enum ice_status status;
4779 u16 handle;
4780 u8 i;
4781
4782 status = ice_get_pca9575_handle(hw, &handle);
4783 if (status)
4784 return status;
4785
4786 for (i = ICE_E810T_SMA_MIN_BIT; i <= ICE_E810T_SMA_MAX_BIT; i++) {
4787 bool pin;
4788
4789 pin = !(data & (1 << i));
4790 status = ice_aq_set_gpio(hw, handle, i + ICE_E810T_P1_OFFSET,
4791 pin, NULL);
4792 if (status)
4793 break;
4794 }
4795
4796 return status;
4797}
4798
4799
4800
4801
4802
4803
4804
4805bool ice_is_pca9575_present(struct ice_hw *hw)
4806{
4807 enum ice_status status;
4808 u16 handle = 0;
4809
4810 status = ice_get_pca9575_handle(hw, &handle);
4811 if (!status && handle)
4812 return true;
4813
4814 return false;
4815}
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839bool ice_ptp_lock(struct ice_hw *hw)
4840{
4841 u32 hw_lock;
4842 int i;
4843
4844#define MAX_TRIES 15
4845
4846 for (i = 0; i < MAX_TRIES; i++) {
4847 hw_lock = rd32(hw, PFTSYN_SEM + (PFTSYN_SEM_BYTES * hw->pf_id));
4848 hw_lock = hw_lock & PFTSYN_SEM_BUSY_M;
4849 if (hw_lock) {
4850
4851 ice_msec_delay(5, true);
4852 continue;
4853 }
4854
4855 break;
4856 }
4857
4858 return !hw_lock;
4859}
4860
4861
4862
4863
4864
4865
4866
4867
4868void ice_ptp_unlock(struct ice_hw *hw)
4869{
4870 wr32(hw, PFTSYN_SEM + (PFTSYN_SEM_BYTES * hw->pf_id), 0);
4871}
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884static enum ice_status
4885ice_ptp_tmr_cmd(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd, bool lock_sbq)
4886{
4887 enum ice_status status;
4888
4889
4890 ice_ptp_src_cmd(hw, cmd);
4891
4892
4893 switch (hw->phy_cfg) {
4894 case ICE_PHY_ETH56G:
4895 status = ice_ptp_port_cmd_eth56g(hw, cmd, lock_sbq);
4896 break;
4897 case ICE_PHY_E810:
4898 status = ice_ptp_port_cmd_e810(hw, cmd, lock_sbq);
4899 break;
4900 case ICE_PHY_E822:
4901 status = ice_ptp_port_cmd_e822(hw, cmd, lock_sbq);
4902 break;
4903 default:
4904 status = ICE_ERR_NOT_SUPPORTED;
4905 }
4906 if (status) {
4907 ice_debug(hw, ICE_DBG_PTP, "Failed to prepare PHY ports for timer command %u, status %d\n",
4908 cmd, status);
4909 return status;
4910 }
4911
4912
4913
4914
4915 ice_ptp_exec_tmr_cmd(hw);
4916 ice_ptp_clean_cmd(hw);
4917
4918 return ICE_SUCCESS;
4919}
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934enum ice_status ice_ptp_init_time(struct ice_hw *hw, u64 time)
4935{
4936 enum ice_status status;
4937 u8 tmr_idx;
4938
4939 tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
4940
4941
4942 wr32(hw, GLTSYN_SHTIME_L(tmr_idx), ICE_LO_DWORD(time));
4943 wr32(hw, GLTSYN_SHTIME_H(tmr_idx), ICE_HI_DWORD(time));
4944 wr32(hw, GLTSYN_SHTIME_0(tmr_idx), 0);
4945
4946
4947
4948 switch (hw->phy_cfg) {
4949 case ICE_PHY_ETH56G:
4950 status = ice_ptp_prep_phy_time_eth56g(hw, time & 0xFFFFFFFF);
4951 break;
4952 case ICE_PHY_E810:
4953 status = ice_ptp_prep_phy_time_e810(hw, time & 0xFFFFFFFF);
4954 break;
4955 case ICE_PHY_E822:
4956 status = ice_ptp_prep_phy_time_e822(hw, time & 0xFFFFFFFF);
4957 break;
4958 default:
4959 status = ICE_ERR_NOT_SUPPORTED;
4960 }
4961
4962 if (status)
4963 return status;
4964
4965 return ice_ptp_tmr_cmd(hw, ICE_PTP_INIT_TIME, true);
4966}
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982enum ice_status ice_ptp_write_incval(struct ice_hw *hw, u64 incval)
4983{
4984 enum ice_status status;
4985 u8 tmr_idx;
4986
4987 tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
4988
4989
4990 wr32(hw, GLTSYN_SHADJ_L(tmr_idx), ICE_LO_DWORD(incval));
4991 wr32(hw, GLTSYN_SHADJ_H(tmr_idx), ICE_HI_DWORD(incval));
4992
4993 switch (hw->phy_cfg) {
4994 case ICE_PHY_ETH56G:
4995 status = ice_ptp_prep_phy_incval_eth56g(hw, incval);
4996 break;
4997 case ICE_PHY_E810:
4998 status = ice_ptp_prep_phy_incval_e810(hw, incval);
4999 break;
5000 case ICE_PHY_E822:
5001 status = ice_ptp_prep_phy_incval_e822(hw, incval);
5002 break;
5003 default:
5004 status = ICE_ERR_NOT_SUPPORTED;
5005 }
5006
5007 if (status)
5008 return status;
5009
5010 return ice_ptp_tmr_cmd(hw, ICE_PTP_INIT_INCVAL, true);
5011}
5012
5013
5014
5015
5016
5017
5018
5019
5020enum ice_status ice_ptp_write_incval_locked(struct ice_hw *hw, u64 incval)
5021{
5022 enum ice_status status;
5023
5024 if (!ice_ptp_lock(hw))
5025 return ICE_ERR_NOT_READY;
5026
5027 status = ice_ptp_write_incval(hw, incval);
5028
5029 ice_ptp_unlock(hw);
5030
5031 return status;
5032}
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049enum ice_status ice_ptp_adj_clock(struct ice_hw *hw, s32 adj, bool lock_sbq)
5050{
5051 enum ice_status status;
5052 u8 tmr_idx;
5053
5054 tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
5055
5056
5057
5058
5059
5060
5061 wr32(hw, GLTSYN_SHADJ_L(tmr_idx), 0);
5062 wr32(hw, GLTSYN_SHADJ_H(tmr_idx), adj);
5063
5064 switch (hw->phy_cfg) {
5065 case ICE_PHY_ETH56G:
5066 status = ice_ptp_prep_phy_adj_eth56g(hw, adj, lock_sbq);
5067 break;
5068 case ICE_PHY_E810:
5069 status = ice_ptp_prep_phy_adj_e810(hw, adj, lock_sbq);
5070 break;
5071 case ICE_PHY_E822:
5072 status = ice_ptp_prep_phy_adj_e822(hw, adj, lock_sbq);
5073 break;
5074 default:
5075 status = ICE_ERR_NOT_SUPPORTED;
5076 }
5077
5078 if (status)
5079 return status;
5080
5081 return ice_ptp_tmr_cmd(hw, ICE_PTP_ADJ_TIME, lock_sbq);
5082}
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100enum ice_status
5101ice_ptp_adj_clock_at_time(struct ice_hw *hw, u64 at_time, s32 adj)
5102{
5103 enum ice_status status;
5104 u32 time_lo, time_hi;
5105 u8 tmr_idx;
5106
5107 tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
5108 time_lo = ICE_LO_DWORD(at_time);
5109 time_hi = ICE_HI_DWORD(at_time);
5110
5111
5112
5113
5114
5115
5116 wr32(hw, GLTSYN_SHADJ_L(tmr_idx), 0);
5117 wr32(hw, GLTSYN_SHADJ_H(tmr_idx), adj);
5118
5119
5120 wr32(hw, GLTSYN_SHTIME_0(tmr_idx), 0);
5121 wr32(hw, GLTSYN_SHTIME_L(tmr_idx), time_lo);
5122 wr32(hw, GLTSYN_SHTIME_H(tmr_idx), time_hi);
5123
5124
5125 switch (hw->phy_cfg) {
5126 case ICE_PHY_ETH56G:
5127 status = ice_ptp_prep_phy_adj_eth56g(hw, adj, true);
5128 break;
5129 case ICE_PHY_E810:
5130 status = ice_ptp_prep_phy_adj_e810(hw, adj, true);
5131 break;
5132 case ICE_PHY_E822:
5133 status = ice_ptp_prep_phy_adj_e822(hw, adj, true);
5134 break;
5135 default:
5136 status = ICE_ERR_NOT_SUPPORTED;
5137 }
5138
5139 if (status)
5140 return status;
5141
5142
5143 switch (hw->phy_cfg) {
5144 case ICE_PHY_ETH56G:
5145 status = ice_ptp_prep_phy_adj_target_eth56g(hw, time_lo);
5146 break;
5147 case ICE_PHY_E810:
5148 status = ice_ptp_prep_phy_adj_target_e810(hw, time_lo);
5149 break;
5150 case ICE_PHY_E822:
5151 status = ice_ptp_prep_phy_adj_target_e822(hw, time_lo);
5152 break;
5153 default:
5154 status = ICE_ERR_NOT_SUPPORTED;
5155 }
5156
5157 if (status)
5158 return status;
5159
5160 return ice_ptp_tmr_cmd(hw, ICE_PTP_ADJ_TIME_AT_TIME, true);
5161}
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174enum ice_status
5175ice_read_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx, u64 *tstamp)
5176{
5177 enum ice_status status;
5178
5179 switch (hw->phy_cfg) {
5180 case ICE_PHY_ETH56G:
5181 status = ice_read_phy_tstamp_eth56g(hw, block, idx, tstamp);
5182 break;
5183 case ICE_PHY_E810:
5184 status = ice_read_phy_tstamp_e810(hw, block, idx, tstamp);
5185 break;
5186 case ICE_PHY_E822:
5187 status = ice_read_phy_tstamp_e822(hw, block, idx, tstamp);
5188 break;
5189 default:
5190 status = ICE_ERR_NOT_SUPPORTED;
5191 }
5192
5193 return status;
5194}
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206enum ice_status
5207ice_clear_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx)
5208{
5209 enum ice_status status;
5210
5211 switch (hw->phy_cfg) {
5212 case ICE_PHY_ETH56G:
5213 status = ice_clear_phy_tstamp_eth56g(hw, block, idx);
5214 break;
5215 case ICE_PHY_E810:
5216 status = ice_clear_phy_tstamp_e810(hw, block, idx);
5217 break;
5218 case ICE_PHY_E822:
5219 status = ice_clear_phy_tstamp_e822(hw, block, idx);
5220 break;
5221 default:
5222 status = ICE_ERR_NOT_SUPPORTED;
5223 }
5224
5225 return status;
5226}
5227
5228
5229
5230
5231
5232
5233
5234enum ice_status ice_ptp_init_phc(struct ice_hw *hw)
5235{
5236 enum ice_status status;
5237 u8 src_idx = hw->func_caps.ts_func_info.tmr_index_owned;
5238
5239
5240 wr32(hw, GLTSYN_ENA(src_idx), GLTSYN_ENA_TSYN_ENA_M);
5241
5242
5243 (void)rd32(hw, GLTSYN_STAT(src_idx));
5244
5245 switch (hw->phy_cfg) {
5246 case ICE_PHY_ETH56G:
5247 status = ice_ptp_init_phc_eth56g(hw);
5248 break;
5249 case ICE_PHY_E810:
5250 status = ice_ptp_init_phc_e810(hw);
5251 break;
5252 case ICE_PHY_E822:
5253 status = ice_ptp_init_phc_e822(hw);
5254 break;
5255 default:
5256 status = ICE_ERR_NOT_SUPPORTED;
5257 }
5258
5259 return status;
5260}
5261