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