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