1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2001-2021 Intel Corporation
6 #include "ice_common.h"
7 #include "ice_ptp_hw.h"
8 #include "ice_ptp_consts.h"
11 /* Low level functions for interacting with and managing the device clock used
12 * for the Precision Time Protocol.
14 * The ice hardware represents the current time using three registers:
16 * GLTSYN_TIME_H GLTSYN_TIME_L GLTSYN_TIME_R
17 * +---------------+ +---------------+ +---------------+
18 * | 32 bits | | 32 bits | | 32 bits |
19 * +---------------+ +---------------+ +---------------+
21 * The registers are incremented every clock tick using a 40bit increment
22 * value defined over two registers:
24 * GLTSYN_INCVAL_H GLTSYN_INCVAL_L
25 * +---------------+ +---------------+
26 * | 8 bit s | | 32 bits |
27 * +---------------+ +---------------+
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
34 * For E810 devices, the increment frequency is 812.5 MHz
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:
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.
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.
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.
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.
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.
69 * Functions which only make sense on a single device family may not have
70 * a suitable generic implementation
74 * ice_get_ptp_src_clock_index - determine source clock index
75 * @hw: pointer to HW struct
77 * Determine the source clock index currently in use, based on device
78 * capabilities reported during initialization.
80 u8 ice_get_ptp_src_clock_index(struct ice_hw *hw)
82 return hw->func_caps.ts_func_info.tmr_index_assoc;
86 * ice_ptp_read_src_incval - Read source timer increment value
87 * @hw: pointer to HW struct
89 * Read the increment value of the source timer and return it.
91 u64 ice_ptp_read_src_incval(struct ice_hw *hw)
96 tmr_idx = ice_get_ptp_src_clock_index(hw);
98 lo = rd32(hw, GLTSYN_INCVAL_L(tmr_idx));
99 hi = rd32(hw, GLTSYN_INCVAL_H(tmr_idx));
101 return ((u64)(hi & INCVAL_HIGH_M) << 32) | lo;
105 * ice_ptp_exec_tmr_cmd - Execute all prepared timer commands
106 * @hw: pointer to HW struct
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.
112 static void ice_ptp_exec_tmr_cmd(struct ice_hw *hw)
114 wr32(hw, GLTSYN_CMD_SYNC, SYNC_EXEC_CMD);
118 /* E822 family functions
120 * The following functions operate on the E822 family of devices.
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
130 ice_fill_phy_msg_e822(struct ice_sbq_msg_input *msg, u8 port, u16 offset)
132 int phy_port, phy, quadtype;
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;
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);
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);
147 msg->dest_dev = rmn_0;
149 msg->dest_dev = rmn_1;
151 msg->dest_dev = rmn_2;
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
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.
163 static bool ice_is_64b_phy_reg_e822(u16 low_addr, u16 *high_addr)
166 case P_REG_PAR_PCS_TX_OFFSET_L:
167 *high_addr = P_REG_PAR_PCS_TX_OFFSET_U;
169 case P_REG_PAR_PCS_RX_OFFSET_L:
170 *high_addr = P_REG_PAR_PCS_RX_OFFSET_U;
172 case P_REG_PAR_TX_TIME_L:
173 *high_addr = P_REG_PAR_TX_TIME_U;
175 case P_REG_PAR_RX_TIME_L:
176 *high_addr = P_REG_PAR_RX_TIME_U;
178 case P_REG_TOTAL_TX_OFFSET_L:
179 *high_addr = P_REG_TOTAL_TX_OFFSET_U;
181 case P_REG_TOTAL_RX_OFFSET_L:
182 *high_addr = P_REG_TOTAL_RX_OFFSET_U;
184 case P_REG_UIX66_10G_40G_L:
185 *high_addr = P_REG_UIX66_10G_40G_U;
187 case P_REG_UIX66_25G_100G_L:
188 *high_addr = P_REG_UIX66_25G_100G_U;
190 case P_REG_TX_CAPTURE_L:
191 *high_addr = P_REG_TX_CAPTURE_U;
193 case P_REG_RX_CAPTURE_L:
194 *high_addr = P_REG_RX_CAPTURE_U;
196 case P_REG_TX_TIMER_INC_PRE_L:
197 *high_addr = P_REG_TX_TIMER_INC_PRE_U;
199 case P_REG_RX_TIMER_INC_PRE_L:
200 *high_addr = P_REG_RX_TIMER_INC_PRE_U;
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
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.
217 static bool ice_is_40b_phy_reg_e822(u16 low_addr, u16 *high_addr)
220 case P_REG_TIMETUS_L:
221 *high_addr = P_REG_TIMETUS_U;
223 case P_REG_PAR_RX_TUS_L:
224 *high_addr = P_REG_PAR_RX_TUS_U;
226 case P_REG_PAR_TX_TUS_L:
227 *high_addr = P_REG_PAR_TX_TUS_U;
229 case P_REG_PCS_RX_TUS_L:
230 *high_addr = P_REG_PCS_RX_TUS_U;
232 case P_REG_PCS_TX_TUS_L:
233 *high_addr = P_REG_PCS_TX_TUS_U;
235 case P_REG_DESK_PAR_RX_TUS_L:
236 *high_addr = P_REG_DESK_PAR_RX_TUS_U;
238 case P_REG_DESK_PAR_TX_TUS_L:
239 *high_addr = P_REG_DESK_PAR_TX_TUS_U;
241 case P_REG_DESK_PCS_RX_TUS_L:
242 *high_addr = P_REG_DESK_PCS_RX_TUS_U;
244 case P_REG_DESK_PCS_TX_TUS_L:
245 *high_addr = P_REG_DESK_PCS_TX_TUS_U;
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
260 * Read a PHY register for the given port over the device sideband queue.
262 static enum ice_status
263 ice_read_phy_reg_e822_lp(struct ice_hw *hw, u8 port, u16 offset, u32 *val,
266 struct ice_sbq_msg_input msg = {0};
267 enum ice_status status;
269 ice_fill_phy_msg_e822(&msg, port, offset);
270 msg.opcode = ice_sbq_msg_rd;
272 status = ice_sbq_rw_reg_lp(hw, &msg, lock_sbq);
274 ice_debug(hw, ICE_DBG_PTP, "Failed to send message to phy, status %d\n",
285 ice_read_phy_reg_e822(struct ice_hw *hw, u8 port, u16 offset, u32 *val)
287 return ice_read_phy_reg_e822_lp(hw, port, offset, val, true);
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
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.
302 static enum ice_status
303 ice_read_40b_phy_reg_e822(struct ice_hw *hw, u8 port, u16 low_addr, u64 *val)
305 enum ice_status status;
309 /* Only operate on registers known to be split into two 32bit
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",
315 return ICE_ERR_PARAM;
318 status = ice_read_phy_reg_e822(hw, port, low_addr, &low);
320 ice_debug(hw, ICE_DBG_PTP, "Failed to read from low register 0x%08x\n, status %d",
325 status = ice_read_phy_reg_e822(hw, port, high_addr, &high);
327 ice_debug(hw, ICE_DBG_PTP, "Failed to read from high register 0x%08x\n, status %d",
332 *val = (u64)high << P_REG_40B_HIGH_S | (low & P_REG_40B_LOW_M);
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
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.
349 static enum ice_status
350 ice_read_64b_phy_reg_e822(struct ice_hw *hw, u8 port, u16 low_addr, u64 *val)
352 enum ice_status status;
356 /* Only operate on registers known to be split into two 32bit
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",
362 return ICE_ERR_PARAM;
365 status = ice_read_phy_reg_e822(hw, port, low_addr, &low);
367 ice_debug(hw, ICE_DBG_PTP, "Failed to read from low register 0x%08x\n, status %d",
372 status = ice_read_phy_reg_e822(hw, port, high_addr, &high);
374 ice_debug(hw, ICE_DBG_PTP, "Failed to read from high register 0x%08x\n, status %d",
379 *val = (u64)high << 32 | low;
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
392 * Write a PHY register for the given port over the device sideband queue.
394 static enum ice_status
395 ice_write_phy_reg_e822_lp(struct ice_hw *hw, u8 port, u16 offset, u32 val,
398 struct ice_sbq_msg_input msg = {0};
399 enum ice_status status;
401 ice_fill_phy_msg_e822(&msg, port, offset);
402 msg.opcode = ice_sbq_msg_wr;
405 status = ice_sbq_rw_reg_lp(hw, &msg, lock_sbq);
407 ice_debug(hw, ICE_DBG_PTP, "Failed to send message to phy, status %d\n",
416 ice_write_phy_reg_e822(struct ice_hw *hw, u8 port, u16 offset, u32 val)
418 return ice_write_phy_reg_e822_lp(hw, port, offset, val, true);
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
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.
431 static enum ice_status
432 ice_write_40b_phy_reg_e822(struct ice_hw *hw, u8 port, u16 low_addr, u64 val)
434 enum ice_status status;
438 /* Only operate on registers known to be split into a lower 8 bit
439 * register and an upper 32 bit register.
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",
444 return ICE_ERR_PARAM;
447 low = (u32)(val & P_REG_40B_LOW_M);
448 high = (u32)(val >> P_REG_40B_HIGH_S);
450 status = ice_write_phy_reg_e822(hw, port, low_addr, low);
452 ice_debug(hw, ICE_DBG_PTP, "Failed to write to low register 0x%08x\n, status %d",
457 status = ice_write_phy_reg_e822(hw, port, high_addr, high);
459 ice_debug(hw, ICE_DBG_PTP, "Failed to write to high register 0x%08x\n, status %d",
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
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
479 static enum ice_status
480 ice_write_64b_phy_reg_e822(struct ice_hw *hw, u8 port, u16 low_addr, u64 val)
482 enum ice_status status;
486 /* Only operate on registers known to be split into two 32bit
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",
492 return ICE_ERR_PARAM;
495 low = ICE_LO_DWORD(val);
496 high = ICE_HI_DWORD(val);
498 status = ice_write_phy_reg_e822(hw, port, low_addr, low);
500 ice_debug(hw, ICE_DBG_PTP, "Failed to write to low register 0x%08x\n, status %d",
505 status = ice_write_phy_reg_e822(hw, port, high_addr, high);
507 ice_debug(hw, ICE_DBG_PTP, "Failed to write to high register 0x%08x\n, status %d",
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
521 * Fill a message buffer for accessing a register in a quad shared between
525 ice_fill_quad_msg_e822(struct ice_sbq_msg_input *msg, u8 quad, u16 offset)
529 msg->dest_dev = rmn_0;
531 if ((quad % ICE_NUM_QUAD_TYPE) == 0)
532 addr = Q_0_BASE + offset;
534 addr = Q_1_BASE + offset;
536 msg->msg_addr_low = ICE_LO_WORD(addr);
537 msg->msg_addr_high = ICE_HI_WORD(addr);
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
548 * Read a quad register over the device sideband queue. Quad registers are
549 * shared between multiple PHYs.
551 static enum ice_status
552 ice_read_quad_reg_e822_lp(struct ice_hw *hw, u8 quad, u16 offset, u32 *val,
555 struct ice_sbq_msg_input msg = {0};
556 enum ice_status status;
558 if (quad >= ICE_MAX_QUAD)
559 return ICE_ERR_PARAM;
561 ice_fill_quad_msg_e822(&msg, quad, offset);
562 msg.opcode = ice_sbq_msg_rd;
564 status = ice_sbq_rw_reg_lp(hw, &msg, lock_sbq);
566 ice_debug(hw, ICE_DBG_PTP, "Failed to send message to phy, status %d\n",
577 ice_read_quad_reg_e822(struct ice_hw *hw, u8 quad, u16 offset, u32 *val)
579 return ice_read_quad_reg_e822_lp(hw, quad, offset, val, true);
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
590 * Write a quad register over the device sideband queue. Quad registers are
591 * shared between multiple PHYs.
593 static enum ice_status
594 ice_write_quad_reg_e822_lp(struct ice_hw *hw, u8 quad, u16 offset, u32 val,
597 struct ice_sbq_msg_input msg = {0};
598 enum ice_status status;
600 if (quad >= ICE_MAX_QUAD)
601 return ICE_ERR_PARAM;
603 ice_fill_quad_msg_e822(&msg, quad, offset);
604 msg.opcode = ice_sbq_msg_wr;
607 status = ice_sbq_rw_reg_lp(hw, &msg, lock_sbq);
609 ice_debug(hw, ICE_DBG_PTP, "Failed to send message to phy, status %d\n",
618 ice_write_quad_reg_e822(struct ice_hw *hw, u8 quad, u16 offset, u32 val)
620 return ice_write_quad_reg_e822_lp(hw, quad, offset, val, true);
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
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
634 static enum ice_status
635 ice_read_phy_tstamp_e822(struct ice_hw *hw, u8 quad, u8 idx, u64 *tstamp)
637 enum ice_status status;
638 u16 lo_addr, hi_addr;
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);
644 status = ice_read_quad_reg_e822(hw, quad, lo_addr, &lo);
646 ice_debug(hw, ICE_DBG_PTP, "Failed to read low PTP timestamp register, status %d\n",
651 status = ice_read_quad_reg_e822(hw, quad, hi_addr, &hi);
653 ice_debug(hw, ICE_DBG_PTP, "Failed to read high PTP timestamp register, status %d\n",
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
662 *tstamp = ((u64)hi) << TS_PHY_HIGH_S | ((u64)lo & TS_PHY_LOW_M);
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
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.
676 static enum ice_status
677 ice_clear_phy_tstamp_e822(struct ice_hw *hw, u8 quad, u8 idx)
679 enum ice_status status;
680 u16 lo_addr, hi_addr;
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);
685 status = ice_write_quad_reg_e822(hw, quad, lo_addr, 0);
687 ice_debug(hw, ICE_DBG_PTP, "Failed to clear low PTP timestamp register, status %d\n",
692 status = ice_write_quad_reg_e822(hw, quad, hi_addr, 0);
694 ice_debug(hw, ICE_DBG_PTP, "Failed to clear high PTP timestamp register, status %d\n",
703 * ice_ptp_prep_phy_time_e822 - Prepare PHY port with initial time
704 * @hw: pointer to the HW struct
705 * @time: Time to initialize the PHY port clocks to
707 * Program the PHY port registers with a new initial time value. The port
708 * clock will be initialized once the driver issues an INIT_TIME sync
709 * command. The time value is the upper 32 bits of the PHY timer, usually in
710 * units of nominal nanoseconds.
712 static enum ice_status
713 ice_ptp_prep_phy_time_e822(struct ice_hw *hw, u32 time)
715 enum ice_status status;
719 /* The time represents the upper 32 bits of the PHY timer, so we need
720 * to shift to account for this when programming.
722 phy_time = (u64)time << 32;
724 for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
727 status = ice_write_64b_phy_reg_e822(hw, port,
728 P_REG_TX_TIMER_INC_PRE_L,
734 status = ice_write_64b_phy_reg_e822(hw, port,
735 P_REG_RX_TIMER_INC_PRE_L,
744 ice_debug(hw, ICE_DBG_PTP, "Failed to write init time for port %u, status %d\n",
751 * ice_ptp_prep_port_adj_e822 - Prepare a single port for time adjust
752 * @hw: pointer to HW struct
753 * @port: Port number to be programmed
754 * @time: time in cycles to adjust the port Tx and Rx clocks
755 * @lock_sbq: true to lock the sbq sq_lock (the usual case); false if the
756 * sq_lock has already been locked at a higher level
758 * Program the port for an atomic adjustment by writing the Tx and Rx timer
759 * registers. The atomic adjustment won't be completed until the driver issues
760 * an ADJ_TIME command.
762 * Note that time is not in units of nanoseconds. It is in clock time
763 * including the lower sub-nanosecond portion of the port timer.
765 * Negative adjustments are supported using 2s complement arithmetic.
768 ice_ptp_prep_port_adj_e822(struct ice_hw *hw, u8 port, s64 time,
771 enum ice_status status;
774 l_time = ICE_LO_DWORD(time);
775 u_time = ICE_HI_DWORD(time);
778 status = ice_write_phy_reg_e822_lp(hw, port, P_REG_TX_TIMER_INC_PRE_L,
783 status = ice_write_phy_reg_e822_lp(hw, port, P_REG_TX_TIMER_INC_PRE_U,
789 status = ice_write_phy_reg_e822_lp(hw, port, P_REG_RX_TIMER_INC_PRE_L,
794 status = ice_write_phy_reg_e822_lp(hw, port, P_REG_RX_TIMER_INC_PRE_U,
802 ice_debug(hw, ICE_DBG_PTP, "Failed to write time adjust for port %u, status %d\n",
808 * ice_ptp_prep_phy_adj_e822 - Prep PHY ports for a time adjustment
809 * @hw: pointer to HW struct
810 * @adj: adjustment in nanoseconds
811 * @lock_sbq: true to lock the sbq sq_lock (the usual case); false if the
812 * sq_lock has already been locked at a higher level
814 * Prepare the PHY ports for an atomic time adjustment by programming the PHY
815 * Tx and Rx port registers. The actual adjustment is completed by issuing an
816 * ADJ_TIME or ADJ_TIME_AT_TIME sync command.
818 static enum ice_status
819 ice_ptp_prep_phy_adj_e822(struct ice_hw *hw, s32 adj, bool lock_sbq)
824 /* The port clock supports adjustment of the sub-nanosecond portion of
825 * the clock. We shift the provided adjustment in nanoseconds to
826 * calculate the appropriate adjustment to program into the PHY ports.
829 cycles = (s64)adj << 32;
831 cycles = -(((s64)-adj) << 32);
833 for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
834 enum ice_status status;
836 status = ice_ptp_prep_port_adj_e822(hw, port, cycles,
846 * ice_ptp_prep_phy_incval_e822 - Prepare PHY ports for time adjustment
847 * @hw: pointer to HW struct
848 * @incval: new increment value to prepare
850 * Prepare each of the PHY ports for a new increment value by programming the
851 * port's TIMETUS registers. The new increment value will be updated after
852 * issuing an INIT_INCVAL command.
854 static enum ice_status
855 ice_ptp_prep_phy_incval_e822(struct ice_hw *hw, u64 incval)
857 enum ice_status status;
860 for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
861 status = ice_write_40b_phy_reg_e822(hw, port, P_REG_TIMETUS_L,
870 ice_debug(hw, ICE_DBG_PTP, "Failed to write incval for port %u, status %d\n",
877 * ice_ptp_read_phy_incval_e822 - Read a PHY port's current incval
878 * @hw: pointer to the HW struct
879 * @port: the port to read
880 * @incval: on return, the time_clk_cyc incval for this port
882 * Read the time_clk_cyc increment value for a given PHY port.
885 ice_ptp_read_phy_incval_e822(struct ice_hw *hw, u8 port, u64 *incval)
887 enum ice_status status;
889 status = ice_read_40b_phy_reg_e822(hw, port, P_REG_TIMETUS_L, incval);
891 ice_debug(hw, ICE_DBG_PTP, "Failed to read TIMETUS_L, status %d\n",
896 ice_debug(hw, ICE_DBG_PTP, "read INCVAL = 0x%016llx\n",
897 (unsigned long long)*incval);
903 * ice_ptp_prep_phy_adj_target_e822 - Prepare PHY for adjust at target time
904 * @hw: pointer to HW struct
905 * @target_time: target time to program
907 * Program the PHY port Tx and Rx TIMER_CNT_ADJ registers used for the
908 * ADJ_TIME_AT_TIME command. This should be used in conjunction with
909 * ice_ptp_prep_phy_adj_e822 to program an atomic adjustment that is
910 * delayed until a specified target time.
912 * Note that a target time adjustment is not currently supported on E810
915 static enum ice_status
916 ice_ptp_prep_phy_adj_target_e822(struct ice_hw *hw, u32 target_time)
918 enum ice_status status;
921 for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
924 /* No sub-nanoseconds data */
925 status = ice_write_phy_reg_e822_lp(hw, port,
926 P_REG_TX_TIMER_CNT_ADJ_L,
931 status = ice_write_phy_reg_e822_lp(hw, port,
932 P_REG_TX_TIMER_CNT_ADJ_U,
938 /* No sub-nanoseconds data */
939 status = ice_write_phy_reg_e822_lp(hw, port,
940 P_REG_RX_TIMER_CNT_ADJ_L,
945 status = ice_write_phy_reg_e822_lp(hw, port,
946 P_REG_RX_TIMER_CNT_ADJ_U,
955 ice_debug(hw, ICE_DBG_PTP, "Failed to write target time for port %u, status %d\n",
962 * ice_ptp_read_port_capture - Read a port's local time capture
963 * @hw: pointer to HW struct
964 * @port: Port number to read
965 * @tx_ts: on return, the Tx port time capture
966 * @rx_ts: on return, the Rx port time capture
968 * Read the port's Tx and Rx local time capture values.
970 * Note this has no equivalent for the E810 devices.
973 ice_ptp_read_port_capture(struct ice_hw *hw, u8 port, u64 *tx_ts, u64 *rx_ts)
975 enum ice_status status;
978 status = ice_read_64b_phy_reg_e822(hw, port, P_REG_TX_CAPTURE_L, tx_ts);
980 ice_debug(hw, ICE_DBG_PTP, "Failed to read REG_TX_CAPTURE, status %d\n",
985 ice_debug(hw, ICE_DBG_PTP, "tx_init = 0x%016llx\n",
986 (unsigned long long)*tx_ts);
989 status = ice_read_64b_phy_reg_e822(hw, port, P_REG_RX_CAPTURE_L, rx_ts);
991 ice_debug(hw, ICE_DBG_PTP, "Failed to read RX_CAPTURE, status %d\n",
996 ice_debug(hw, ICE_DBG_PTP, "rx_init = 0x%016llx\n",
997 (unsigned long long)*rx_ts);
1003 * ice_ptp_one_port_cmd - Prepare a single PHY port for a timer command
1004 * @hw: pointer to HW struct
1005 * @port: Port to which cmd has to be sent
1006 * @cmd: Command to be sent to the port
1007 * @lock_sbq: true if the sideband queue lock must be acquired
1009 * Prepare the requested port for an upcoming timer sync command.
1011 * Note there is no equivalent of this operation on E810, as that device
1012 * always handles all external PHYs internally.
1015 ice_ptp_one_port_cmd(struct ice_hw *hw, u8 port, enum ice_ptp_tmr_cmd cmd,
1018 enum ice_status status;
1022 tmr_idx = ice_get_ptp_src_clock_index(hw);
1023 cmd_val = tmr_idx << SEL_PHY_SRC;
1026 cmd_val |= PHY_CMD_INIT_TIME;
1029 cmd_val |= PHY_CMD_INIT_INCVAL;
1032 cmd_val |= PHY_CMD_ADJ_TIME;
1034 case ADJ_TIME_AT_TIME:
1035 cmd_val |= PHY_CMD_ADJ_TIME_AT_TIME;
1038 cmd_val |= PHY_CMD_READ_TIME;
1041 ice_warn(hw, "Unknown timer command %u\n", cmd);
1042 return ICE_ERR_PARAM;
1046 /* Read, modify, write */
1047 status = ice_read_phy_reg_e822_lp(hw, port, P_REG_TX_TMR_CMD, &val,
1050 ice_debug(hw, ICE_DBG_PTP, "Failed to read TX_TMR_CMD, status %d\n",
1055 /* Modify necessary bits only and perform write */
1056 val &= ~TS_CMD_MASK;
1059 status = ice_write_phy_reg_e822_lp(hw, port, P_REG_TX_TMR_CMD, val,
1062 ice_debug(hw, ICE_DBG_PTP, "Failed to write back TX_TMR_CMD, status %d\n",
1068 /* Read, modify, write */
1069 status = ice_read_phy_reg_e822_lp(hw, port, P_REG_RX_TMR_CMD, &val,
1072 ice_debug(hw, ICE_DBG_PTP, "Failed to read RX_TMR_CMD, status %d\n",
1077 /* Modify necessary bits only and perform write */
1078 val &= ~TS_CMD_MASK;
1081 status = ice_write_phy_reg_e822_lp(hw, port, P_REG_RX_TMR_CMD, val,
1084 ice_debug(hw, ICE_DBG_PTP, "Failed to write back RX_TMR_CMD, status %d\n",
1093 * ice_ptp_port_cmd_e822 - Prepare all ports for a timer command
1094 * @hw: pointer to the HW struct
1095 * @cmd: timer command to prepare
1096 * @lock_sbq: true if the sideband queue lock must be acquired
1098 * Prepare all ports connected to this device for an upcoming timer sync
1101 static enum ice_status
1102 ice_ptp_port_cmd_e822(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd,
1107 for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
1108 enum ice_status status;
1110 status = ice_ptp_one_port_cmd(hw, port, cmd, lock_sbq);
1118 /* E822 Vernier calibration functions
1120 * The following functions are used as part of the vernier calibration of
1121 * a port. This calibration increases the precision of the timestamps on the
1126 * ice_ptp_set_vernier_wl - Set the window length for vernier calibration
1127 * @hw: pointer to the HW struct
1129 * Set the window length used for the vernier port calibration process.
1131 enum ice_status ice_ptp_set_vernier_wl(struct ice_hw *hw)
1135 for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) {
1136 enum ice_status status;
1138 status = ice_write_phy_reg_e822_lp(hw, port, P_REG_WL,
1139 PTP_VERNIER_WL, true);
1141 ice_debug(hw, ICE_DBG_PTP, "Failed to set vernier window length for port %u, status %d\n",
1151 * ice_phy_get_speed_and_fec_e822 - Get link speed and FEC based on serdes mode
1152 * @hw: pointer to HW struct
1153 * @port: the port to read from
1154 * @link_out: if non-NULL, holds link speed on success
1155 * @fec_out: if non-NULL, holds FEC algorithm on success
1157 * Read the serdes data for the PHY port and extract the link speed and FEC
1161 ice_phy_get_speed_and_fec_e822(struct ice_hw *hw, u8 port,
1162 enum ice_ptp_link_spd *link_out,
1163 enum ice_ptp_fec_mode *fec_out)
1165 enum ice_ptp_link_spd link;
1166 enum ice_ptp_fec_mode fec;
1167 enum ice_status status;
1170 status = ice_read_phy_reg_e822(hw, port, P_REG_LINK_SPEED, &serdes);
1172 ice_debug(hw, ICE_DBG_PTP, "Failed to read serdes info\n");
1176 /* Determine the FEC algorithm */
1177 fec = (enum ice_ptp_fec_mode)P_REG_LINK_SPEED_FEC_MODE(serdes);
1179 serdes &= P_REG_LINK_SPEED_SERDES_M;
1181 /* Determine the link speed */
1182 if (fec == ICE_PTP_FEC_MODE_RS_FEC) {
1184 case ICE_PTP_SERDES_25G:
1185 link = ICE_PTP_LNK_SPD_25G_RS;
1187 case ICE_PTP_SERDES_50G:
1188 link = ICE_PTP_LNK_SPD_50G_RS;
1190 case ICE_PTP_SERDES_100G:
1191 link = ICE_PTP_LNK_SPD_100G_RS;
1194 return ICE_ERR_OUT_OF_RANGE;
1198 case ICE_PTP_SERDES_1G:
1199 link = ICE_PTP_LNK_SPD_1G;
1201 case ICE_PTP_SERDES_10G:
1202 link = ICE_PTP_LNK_SPD_10G;
1204 case ICE_PTP_SERDES_25G:
1205 link = ICE_PTP_LNK_SPD_25G;
1207 case ICE_PTP_SERDES_40G:
1208 link = ICE_PTP_LNK_SPD_40G;
1210 case ICE_PTP_SERDES_50G:
1211 link = ICE_PTP_LNK_SPD_50G;
1214 return ICE_ERR_OUT_OF_RANGE;
1227 * ice_phy_cfg_lane_e822 - Configure PHY quad for single/multi-lane timestamp
1228 * @hw: pointer to HW struct
1229 * @port: to configure the quad for
1231 void ice_phy_cfg_lane_e822(struct ice_hw *hw, u8 port)
1233 enum ice_ptp_link_spd link_spd;
1234 enum ice_status status;
1238 status = ice_phy_get_speed_and_fec_e822(hw, port, &link_spd, NULL);
1240 ice_debug(hw, ICE_DBG_PTP, "Failed to get PHY link speed, status %d\n",
1245 quad = port / ICE_PORTS_PER_QUAD;
1247 status = ice_read_quad_reg_e822(hw, quad, Q_REG_TX_MEM_GBL_CFG, &val);
1249 ice_debug(hw, ICE_DBG_PTP, "Failed to read TX_MEM_GLB_CFG, status %d\n",
1254 if (link_spd >= ICE_PTP_LNK_SPD_40G)
1255 val &= ~Q_REG_TX_MEM_GBL_CFG_LANE_TYPE_M;
1257 val |= Q_REG_TX_MEM_GBL_CFG_LANE_TYPE_M;
1259 status = ice_write_quad_reg_e822(hw, quad, Q_REG_TX_MEM_GBL_CFG, val);
1261 ice_debug(hw, ICE_DBG_PTP, "Failed to write back TX_MEM_GBL_CFG, status %d\n",
1269 * The following functions operate on the E810 series devices which use
1270 * a separate external PHY.
1274 * ice_read_phy_reg_e810_lp - Read register from external PHY on E810
1275 * @hw: pointer to the HW struct
1276 * @addr: the address to read from
1277 * @val: On return, the value read from the PHY
1278 * @lock_sbq: true if the sideband queue lock must be acquired
1280 * Read a register from the external PHY on the E810 device.
1282 static enum ice_status
1283 ice_read_phy_reg_e810_lp(struct ice_hw *hw, u32 addr, u32 *val, bool lock_sbq)
1285 struct ice_sbq_msg_input msg = {0};
1286 enum ice_status status;
1288 msg.msg_addr_low = ICE_LO_WORD(addr);
1289 msg.msg_addr_high = ICE_HI_WORD(addr);
1290 msg.opcode = ice_sbq_msg_rd;
1291 msg.dest_dev = rmn_0;
1293 status = ice_sbq_rw_reg_lp(hw, &msg, lock_sbq);
1295 ice_debug(hw, ICE_DBG_PTP, "Failed to send message to phy, status %d\n",
1305 static enum ice_status
1306 ice_read_phy_reg_e810(struct ice_hw *hw, u32 addr, u32 *val)
1308 return ice_read_phy_reg_e810_lp(hw, addr, val, true);
1312 * ice_write_phy_reg_e810_lp - Write register on external PHY on E810
1313 * @hw: pointer to the HW struct
1314 * @addr: the address to writem to
1315 * @val: the value to write to the PHY
1316 * @lock_sbq: true if the sideband queue lock must be acquired
1318 * Write a value to a register of the external PHY on the E810 device.
1320 static enum ice_status
1321 ice_write_phy_reg_e810_lp(struct ice_hw *hw, u32 addr, u32 val, bool lock_sbq)
1323 struct ice_sbq_msg_input msg = {0};
1324 enum ice_status status;
1326 msg.msg_addr_low = ICE_LO_WORD(addr);
1327 msg.msg_addr_high = ICE_HI_WORD(addr);
1328 msg.opcode = ice_sbq_msg_wr;
1329 msg.dest_dev = rmn_0;
1332 status = ice_sbq_rw_reg_lp(hw, &msg, lock_sbq);
1334 ice_debug(hw, ICE_DBG_PTP, "Failed to send message to phy, status %d\n",
1342 static enum ice_status
1343 ice_write_phy_reg_e810(struct ice_hw *hw, u32 addr, u32 val)
1345 return ice_write_phy_reg_e810_lp(hw, addr, val, true);
1349 * ice_read_phy_tstamp_e810 - Read a PHY timestamp out of the external PHY
1350 * @hw: pointer to the HW struct
1351 * @lport: the lport to read from
1352 * @idx: the timestamp index to read
1353 * @tstamp: on return, the 40bit timestamp value
1355 * Read a 40bit timestamp value out of the timestamp block of the external PHY
1356 * on the E810 device.
1358 static enum ice_status
1359 ice_read_phy_tstamp_e810(struct ice_hw *hw, u8 lport, u8 idx, u64 *tstamp)
1361 enum ice_status status;
1362 u32 lo_addr, hi_addr, lo, hi;
1364 lo_addr = TS_EXT(LOW_TX_MEMORY_BANK_START, lport, idx);
1365 hi_addr = TS_EXT(HIGH_TX_MEMORY_BANK_START, lport, idx);
1367 status = ice_read_phy_reg_e810(hw, lo_addr, &lo);
1369 ice_debug(hw, ICE_DBG_PTP, "Failed to read low PTP timestamp register, status %d\n",
1374 status = ice_read_phy_reg_e810(hw, hi_addr, &hi);
1376 ice_debug(hw, ICE_DBG_PTP, "Failed to read high PTP timestamp register, status %d\n",
1381 /* For E810 devices, the timestamp is reported with the lower 32 bits
1382 * in the low register, and the upper 8 bits in the high register.
1384 *tstamp = ((u64)hi) << TS_HIGH_S | ((u64)lo & TS_LOW_M);
1390 * ice_clear_phy_tstamp_e810 - Clear a timestamp from the external PHY
1391 * @hw: pointer to the HW struct
1392 * @lport: the lport to read from
1393 * @idx: the timestamp index to reset
1395 * Clear a timestamp, resetting its valid bit, from the timestamp block of the
1396 * external PHY on the E810 device.
1398 static enum ice_status
1399 ice_clear_phy_tstamp_e810(struct ice_hw *hw, u8 lport, u8 idx)
1401 enum ice_status status;
1402 u32 lo_addr, hi_addr;
1404 lo_addr = TS_EXT(LOW_TX_MEMORY_BANK_START, lport, idx);
1405 hi_addr = TS_EXT(HIGH_TX_MEMORY_BANK_START, lport, idx);
1407 status = ice_write_phy_reg_e810(hw, lo_addr, 0);
1409 ice_debug(hw, ICE_DBG_PTP, "Failed to clear low PTP timestamp register, status %d\n",
1414 status = ice_write_phy_reg_e810(hw, hi_addr, 0);
1416 ice_debug(hw, ICE_DBG_PTP, "Failed to clear high PTP timestamp register, status %d\n",
1425 * ice_ptp_init_phy_e810 - Enable PTP function on the external PHY
1426 * @hw: pointer to HW struct
1428 * Enable the timesync PTP functionality for the external PHY connected to
1431 * Note there is no equivalent function needed on E822 based devices.
1433 enum ice_status ice_ptp_init_phy_e810(struct ice_hw *hw)
1435 enum ice_status status;
1438 tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
1439 status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_ENA(tmr_idx),
1440 GLTSYN_ENA_TSYN_ENA_M);
1442 ice_debug(hw, ICE_DBG_PTP, "PTP failed in ena_phy_time_syn %d\n",
1449 * ice_ptp_prep_phy_time_e810 - Prepare PHY port with initial time
1450 * @hw: Board private structure
1451 * @time: Time to initialize the PHY port clock to
1453 * Program the PHY port ETH_GLTSYN_SHTIME registers in preparation setting the
1454 * initial clock time. The time will not actually be programmed until the
1455 * driver issues an INIT_TIME command.
1457 * The time value is the upper 32 bits of the PHY timer, usually in units of
1458 * nominal nanoseconds.
1460 static enum ice_status ice_ptp_prep_phy_time_e810(struct ice_hw *hw, u32 time)
1462 enum ice_status status;
1465 tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
1466 status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHTIME_0(tmr_idx), 0);
1468 ice_debug(hw, ICE_DBG_PTP, "Failed to write SHTIME_0, status %d\n",
1473 status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHTIME_L(tmr_idx), time);
1475 ice_debug(hw, ICE_DBG_PTP, "Failed to write SHTIME_L, status %d\n",
1484 * ice_ptp_prep_phy_adj_e810 - Prep PHY port for a time adjustment
1485 * @hw: pointer to HW struct
1486 * @adj: adjustment value to program
1487 * @lock_sbq: true if the sideband queue luck must be acquired
1489 * Prepare the PHY port for an atomic adjustment by programming the PHY
1490 * ETH_GLTSYN_SHADJ_L and ETH_GLTSYN_SHADJ_H registers. The actual adjustment
1491 * is completed by issuing an ADJ_TIME sync command.
1493 * The adjustment value only contains the portion used for the upper 32bits of
1494 * the PHY timer, usually in units of nominal nanoseconds. Negative
1495 * adjustments are supported using 2s complement arithmetic.
1497 static enum ice_status
1498 ice_ptp_prep_phy_adj_e810(struct ice_hw *hw, s32 adj, bool lock_sbq)
1500 enum ice_status status;
1503 tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
1505 /* Adjustments are represented as signed 2's complement values in
1506 * nanoseconds. Sub-nanosecond adjustment is not supported.
1508 status = ice_write_phy_reg_e810_lp(hw, ETH_GLTSYN_SHADJ_L(tmr_idx),
1511 ice_debug(hw, ICE_DBG_PTP, "Failed to write adj to PHY SHADJ_L, status %d\n",
1516 status = ice_write_phy_reg_e810_lp(hw, ETH_GLTSYN_SHADJ_H(tmr_idx),
1519 ice_debug(hw, ICE_DBG_PTP, "Failed to write adj to PHY SHADJ_H, status %d\n",
1528 * ice_ptp_prep_phy_incval_e810 - Prep PHY port increment value change
1529 * @hw: pointer to HW struct
1530 * @incval: The new 40bit increment value to prepare
1532 * Prepare the PHY port for a new increment value by programming the PHY
1533 * ETH_GLTSYN_SHADJ_L and ETH_GLTSYN_SHADJ_H registers. The actual change is
1534 * completed by issuing an INIT_INCVAL command.
1536 static enum ice_status
1537 ice_ptp_prep_phy_incval_e810(struct ice_hw *hw, u64 incval)
1539 enum ice_status status;
1543 tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
1544 low = ICE_LO_DWORD(incval);
1545 high = ICE_HI_DWORD(incval);
1547 status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHADJ_L(tmr_idx), low);
1549 ice_debug(hw, ICE_DBG_PTP, "Failed to write incval to PHY SHADJ_L, status %d\n",
1554 status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHADJ_H(tmr_idx), high);
1556 ice_debug(hw, ICE_DBG_PTP, "Failed to write incval PHY SHADJ_H, status %d\n",
1565 * ice_ptp_prep_phy_adj_target_e810 - Prepare PHY port with adjust target
1566 * @hw: Board private structure
1567 * @target_time: Time to trigger the clock adjustment at
1569 * Program the PHY port ETH_GLTSYN_SHTIME registers in preparation for
1570 * a target time adjust, which will trigger an adjustment of the clock in the
1571 * future. The actual adjustment will occur the next time the PHY port timer
1572 * crosses over the provided value after the driver issues an ADJ_TIME_AT_TIME
1575 * The time value is the upper 32 bits of the PHY timer, usually in units of
1576 * nominal nanoseconds.
1578 static enum ice_status
1579 ice_ptp_prep_phy_adj_target_e810(struct ice_hw *hw, u32 target_time)
1581 enum ice_status status;
1584 tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
1585 status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHTIME_0(tmr_idx), 0);
1587 ice_debug(hw, ICE_DBG_PTP, "Failed to write target time to SHTIME_0, status %d\n",
1592 status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHTIME_L(tmr_idx),
1595 ice_debug(hw, ICE_DBG_PTP, "Failed to write target time to SHTIME_L, status %d\n",
1604 * ice_ptp_port_cmd_e810 - Prepare all external PHYs for a timer command
1605 * @hw: pointer to HW struct
1606 * @cmd: Command to be sent to the port
1607 * @lock_sbq: true if the sideband queue lock must be acquired
1609 * Prepare the external PHYs connected to this device for a timer sync
1612 static enum ice_status
1613 ice_ptp_port_cmd_e810(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd,
1616 enum ice_status status;
1621 cmd_val = GLTSYN_CMD_INIT_TIME;
1624 cmd_val = GLTSYN_CMD_INIT_INCVAL;
1627 cmd_val = GLTSYN_CMD_ADJ_TIME;
1629 case ADJ_TIME_AT_TIME:
1630 cmd_val = GLTSYN_CMD_ADJ_INIT_TIME;
1633 cmd_val = GLTSYN_CMD_READ_TIME;
1636 ice_warn(hw, "Unknown timer command %u\n", cmd);
1637 return ICE_ERR_PARAM;
1640 /* Read, modify, write */
1641 status = ice_read_phy_reg_e810_lp(hw, ETH_GLTSYN_CMD, &val, lock_sbq);
1643 ice_debug(hw, ICE_DBG_PTP, "Failed to read GLTSYN_CMD, status %d\n",
1648 /* Modify necessary bits only and perform write */
1649 val &= ~TS_CMD_MASK_E810;
1652 status = ice_write_phy_reg_e810_lp(hw, ETH_GLTSYN_CMD, val, lock_sbq);
1654 ice_debug(hw, ICE_DBG_PTP, "Failed to write back GLTSYN_CMD, status %d\n",
1662 /* Device agnostic functions
1664 * The following functions implement shared behavior common to both E822 and
1665 * E810 devices, possibly calling a device specific implementation where
1670 * ice_ptp_lock - Acquire PTP global semaphore register lock
1671 * @hw: pointer to the HW struct
1673 * Acquire the global PTP hardware semaphore lock. Returns true if the lock
1674 * was acquired, false otherwise.
1676 * The PFTSYN_SEM register sets the busy bit on read, returning the previous
1677 * value. If software sees the busy bit cleared, this means that this function
1678 * acquired the lock (and the busy bit is now set). If software sees the busy
1679 * bit set, it means that another function acquired the lock.
1681 * Software must clear the busy bit with a write to release the lock for other
1682 * functions when done.
1684 bool ice_ptp_lock(struct ice_hw *hw)
1691 for (i = 0; i < MAX_TRIES; i++) {
1692 hw_lock = rd32(hw, PFTSYN_SEM + (PFTSYN_SEM_BYTES * hw->pf_id));
1693 hw_lock = hw_lock & PFTSYN_SEM_BUSY_M;
1695 /* Somebody is holding the lock */
1696 ice_msec_delay(10, true);
1707 * ice_ptp_unlock - Release PTP global semaphore register lock
1708 * @hw: pointer to the HW struct
1710 * Release the global PTP hardware semaphore lock. This is done by writing to
1711 * the PFTSYN_SEM register.
1713 void ice_ptp_unlock(struct ice_hw *hw)
1715 wr32(hw, PFTSYN_SEM + (PFTSYN_SEM_BYTES * hw->pf_id), 0);
1719 * ice_ptp_src_cmd - Prepare source timer for a timer command
1720 * @hw: pointer to HW structure
1721 * @cmd: Timer command
1723 * Prepare the source timer for an upcoming timer sync command.
1725 void ice_ptp_src_cmd(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd)
1730 tmr_idx = ice_get_ptp_src_clock_index(hw);
1731 cmd_val = tmr_idx << SEL_CPK_SRC;
1735 cmd_val |= GLTSYN_CMD_INIT_TIME;
1738 cmd_val |= GLTSYN_CMD_INIT_INCVAL;
1741 cmd_val |= GLTSYN_CMD_ADJ_TIME;
1743 case ADJ_TIME_AT_TIME:
1744 cmd_val |= GLTSYN_CMD_ADJ_INIT_TIME;
1747 cmd_val |= GLTSYN_CMD_READ_TIME;
1750 ice_warn(hw, "Unknown timer command %u\n", cmd);
1754 wr32(hw, GLTSYN_CMD, cmd_val);
1758 * ice_ptp_tmr_cmd - Prepare and trigger a timer sync command
1759 * @hw: pointer to HW struct
1760 * @cmd: the command to issue
1761 * @lock_sbq: true if the sideband queue lock must be acquired
1763 * Prepare the source timer and PHY timers and then trigger the requested
1764 * command. This causes the shadow registers previously written in preparation
1765 * for the command to be synchronously applied to both the source and PHY
1768 static enum ice_status
1769 ice_ptp_tmr_cmd(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd, bool lock_sbq)
1771 enum ice_status status;
1773 /* First, prepare the source timer */
1774 ice_ptp_src_cmd(hw, cmd);
1776 /* Next, prepare the ports */
1777 if (ice_is_e810(hw))
1778 status = ice_ptp_port_cmd_e810(hw, cmd, lock_sbq);
1780 status = ice_ptp_port_cmd_e822(hw, cmd, lock_sbq);
1782 ice_debug(hw, ICE_DBG_PTP, "Failed to prepare PHY ports for timer command %u, status %d\n",
1787 /* Write the sync command register to drive both source and PHY timer
1788 * commands synchronously
1790 ice_ptp_exec_tmr_cmd(hw);
1796 * ice_ptp_init_time - Initialize device time to provided value
1797 * @hw: pointer to HW struct
1798 * @time: 64bits of time (GLTSYN_TIME_L and GLTSYN_TIME_H)
1800 * Initialize the device to the specified time provided. This requires a three
1803 * 1) write the new init time to the source timer shadow registers
1804 * 2) write the new init time to the phy timer shadow registers
1805 * 3) issue an init_time timer command to synchronously switch both the source
1806 * and port timers to the new init time value at the next clock cycle.
1808 enum ice_status ice_ptp_init_time(struct ice_hw *hw, u64 time)
1810 enum ice_status status;
1813 tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
1816 wr32(hw, GLTSYN_SHTIME_L(tmr_idx), ICE_LO_DWORD(time));
1817 wr32(hw, GLTSYN_SHTIME_H(tmr_idx), ICE_HI_DWORD(time));
1818 wr32(hw, GLTSYN_SHTIME_0(tmr_idx), 0);
1821 /* Fill Rx and Tx ports and send msg to PHY */
1822 if (ice_is_e810(hw))
1823 status = ice_ptp_prep_phy_time_e810(hw, time & 0xFFFFFFFF);
1825 status = ice_ptp_prep_phy_time_e822(hw, time & 0xFFFFFFFF);
1829 return ice_ptp_tmr_cmd(hw, INIT_TIME, true);
1833 * ice_ptp_write_incval - Program PHC with new increment value
1834 * @hw: pointer to HW struct
1835 * @incval: Source timer increment value per clock cycle
1837 * Program the PHC with a new increment value. This requires a three-step
1840 * 1) Write the increment value to the source timer shadow registers
1841 * 2) Write the increment value to the PHY timer shadow registers
1842 * 3) Issue an INIT_INCVAL timer command to synchronously switch both the
1843 * source and port timers to the new increment value at the next clock
1846 enum ice_status ice_ptp_write_incval(struct ice_hw *hw, u64 incval)
1848 enum ice_status status;
1851 tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
1854 wr32(hw, GLTSYN_SHADJ_L(tmr_idx), ICE_LO_DWORD(incval));
1855 wr32(hw, GLTSYN_SHADJ_H(tmr_idx), ICE_HI_DWORD(incval));
1857 if (ice_is_e810(hw))
1858 status = ice_ptp_prep_phy_incval_e810(hw, incval);
1860 status = ice_ptp_prep_phy_incval_e822(hw, incval);
1864 return ice_ptp_tmr_cmd(hw, INIT_INCVAL, true);
1868 * ice_ptp_write_incval_locked - Program new incval while holding semaphore
1869 * @hw: pointer to HW struct
1870 * @incval: Source timer increment value per clock cycle
1872 * Program a new PHC incval while holding the PTP semaphore.
1874 enum ice_status ice_ptp_write_incval_locked(struct ice_hw *hw, u64 incval)
1876 enum ice_status status;
1878 if (!ice_ptp_lock(hw))
1879 return ICE_ERR_NOT_READY;
1881 status = ice_ptp_write_incval(hw, incval);
1889 * ice_ptp_adj_clock - Adjust PHC clock time atomically
1890 * @hw: pointer to HW struct
1891 * @adj: Adjustment in nanoseconds
1892 * @lock_sbq: true to lock the sbq sq_lock (the usual case); false if the
1893 * sq_lock has already been locked at a higher level
1895 * Perform an atomic adjustment of the PHC time by the specified number of
1896 * nanoseconds. This requires a three-step process:
1898 * 1) Write the adjustment to the source timer shadow registers
1899 * 2) Write the adjustment to the PHY timer shadow registers
1900 * 3) Issue an ADJ_TIME timer command to synchronously apply the adjustment to
1901 * both the source and port timers at the next clock cycle.
1903 enum ice_status ice_ptp_adj_clock(struct ice_hw *hw, s32 adj, bool lock_sbq)
1905 enum ice_status status;
1908 tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
1910 /* Write the desired clock adjustment into the GLTSYN_SHADJ register.
1911 * For an ADJ_TIME command, this set of registers represents the value
1912 * to add to the clock time. It supports subtraction by interpreting
1913 * the value as a 2's complement integer.
1915 wr32(hw, GLTSYN_SHADJ_L(tmr_idx), 0);
1916 wr32(hw, GLTSYN_SHADJ_H(tmr_idx), adj);
1918 if (ice_is_e810(hw))
1919 status = ice_ptp_prep_phy_adj_e810(hw, adj, lock_sbq);
1921 status = ice_ptp_prep_phy_adj_e822(hw, adj, lock_sbq);
1925 return ice_ptp_tmr_cmd(hw, ADJ_TIME, lock_sbq);
1929 * ice_ptp_adj_clock_at_time - Adjust PHC atomically at specified time
1930 * @hw: pointer to HW struct
1931 * @at_time: Time in nanoseconds at which to perform the adjustment
1932 * @adj: Adjustment in nanoseconds
1934 * Perform an atomic adjustment to the PHC clock at the specified time. This
1935 * requires a five-step process:
1937 * 1) Write the adjustment to the source timer shadow adjust registers
1938 * 2) Write the target time to the source timer shadow time registers
1939 * 3) Write the adjustment to the PHY timers shadow adjust registers
1940 * 4) Write the target time to the PHY timers shadow adjust registers
1941 * 5) Issue an ADJ_TIME_AT_TIME command to initiate the atomic adjustment.
1944 ice_ptp_adj_clock_at_time(struct ice_hw *hw, u64 at_time, s32 adj)
1946 enum ice_status status;
1947 u32 time_lo, time_hi;
1950 tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
1951 time_lo = ICE_LO_DWORD(at_time);
1952 time_hi = ICE_HI_DWORD(at_time);
1954 /* Write the desired clock adjustment into the GLTSYN_SHADJ register.
1955 * For an ADJ_TIME_AT_TIME command, this set of registers represents
1956 * the value to add to the clock time. It supports subtraction by
1957 * interpreting the value as a 2's complement integer.
1959 wr32(hw, GLTSYN_SHADJ_L(tmr_idx), 0);
1960 wr32(hw, GLTSYN_SHADJ_H(tmr_idx), adj);
1962 /* Write the target time to trigger the adjustment for source clock */
1963 wr32(hw, GLTSYN_SHTIME_0(tmr_idx), 0);
1964 wr32(hw, GLTSYN_SHTIME_L(tmr_idx), time_lo);
1965 wr32(hw, GLTSYN_SHTIME_H(tmr_idx), time_hi);
1967 /* Prepare PHY port adjustments */
1968 if (ice_is_e810(hw))
1969 status = ice_ptp_prep_phy_adj_e810(hw, adj, true);
1971 status = ice_ptp_prep_phy_adj_e822(hw, adj, true);
1975 /* Set target time for each PHY port */
1976 if (ice_is_e810(hw))
1977 status = ice_ptp_prep_phy_adj_target_e810(hw, time_lo);
1979 status = ice_ptp_prep_phy_adj_target_e822(hw, time_lo);
1983 return ice_ptp_tmr_cmd(hw, ADJ_TIME_AT_TIME, true);
1987 * ice_read_phy_tstamp - Read a PHY timestamp from the timestamo block
1988 * @hw: pointer to the HW struct
1989 * @block: the block to read from
1990 * @idx: the timestamp index to read
1991 * @tstamp: on return, the 40bit timestamp value
1993 * Read a 40bit timestamp value out of the timestamp block. For E822 devices,
1994 * the block is the quad to read from. For E810 devices, the block is the
1995 * logical port to read from.
1998 ice_read_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx, u64 *tstamp)
2000 if (ice_is_e810(hw))
2001 return ice_read_phy_tstamp_e810(hw, block, idx, tstamp);
2003 return ice_read_phy_tstamp_e822(hw, block, idx, tstamp);
2007 * ice_clear_phy_tstamp - Clear a timestamp from the timestamp block
2008 * @hw: pointer to the HW struct
2009 * @block: the block to read from
2010 * @idx: the timestamp index to reset
2012 * Clear a timestamp, resetting its valid bit, from the timestamp block. For
2013 * E822 devices, the block is the quad to clear from. For E810 devices, the
2014 * block is the logical port to clear from.
2017 ice_clear_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx)
2019 if (ice_is_e810(hw))
2020 return ice_clear_phy_tstamp_e810(hw, block, idx);
2022 return ice_clear_phy_tstamp_e822(hw, block, idx);