xref: /dpdk/drivers/net/ice/base/ice_ptp_hw.c (revision b3d1ca7d)
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  */
ice_get_ptp_src_clock_index(struct ice_hw * hw)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  */
ice_ptp_read_src_incval(struct ice_hw * hw)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  */
ice_ptp_exec_tmr_cmd(struct ice_hw * hw)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
ice_fill_phy_msg_e822(struct ice_sbq_msg_input * msg,u8 port,u16 offset)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  */
ice_is_64b_phy_reg_e822(u16 low_addr,u16 * high_addr)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  */
ice_is_40b_phy_reg_e822(u16 low_addr,u16 * high_addr)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
ice_read_phy_reg_e822_lp(struct ice_hw * hw,u8 port,u16 offset,u32 * val,bool lock_sbq)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
ice_read_phy_reg_e822(struct ice_hw * hw,u8 port,u16 offset,u32 * val)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
ice_read_40b_phy_reg_e822(struct ice_hw * hw,u8 port,u16 low_addr,u64 * val)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
ice_read_64b_phy_reg_e822(struct ice_hw * hw,u8 port,u16 low_addr,u64 * val)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
ice_write_phy_reg_e822_lp(struct ice_hw * hw,u8 port,u16 offset,u32 val,bool lock_sbq)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
ice_write_phy_reg_e822(struct ice_hw * hw,u8 port,u16 offset,u32 val)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
ice_write_40b_phy_reg_e822(struct ice_hw * hw,u8 port,u16 low_addr,u64 val)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
ice_write_64b_phy_reg_e822(struct ice_hw * hw,u8 port,u16 low_addr,u64 val)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
ice_fill_quad_msg_e822(struct ice_sbq_msg_input * msg,u8 quad,u16 offset)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
ice_read_quad_reg_e822_lp(struct ice_hw * hw,u8 quad,u16 offset,u32 * val,bool lock_sbq)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
ice_read_quad_reg_e822(struct ice_hw * hw,u8 quad,u16 offset,u32 * val)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
ice_write_quad_reg_e822_lp(struct ice_hw * hw,u8 quad,u16 offset,u32 val,bool lock_sbq)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
ice_write_quad_reg_e822(struct ice_hw * hw,u8 quad,u16 offset,u32 val)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
ice_read_phy_tstamp_e822(struct ice_hw * hw,u8 quad,u8 idx,u64 * tstamp)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
ice_clear_phy_tstamp_e822(struct ice_hw * hw,u8 quad,u8 idx)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
ice_read_cgu_reg_e822(struct ice_hw * hw,u16 addr,u32 * val)712 ice_read_cgu_reg_e822(struct ice_hw *hw, u16 addr, u32 *val)
713 {
714 	struct ice_sbq_msg_input cgu_msg;
715 	enum ice_status status;
716 
717 	cgu_msg.opcode = ice_sbq_msg_rd;
718 	cgu_msg.dest_dev = cgu;
719 	cgu_msg.msg_addr_low = addr;
720 	cgu_msg.msg_addr_high = 0x0;
721 
722 	status = ice_sbq_rw_reg_lp(hw, &cgu_msg, true);
723 	if (status) {
724 		ice_debug(hw, ICE_DBG_PTP, "Failed to read CGU register 0x%04x, status %d\n",
725 			  addr, status);
726 		return status;
727 	}
728 
729 	*val = cgu_msg.data;
730 
731 	return status;
732 }
733 
734 /**
735  * 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
ice_write_cgu_reg_e822(struct ice_hw * hw,u16 addr,u32 val)744 ice_write_cgu_reg_e822(struct ice_hw *hw, u16 addr, u32 val)
745 {
746 	struct ice_sbq_msg_input cgu_msg;
747 	enum ice_status status;
748 
749 	cgu_msg.opcode = ice_sbq_msg_wr;
750 	cgu_msg.dest_dev = cgu;
751 	cgu_msg.msg_addr_low = addr;
752 	cgu_msg.msg_addr_high = 0x0;
753 	cgu_msg.data = val;
754 
755 	status = ice_sbq_rw_reg_lp(hw, &cgu_msg, true);
756 	if (status) {
757 		ice_debug(hw, ICE_DBG_PTP, "Failed to write CGU register 0x%04x, status %d\n",
758 			  addr, status);
759 		return status;
760 	}
761 
762 	return status;
763 }
764 
765 /**
766  * 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  */
ice_clk_freq_str(u8 clk_freq)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  */
ice_clk_src_str(u8 clk_src)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
ice_cfg_cgu_pll_e822(struct ice_hw * hw,enum ice_time_ref_freq clk_freq,enum ice_clk_src clk_src)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  */
ice_init_cgu_e822(struct ice_hw * hw)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  */
ice_ptp_init_phc_e822(struct ice_hw * hw)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
ice_ptp_prep_phy_time_e822(struct ice_hw * hw,u32 time)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
ice_ptp_prep_port_adj_e822(struct ice_hw * hw,u8 port,s64 time,bool lock_sbq)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
ice_ptp_prep_phy_adj_e822(struct ice_hw * hw,s32 adj,bool lock_sbq)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
ice_ptp_prep_phy_incval_e822(struct ice_hw * hw,u64 incval)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
ice_ptp_read_phy_incval_e822(struct ice_hw * hw,u8 port,u64 * incval)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
ice_ptp_prep_phy_adj_target_e822(struct ice_hw * hw,u32 target_time)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
ice_ptp_read_port_capture(struct ice_hw * hw,u8 port,u64 * tx_ts,u64 * rx_ts)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
ice_ptp_one_port_cmd(struct ice_hw * hw,u8 port,enum ice_ptp_tmr_cmd cmd,bool lock_sbq)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
ice_ptp_port_cmd_e822(struct ice_hw * hw,enum ice_ptp_tmr_cmd cmd,bool lock_sbq)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  */
ice_ptp_set_vernier_wl(struct ice_hw * hw)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
ice_phy_get_speed_and_fec_e822(struct ice_hw * hw,u8 port,enum ice_ptp_link_spd * link_out,enum ice_ptp_fec_mode * fec_out)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  */
ice_phy_cfg_lane_e822(struct ice_hw * hw,u8 port)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  */
ice_phy_cfg_uix_e822(struct ice_hw * hw,u8 port)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 = DIV_64BIT(tu_per_sec * LINE_UI_10G_40G, 390625000);
1638 
1639 	status = ice_write_64b_phy_reg_e822(hw, port, P_REG_UIX66_10G_40G_L,
1640 					    uix);
1641 	if (status) {
1642 		ice_debug(hw, ICE_DBG_PTP, "Failed to write UIX66_10G_40G, status %d\n",
1643 			  status);
1644 		return status;
1645 	}
1646 
1647 	/* Program the 25Gb/100Gb conversion ratio */
1648 	uix = DIV_64BIT(tu_per_sec * LINE_UI_25G_100G, 390625000);
1649 
1650 	status = ice_write_64b_phy_reg_e822(hw, port, P_REG_UIX66_25G_100G_L,
1651 					    uix);
1652 	if (status) {
1653 		ice_debug(hw, ICE_DBG_PTP, "Failed to write UIX66_25G_100G, status %d\n",
1654 			  status);
1655 		return status;
1656 	}
1657 
1658 	return ICE_SUCCESS;
1659 }
1660 
1661 /**
1662  * 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  */
ice_phy_cfg_parpcs_e822(struct ice_hw * hw,u8 port)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 = DIV_64BIT(tu_per_sec,
1731 				    e822_vernier[link_spd].tx_par_clk);
1732 	else
1733 		phy_tus = 0;
1734 
1735 	status = ice_write_40b_phy_reg_e822(hw, port, P_REG_PAR_TX_TUS_L,
1736 					    phy_tus);
1737 	if (status)
1738 		return status;
1739 
1740 	/* P_REG_PAR_RX_TUS */
1741 	if (e822_vernier[link_spd].rx_par_clk)
1742 		phy_tus = DIV_64BIT(tu_per_sec,
1743 				    e822_vernier[link_spd].rx_par_clk);
1744 	else
1745 		phy_tus = 0;
1746 
1747 	status = ice_write_40b_phy_reg_e822(hw, port, P_REG_PAR_RX_TUS_L,
1748 					    phy_tus);
1749 	if (status)
1750 		return status;
1751 
1752 	/* P_REG_PCS_TX_TUS */
1753 	if (e822_vernier[link_spd].tx_pcs_clk)
1754 		phy_tus = DIV_64BIT(tu_per_sec,
1755 				    e822_vernier[link_spd].tx_pcs_clk);
1756 	else
1757 		phy_tus = 0;
1758 
1759 	status = ice_write_40b_phy_reg_e822(hw, port, P_REG_PCS_TX_TUS_L,
1760 					    phy_tus);
1761 	if (status)
1762 		return status;
1763 
1764 	/* P_REG_PCS_RX_TUS */
1765 	if (e822_vernier[link_spd].rx_pcs_clk)
1766 		phy_tus = DIV_64BIT(tu_per_sec,
1767 				    e822_vernier[link_spd].rx_pcs_clk);
1768 	else
1769 		phy_tus = 0;
1770 
1771 	status = ice_write_40b_phy_reg_e822(hw, port, P_REG_PCS_RX_TUS_L,
1772 					    phy_tus);
1773 	if (status)
1774 		return status;
1775 
1776 	/* P_REG_DESK_PAR_TX_TUS */
1777 	if (e822_vernier[link_spd].tx_desk_rsgb_par)
1778 		phy_tus = DIV_64BIT(tu_per_sec,
1779 				    e822_vernier[link_spd].tx_desk_rsgb_par);
1780 	else
1781 		phy_tus = 0;
1782 
1783 	status = ice_write_40b_phy_reg_e822(hw, port, P_REG_DESK_PAR_TX_TUS_L,
1784 					    phy_tus);
1785 	if (status)
1786 		return status;
1787 
1788 	/* P_REG_DESK_PAR_RX_TUS */
1789 	if (e822_vernier[link_spd].rx_desk_rsgb_par)
1790 		phy_tus = DIV_64BIT(tu_per_sec,
1791 				    e822_vernier[link_spd].rx_desk_rsgb_par);
1792 	else
1793 		phy_tus = 0;
1794 
1795 	status = ice_write_40b_phy_reg_e822(hw, port, P_REG_DESK_PAR_RX_TUS_L,
1796 					    phy_tus);
1797 	if (status)
1798 		return status;
1799 
1800 	/* P_REG_DESK_PCS_TX_TUS */
1801 	if (e822_vernier[link_spd].tx_desk_rsgb_pcs)
1802 		phy_tus = DIV_64BIT(tu_per_sec,
1803 				    e822_vernier[link_spd].tx_desk_rsgb_pcs);
1804 	else
1805 		phy_tus = 0;
1806 
1807 	status = ice_write_40b_phy_reg_e822(hw, port, P_REG_DESK_PCS_TX_TUS_L,
1808 					    phy_tus);
1809 	if (status)
1810 		return status;
1811 
1812 	/* P_REG_DESK_PCS_RX_TUS */
1813 	if (e822_vernier[link_spd].rx_desk_rsgb_pcs)
1814 		phy_tus = DIV_64BIT(tu_per_sec,
1815 				    e822_vernier[link_spd].rx_desk_rsgb_pcs);
1816 	else
1817 		phy_tus = 0;
1818 
1819 	return ice_write_40b_phy_reg_e822(hw, port, P_REG_DESK_PCS_RX_TUS_L,
1820 					  phy_tus);
1821 }
1822 
1823 /**
1824  * ice_calc_fixed_tx_offset_e822 - Calculated Fixed Tx offset for a port
1825  * @hw: pointer to the HW struct
1826  * @link_spd: the Link speed to calculate for
1827  *
1828  * Calculate the fixed offset due to known static latency data.
1829  */
1830 static u64
ice_calc_fixed_tx_offset_e822(struct ice_hw * hw,enum ice_ptp_link_spd link_spd)1831 ice_calc_fixed_tx_offset_e822(struct ice_hw *hw, enum ice_ptp_link_spd link_spd)
1832 {
1833 	u64 cur_freq, clk_incval, tu_per_sec, fixed_offset;
1834 
1835 	cur_freq = ice_e822_pll_freq(ice_e822_time_ref(hw));
1836 	clk_incval = ice_ptp_read_src_incval(hw);
1837 
1838 	/* Calculate TUs per second */
1839 	tu_per_sec = cur_freq * clk_incval;
1840 
1841 	/* Calculate number of TUs to add for the fixed Tx latency. Since the
1842 	 * latency measurement is in 1/100th of a nanosecond, we need to
1843 	 * multiply by tu_per_sec and then divide by 1e11. This calculation
1844 	 * overflows 64 bit integer arithmetic, so break it up into two
1845 	 * divisions by 1e4 first then by 1e7.
1846 	 */
1847 	fixed_offset = DIV_64BIT(tu_per_sec, 10000);
1848 	fixed_offset *= e822_vernier[link_spd].tx_fixed_delay;
1849 	fixed_offset = DIV_64BIT(fixed_offset, 10000000);
1850 
1851 	return fixed_offset;
1852 }
1853 
1854 /**
1855  * ice_phy_cfg_tx_offset_e822 - Configure total Tx timestamp offset
1856  * @hw: pointer to the HW struct
1857  * @port: the PHY port to configure
1858  *
1859  * Program the P_REG_TOTAL_TX_OFFSET register with the total number of TUs to
1860  * adjust Tx timestamps by. This is calculated by combining some known static
1861  * latency along with the Vernier offset computations done by hardware.
1862  *
1863  * This function must be called only after the offset registers are valid,
1864  * i.e. after the Vernier calibration wait has passed, to ensure that the PHY
1865  * has measured the offset.
1866  *
1867  * To avoid overflow, when calculating the offset based on the known static
1868  * latency values, we use measurements in 1/100th of a nanosecond, and divide
1869  * the TUs per second up front. This avoids overflow while allowing
1870  * calculation of the adjustment using integer arithmetic.
1871  */
ice_phy_cfg_tx_offset_e822(struct ice_hw * hw,u8 port)1872 enum ice_status ice_phy_cfg_tx_offset_e822(struct ice_hw *hw, u8 port)
1873 {
1874 	enum ice_ptp_link_spd link_spd;
1875 	enum ice_ptp_fec_mode fec_mode;
1876 	enum ice_status status;
1877 	u64 total_offset, val;
1878 
1879 	status = ice_phy_get_speed_and_fec_e822(hw, port, &link_spd, &fec_mode);
1880 	if (status)
1881 		return status;
1882 
1883 	total_offset = ice_calc_fixed_tx_offset_e822(hw, link_spd);
1884 
1885 	/* Read the first Vernier offset from the PHY register and add it to
1886 	 * the total offset.
1887 	 */
1888 	if (link_spd == ICE_PTP_LNK_SPD_1G ||
1889 	    link_spd == ICE_PTP_LNK_SPD_10G ||
1890 	    link_spd == ICE_PTP_LNK_SPD_25G ||
1891 	    link_spd == ICE_PTP_LNK_SPD_25G_RS ||
1892 	    link_spd == ICE_PTP_LNK_SPD_40G ||
1893 	    link_spd == ICE_PTP_LNK_SPD_50G) {
1894 		status = ice_read_64b_phy_reg_e822(hw, port,
1895 						   P_REG_PAR_PCS_TX_OFFSET_L,
1896 						   &val);
1897 		if (status)
1898 			return status;
1899 
1900 		total_offset += val;
1901 	}
1902 
1903 	/* For Tx, we only need to use the second Vernier offset for
1904 	 * multi-lane link speeds with RS-FEC. The lanes will always be
1905 	 * aligned.
1906 	 */
1907 	if (link_spd == ICE_PTP_LNK_SPD_50G_RS ||
1908 	    link_spd == ICE_PTP_LNK_SPD_100G_RS) {
1909 		status = ice_read_64b_phy_reg_e822(hw, port,
1910 						   P_REG_PAR_TX_TIME_L,
1911 						   &val);
1912 		if (status)
1913 			return status;
1914 
1915 		total_offset += val;
1916 	}
1917 
1918 	/* Now that the total offset has been calculated, program it to the
1919 	 * PHY and indicate that the Tx offset is ready. After this,
1920 	 * timestamps will be enabled.
1921 	 */
1922 	status = ice_write_64b_phy_reg_e822(hw, port, P_REG_TOTAL_TX_OFFSET_L,
1923 					    total_offset);
1924 	if (status)
1925 		return status;
1926 
1927 	status = ice_write_phy_reg_e822(hw, port, P_REG_TX_OR, 1);
1928 	if (status)
1929 		return status;
1930 
1931 	return ICE_SUCCESS;
1932 }
1933 
1934 /**
1935  * ice_phy_cfg_fixed_tx_offset_e822 - Configure Tx offset for bypass mode
1936  * @hw: pointer to the HW struct
1937  * @port: the PHY port to configure
1938  *
1939  * Calculate and program the fixed Tx offset, and indicate that the offset is
1940  * ready. This can be used when operating in bypass mode.
1941  */
1942 static enum ice_status
ice_phy_cfg_fixed_tx_offset_e822(struct ice_hw * hw,u8 port)1943 ice_phy_cfg_fixed_tx_offset_e822(struct ice_hw *hw, u8 port)
1944 {
1945 	enum ice_ptp_link_spd link_spd;
1946 	enum ice_ptp_fec_mode fec_mode;
1947 	enum ice_status status;
1948 	u64 total_offset;
1949 
1950 	status = ice_phy_get_speed_and_fec_e822(hw, port, &link_spd, &fec_mode);
1951 	if (status)
1952 		return status;
1953 
1954 	total_offset = ice_calc_fixed_tx_offset_e822(hw, link_spd);
1955 
1956 	/* Program the fixed Tx offset into the P_REG_TOTAL_TX_OFFSET_L
1957 	 * register, then indicate that the Tx offset is ready. After this,
1958 	 * timestamps will be enabled.
1959 	 *
1960 	 * Note that this skips including the more precise offsets generated
1961 	 * by the Vernier calibration.
1962 	 */
1963 	status = ice_write_64b_phy_reg_e822(hw, port, P_REG_TOTAL_TX_OFFSET_L,
1964 					    total_offset);
1965 	if (status)
1966 		return status;
1967 
1968 	status = ice_write_phy_reg_e822(hw, port, P_REG_TX_OR, 1);
1969 	if (status)
1970 		return status;
1971 
1972 	return ICE_SUCCESS;
1973 }
1974 
1975 /**
1976  * ice_phy_calc_pmd_adj_e822 - Calculate PMD adjustment for Rx
1977  * @hw: pointer to the HW struct
1978  * @port: the PHY port to adjust for
1979  * @link_spd: the current link speed of the PHY
1980  * @fec_mode: the current FEC mode of the PHY
1981  * @pmd_adj: on return, the amount to adjust the Rx total offset by
1982  *
1983  * Calculates the adjustment to Rx timestamps due to PMD alignment in the PHY.
1984  * This varies by link speed and FEC mode. The value calculated accounts for
1985  * various delays caused when receiving a packet.
1986  */
1987 static enum ice_status
ice_phy_calc_pmd_adj_e822(struct ice_hw * hw,u8 port,enum ice_ptp_link_spd link_spd,enum ice_ptp_fec_mode fec_mode,u64 * pmd_adj)1988 ice_phy_calc_pmd_adj_e822(struct ice_hw *hw, u8 port,
1989 			  enum ice_ptp_link_spd link_spd,
1990 			  enum ice_ptp_fec_mode fec_mode, u64 *pmd_adj)
1991 {
1992 	u64 cur_freq, clk_incval, tu_per_sec, mult, adj;
1993 	u32 pmd_adj_divisor, val;
1994 	enum ice_status status;
1995 	u8 pmd_align;
1996 
1997 	status = ice_read_phy_reg_e822(hw, port, P_REG_PMD_ALIGNMENT, &val);
1998 	if (status) {
1999 		ice_debug(hw, ICE_DBG_PTP, "Failed to read PMD alignment, status %d\n",
2000 			  status);
2001 		return status;
2002 	}
2003 
2004 	pmd_align = (u8)val;
2005 
2006 	cur_freq = ice_e822_pll_freq(ice_e822_time_ref(hw));
2007 	clk_incval = ice_ptp_read_src_incval(hw);
2008 
2009 	/* Calculate TUs per second */
2010 	tu_per_sec = cur_freq * clk_incval;
2011 
2012 	/* Get the link speed dependent PMD adjustment divisor */
2013 	pmd_adj_divisor = e822_vernier[link_spd].pmd_adj_divisor;
2014 
2015 	/* The PMD alignment adjustment measurement depends on the link speed,
2016 	 * and whether FEC is enabled. For each link speed, the alignment
2017 	 * adjustment is calculated by dividing a value by the length of
2018 	 * a Time Unit in nanoseconds.
2019 	 *
2020 	 * 1G: align == 4 ? 10 * 0.8 : (align + 6 % 10) * 0.8
2021 	 * 10G: align == 65 ? 0 : (align * 0.1 * 32/33)
2022 	 * 10G w/FEC: align * 0.1 * 32/33
2023 	 * 25G: align == 65 ? 0 : (align * 0.4 * 32/33)
2024 	 * 25G w/FEC: align * 0.4 * 32/33
2025 	 * 40G: align == 65 ? 0 : (align * 0.1 * 32/33)
2026 	 * 40G w/FEC: align * 0.1 * 32/33
2027 	 * 50G: align == 65 ? 0 : (align * 0.4 * 32/33)
2028 	 * 50G w/FEC: align * 0.8 * 32/33
2029 	 *
2030 	 * For RS-FEC, if align is < 17 then we must also add 1.6 * 32/33.
2031 	 *
2032 	 * To allow for calculating this value using integer arithmetic, we
2033 	 * instead start with the number of TUs per second, (inverse of the
2034 	 * length of a Time Unit in nanoseconds), multiply by a value based
2035 	 * on the PMD alignment register, and then divide by the right value
2036 	 * calculated based on the table above. To avoid integer overflow this
2037 	 * division is broken up into a step of dividing by 125 first.
2038 	 */
2039 	if (link_spd == ICE_PTP_LNK_SPD_1G) {
2040 		if (pmd_align == 4)
2041 			mult = 10;
2042 		else
2043 			mult = (pmd_align + 6) % 10;
2044 	} else if (link_spd == ICE_PTP_LNK_SPD_10G ||
2045 		   link_spd == ICE_PTP_LNK_SPD_25G ||
2046 		   link_spd == ICE_PTP_LNK_SPD_40G ||
2047 		   link_spd == ICE_PTP_LNK_SPD_50G) {
2048 		/* If Clause 74 FEC, always calculate PMD adjust */
2049 		if (pmd_align != 65 || fec_mode == ICE_PTP_FEC_MODE_CLAUSE74)
2050 			mult = pmd_align;
2051 		else
2052 			mult = 0;
2053 	} else if (link_spd == ICE_PTP_LNK_SPD_25G_RS ||
2054 		   link_spd == ICE_PTP_LNK_SPD_50G_RS ||
2055 		   link_spd == ICE_PTP_LNK_SPD_100G_RS) {
2056 		if (pmd_align < 17)
2057 			mult = pmd_align + 40;
2058 		else
2059 			mult = pmd_align;
2060 	} else {
2061 		ice_debug(hw, ICE_DBG_PTP, "Unknown link speed %d, skipping PMD adjustment\n",
2062 			  link_spd);
2063 		mult = 0;
2064 	}
2065 
2066 	/* In some cases, there's no need to adjust for the PMD alignment */
2067 	if (!mult) {
2068 		*pmd_adj = 0;
2069 		return ICE_SUCCESS;
2070 	}
2071 
2072 	/* Calculate the adjustment by multiplying TUs per second by the
2073 	 * appropriate multiplier and divisor. To avoid overflow, we first
2074 	 * divide by 125, and then handle remaining divisor based on the link
2075 	 * speed pmd_adj_divisor value.
2076 	 */
2077 	adj = DIV_64BIT(tu_per_sec, 125);
2078 	adj *= mult;
2079 	adj = DIV_64BIT(adj, pmd_adj_divisor);
2080 
2081 	/* Finally, for 25G-RS and 50G-RS, a further adjustment for the Rx
2082 	 * cycle count is necessary.
2083 	 */
2084 	if (link_spd == ICE_PTP_LNK_SPD_25G_RS) {
2085 		u64 cycle_adj;
2086 		u8 rx_cycle;
2087 
2088 		status = ice_read_phy_reg_e822(hw, port, P_REG_RX_40_TO_160_CNT,
2089 					       &val);
2090 		if (status) {
2091 			ice_debug(hw, ICE_DBG_PTP, "Failed to read 25G-RS Rx cycle count, status %d\n",
2092 				  status);
2093 			return status;
2094 		}
2095 
2096 		rx_cycle = val & P_REG_RX_40_TO_160_CNT_RXCYC_M;
2097 		if (rx_cycle) {
2098 			mult = (4 - rx_cycle) * 40;
2099 
2100 			cycle_adj = DIV_64BIT(tu_per_sec, 125);
2101 			cycle_adj *= mult;
2102 			cycle_adj = DIV_64BIT(cycle_adj, pmd_adj_divisor);
2103 
2104 			adj += cycle_adj;
2105 		}
2106 	} else if (link_spd == ICE_PTP_LNK_SPD_50G_RS) {
2107 		u64 cycle_adj;
2108 		u8 rx_cycle;
2109 
2110 		status = ice_read_phy_reg_e822(hw, port, P_REG_RX_80_TO_160_CNT,
2111 					       &val);
2112 		if (status) {
2113 			ice_debug(hw, ICE_DBG_PTP, "Failed to read 50G-RS Rx cycle count, status %d\n",
2114 				  status);
2115 			return status;
2116 		}
2117 
2118 		rx_cycle = val & P_REG_RX_80_TO_160_CNT_RXCYC_M;
2119 		if (rx_cycle) {
2120 			mult = rx_cycle * 40;
2121 
2122 			cycle_adj = DIV_64BIT(tu_per_sec, 125);
2123 			cycle_adj *= mult;
2124 			cycle_adj = DIV_64BIT(cycle_adj, pmd_adj_divisor);
2125 
2126 			adj += cycle_adj;
2127 		}
2128 	}
2129 
2130 	/* Return the calculated adjustment */
2131 	*pmd_adj = adj;
2132 
2133 	return ICE_SUCCESS;
2134 }
2135 
2136 /**
2137  * ice_calc_fixed_rx_offset_e822 - Calculated the fixed Rx offset for a port
2138  * @hw: pointer to HW struct
2139  * @link_spd: The Link speed to calculate for
2140  *
2141  * Determine the fixed Rx latency for a given link speed.
2142  */
2143 static u64
ice_calc_fixed_rx_offset_e822(struct ice_hw * hw,enum ice_ptp_link_spd link_spd)2144 ice_calc_fixed_rx_offset_e822(struct ice_hw *hw, enum ice_ptp_link_spd link_spd)
2145 {
2146 	u64 cur_freq, clk_incval, tu_per_sec, fixed_offset;
2147 
2148 	cur_freq = ice_e822_pll_freq(ice_e822_time_ref(hw));
2149 	clk_incval = ice_ptp_read_src_incval(hw);
2150 
2151 	/* Calculate TUs per second */
2152 	tu_per_sec = cur_freq * clk_incval;
2153 
2154 	/* Calculate number of TUs to add for the fixed Rx latency. Since the
2155 	 * latency measurement is in 1/100th of a nanosecond, we need to
2156 	 * multiply by tu_per_sec and then divide by 1e11. This calculation
2157 	 * overflows 64 bit integer arithmetic, so break it up into two
2158 	 * divisions by 1e4 first then by 1e7.
2159 	 */
2160 	fixed_offset = DIV_64BIT(tu_per_sec, 10000);
2161 	fixed_offset *= e822_vernier[link_spd].rx_fixed_delay;
2162 	fixed_offset = DIV_64BIT(fixed_offset, 10000000);
2163 
2164 	return fixed_offset;
2165 }
2166 
2167 /**
2168  * ice_phy_cfg_rx_offset_e822 - Configure total Rx timestamp offset
2169  * @hw: pointer to the HW struct
2170  * @port: the PHY port to configure
2171  *
2172  * Program the P_REG_TOTAL_RX_OFFSET register with the number of Time Units to
2173  * adjust Rx timestamps by. This combines calculations from the Vernier offset
2174  * measurements taken in hardware with some data about known fixed delay as
2175  * well as adjusting for multi-lane alignment delay.
2176  *
2177  * This function must be called only after the offset registers are valid,
2178  * i.e. after the Vernier calibration wait has passed, to ensure that the PHY
2179  * has measured the offset.
2180  *
2181  * To avoid overflow, when calculating the offset based on the known static
2182  * latency values, we use measurements in 1/100th of a nanosecond, and divide
2183  * the TUs per second up front. This avoids overflow while allowing
2184  * calculation of the adjustment using integer arithmetic.
2185  */
ice_phy_cfg_rx_offset_e822(struct ice_hw * hw,u8 port)2186 enum ice_status ice_phy_cfg_rx_offset_e822(struct ice_hw *hw, u8 port)
2187 {
2188 	enum ice_ptp_link_spd link_spd;
2189 	enum ice_ptp_fec_mode fec_mode;
2190 	u64 total_offset, pmd, val;
2191 	enum ice_status status;
2192 
2193 	status = ice_phy_get_speed_and_fec_e822(hw, port, &link_spd, &fec_mode);
2194 	if (status)
2195 		return status;
2196 
2197 	total_offset = ice_calc_fixed_rx_offset_e822(hw, link_spd);
2198 
2199 	/* Read the first Vernier offset from the PHY register and add it to
2200 	 * the total offset.
2201 	 */
2202 	status = ice_read_64b_phy_reg_e822(hw, port,
2203 					   P_REG_PAR_PCS_RX_OFFSET_L,
2204 					   &val);
2205 	if (status)
2206 		return status;
2207 
2208 	total_offset += val;
2209 
2210 	/* For Rx, all multi-lane link speeds include a second Vernier
2211 	 * calibration, because the lanes might not be aligned.
2212 	 */
2213 	if (link_spd == ICE_PTP_LNK_SPD_40G ||
2214 	    link_spd == ICE_PTP_LNK_SPD_50G ||
2215 	    link_spd == ICE_PTP_LNK_SPD_50G_RS ||
2216 	    link_spd == ICE_PTP_LNK_SPD_100G_RS) {
2217 		status = ice_read_64b_phy_reg_e822(hw, port,
2218 						   P_REG_PAR_RX_TIME_L,
2219 						   &val);
2220 		if (status)
2221 			return status;
2222 
2223 		total_offset += val;
2224 	}
2225 
2226 	/* In addition, Rx must account for the PMD alignment */
2227 	status = ice_phy_calc_pmd_adj_e822(hw, port, link_spd, fec_mode, &pmd);
2228 	if (status)
2229 		return status;
2230 
2231 	/* For RS-FEC, this adjustment adds delay, but for other modes, it
2232 	 * subtracts delay.
2233 	 */
2234 	if (fec_mode == ICE_PTP_FEC_MODE_RS_FEC)
2235 		total_offset += pmd;
2236 	else
2237 		total_offset -= pmd;
2238 
2239 	/* Now that the total offset has been calculated, program it to the
2240 	 * PHY and indicate that the Rx offset is ready. After this,
2241 	 * timestamps will be enabled.
2242 	 */
2243 	status = ice_write_64b_phy_reg_e822(hw, port, P_REG_TOTAL_RX_OFFSET_L,
2244 					    total_offset);
2245 	if (status)
2246 		return status;
2247 
2248 	status = ice_write_phy_reg_e822(hw, port, P_REG_RX_OR, 1);
2249 	if (status)
2250 		return status;
2251 
2252 	return ICE_SUCCESS;
2253 }
2254 
2255 /**
2256  * ice_phy_cfg_fixed_rx_offset_e822 - Configure fixed Rx offset for bypass mode
2257  * @hw: pointer to the HW struct
2258  * @port: the PHY port to configure
2259  *
2260  * Calculate and program the fixed Rx offset, and indicate that the offset is
2261  * ready. This can be used when operating in bypass mode.
2262  */
2263 static enum ice_status
ice_phy_cfg_fixed_rx_offset_e822(struct ice_hw * hw,u8 port)2264 ice_phy_cfg_fixed_rx_offset_e822(struct ice_hw *hw, u8 port)
2265 {
2266 	enum ice_ptp_link_spd link_spd;
2267 	enum ice_ptp_fec_mode fec_mode;
2268 	enum ice_status status;
2269 	u64 total_offset;
2270 
2271 	status = ice_phy_get_speed_and_fec_e822(hw, port, &link_spd, &fec_mode);
2272 	if (status)
2273 		return status;
2274 
2275 	total_offset = ice_calc_fixed_rx_offset_e822(hw, link_spd);
2276 
2277 	/* Program the fixed Rx offset into the P_REG_TOTAL_RX_OFFSET_L
2278 	 * register, then indicate that the Rx offset is ready. After this,
2279 	 * timestamps will be enabled.
2280 	 *
2281 	 * Note that this skips including the more precise offsets generated
2282 	 * by Vernier calibration.
2283 	 */
2284 	status = ice_write_64b_phy_reg_e822(hw, port, P_REG_TOTAL_RX_OFFSET_L,
2285 					    total_offset);
2286 	if (status)
2287 		return status;
2288 
2289 	status = ice_write_phy_reg_e822(hw, port, P_REG_RX_OR, 1);
2290 	if (status)
2291 		return status;
2292 
2293 	return ICE_SUCCESS;
2294 }
2295 
2296 /**
2297  * ice_read_phy_and_phc_time_e822 - Simultaneously capture PHC and PHY time
2298  * @hw: pointer to the HW struct
2299  * @port: the PHY port to read
2300  * @phy_time: on return, the 64bit PHY timer value
2301  * @phc_time: on return, the lower 64bits of PHC time
2302  *
2303  * Issue a READ_TIME timer command to simultaneously capture the PHY and PHC
2304  * timer values.
2305  */
2306 static enum ice_status
ice_read_phy_and_phc_time_e822(struct ice_hw * hw,u8 port,u64 * phy_time,u64 * phc_time)2307 ice_read_phy_and_phc_time_e822(struct ice_hw *hw, u8 port, u64 *phy_time,
2308 			       u64 *phc_time)
2309 {
2310 	enum ice_status status;
2311 	u64 tx_time, rx_time;
2312 	u32 zo, lo;
2313 	u8 tmr_idx;
2314 
2315 	tmr_idx = ice_get_ptp_src_clock_index(hw);
2316 
2317 	/* Prepare the PHC timer for a READ_TIME capture command */
2318 	ice_ptp_src_cmd(hw, READ_TIME);
2319 
2320 	/* Prepare the PHY timer for a READ_TIME capture command */
2321 	status = ice_ptp_one_port_cmd(hw, port, READ_TIME, true);
2322 	if (status)
2323 		return status;
2324 
2325 	/* Issue the sync to start the READ_TIME capture */
2326 	ice_ptp_exec_tmr_cmd(hw);
2327 
2328 	/* Read the captured PHC time from the shadow time registers */
2329 	zo = rd32(hw, GLTSYN_SHTIME_0(tmr_idx));
2330 	lo = rd32(hw, GLTSYN_SHTIME_L(tmr_idx));
2331 	*phc_time = (u64)lo << 32 | zo;
2332 
2333 	/* Read the captured PHY time from the PHY shadow registers */
2334 	status = ice_ptp_read_port_capture(hw, port, &tx_time, &rx_time);
2335 	if (status)
2336 		return status;
2337 
2338 	/* If the PHY Tx and Rx timers don't match, log a warning message.
2339 	 * Note that this should not happen in normal circumstances since the
2340 	 * driver always programs them together.
2341 	 */
2342 	if (tx_time != rx_time)
2343 		ice_warn(hw, "PHY port %u Tx and Rx timers do not match, tx_time 0x%016llX, rx_time 0x%016llX\n",
2344 			 port, (unsigned long long)tx_time,
2345 			 (unsigned long long)rx_time);
2346 
2347 	*phy_time = tx_time;
2348 
2349 	return ICE_SUCCESS;
2350 }
2351 
2352 /**
2353  * ice_sync_phy_timer_e822 - Synchronize the PHY timer with PHC timer
2354  * @hw: pointer to the HW struct
2355  * @port: the PHY port to synchronize
2356  *
2357  * Perform an adjustment to ensure that the PHY and PHC timers are in sync.
2358  * This is done by issuing a READ_TIME command which triggers a simultaneous
2359  * read of the PHY timer and PHC timer. Then we use the difference to
2360  * calculate an appropriate 2s complement addition to add to the PHY timer in
2361  * order to ensure it reads the same value as the primary PHC timer.
2362  */
ice_sync_phy_timer_e822(struct ice_hw * hw,u8 port)2363 static enum ice_status ice_sync_phy_timer_e822(struct ice_hw *hw, u8 port)
2364 {
2365 	u64 phc_time, phy_time, difference;
2366 	enum ice_status status;
2367 
2368 	if (!ice_ptp_lock(hw)) {
2369 		ice_debug(hw, ICE_DBG_PTP, "Failed to acquire PTP semaphore\n");
2370 		return ICE_ERR_NOT_READY;
2371 	}
2372 
2373 	status = ice_read_phy_and_phc_time_e822(hw, port, &phy_time, &phc_time);
2374 	if (status)
2375 		goto err_unlock;
2376 
2377 	/* Calculate the amount required to add to the port time in order for
2378 	 * it to match the PHC time.
2379 	 *
2380 	 * Note that the port adjustment is done using 2s complement
2381 	 * arithmetic. This is convenient since it means that we can simply
2382 	 * calculate the difference between the PHC time and the port time,
2383 	 * and it will be interpreted correctly.
2384 	 */
2385 	difference = phc_time - phy_time;
2386 
2387 	status = ice_ptp_prep_port_adj_e822(hw, port, (s64)difference, true);
2388 	if (status)
2389 		goto err_unlock;
2390 
2391 	status = ice_ptp_one_port_cmd(hw, port, ADJ_TIME, true);
2392 	if (status)
2393 		goto err_unlock;
2394 
2395 	/* Issue the sync to activate the time adjustment */
2396 	ice_ptp_exec_tmr_cmd(hw);
2397 
2398 	/* Re-capture the timer values to flush the command registers and
2399 	 * verify that the time was properly adjusted.
2400 	 */
2401 	status = ice_read_phy_and_phc_time_e822(hw, port, &phy_time, &phc_time);
2402 	if (status)
2403 		goto err_unlock;
2404 
2405 	ice_info(hw, "Port %u PHY time synced to PHC: 0x%016llX, 0x%016llX\n",
2406 		 port, (unsigned long long)phy_time,
2407 		 (unsigned long long)phc_time);
2408 
2409 	ice_ptp_unlock(hw);
2410 
2411 	return ICE_SUCCESS;
2412 
2413 err_unlock:
2414 	ice_ptp_unlock(hw);
2415 	return status;
2416 }
2417 
2418 /**
2419  * ice_stop_phy_timer_e822 - Stop the PHY clock timer
2420  * @hw: pointer to the HW struct
2421  * @port: the PHY port to stop
2422  * @soft_reset: if true, hold the SOFT_RESET bit of P_REG_PS
2423  *
2424  * Stop the clock of a PHY port. This must be done as part of the flow to
2425  * re-calibrate Tx and Rx timestamping offsets whenever the clock time is
2426  * initialized or when link speed changes.
2427  */
2428 enum ice_status
ice_stop_phy_timer_e822(struct ice_hw * hw,u8 port,bool soft_reset)2429 ice_stop_phy_timer_e822(struct ice_hw *hw, u8 port, bool soft_reset)
2430 {
2431 	enum ice_status status;
2432 	u32 val;
2433 
2434 	status = ice_write_phy_reg_e822(hw, port, P_REG_TX_OR, 0);
2435 	if (status)
2436 		return status;
2437 
2438 	status = ice_write_phy_reg_e822(hw, port, P_REG_RX_OR, 0);
2439 	if (status)
2440 		return status;
2441 
2442 	status = ice_read_phy_reg_e822(hw, port, P_REG_PS, &val);
2443 	if (status)
2444 		return status;
2445 
2446 	val &= ~P_REG_PS_START_M;
2447 	status = ice_write_phy_reg_e822(hw, port, P_REG_PS, val);
2448 	if (status)
2449 		return status;
2450 
2451 	val &= ~P_REG_PS_ENA_CLK_M;
2452 	status = ice_write_phy_reg_e822(hw, port, P_REG_PS, val);
2453 	if (status)
2454 		return status;
2455 
2456 	if (soft_reset) {
2457 		val |= P_REG_PS_SFT_RESET_M;
2458 		status = ice_write_phy_reg_e822(hw, port, P_REG_PS, val);
2459 		if (status)
2460 			return status;
2461 	}
2462 
2463 	ice_debug(hw, ICE_DBG_PTP, "Disabled clock on PHY port %u\n", port);
2464 
2465 	return ICE_SUCCESS;
2466 }
2467 
2468 /**
2469  * ice_start_phy_timer_e822 - Start the PHY clock timer
2470  * @hw: pointer to the HW struct
2471  * @port: the PHY port to start
2472  * @bypass: if true, start the PHY in bypass mode
2473  *
2474  * Start the clock of a PHY port. This must be done as part of the flow to
2475  * re-calibrate Tx and Rx timestamping offsets whenever the clock time is
2476  * initialized or when link speed changes.
2477  *
2478  * Bypass mode enables timestamps immediately without waiting for Vernier
2479  * calibration to complete. Hardware will still continue taking Vernier
2480  * measurements on Tx or Rx of packets, but they will not be applied to
2481  * timestamps. Use ice_phy_exit_bypass_e822 to exit bypass mode once hardware
2482  * has completed offset calculation.
2483  */
2484 enum ice_status
ice_start_phy_timer_e822(struct ice_hw * hw,u8 port,bool bypass)2485 ice_start_phy_timer_e822(struct ice_hw *hw, u8 port, bool bypass)
2486 {
2487 	enum ice_status status;
2488 	u32 lo, hi, val;
2489 	u64 incval;
2490 	u8 tmr_idx;
2491 
2492 	tmr_idx = ice_get_ptp_src_clock_index(hw);
2493 
2494 	status = ice_stop_phy_timer_e822(hw, port, false);
2495 	if (status)
2496 		return status;
2497 
2498 	ice_phy_cfg_lane_e822(hw, port);
2499 
2500 	status = ice_phy_cfg_uix_e822(hw, port);
2501 	if (status)
2502 		return status;
2503 
2504 	status = ice_phy_cfg_parpcs_e822(hw, port);
2505 	if (status)
2506 		return status;
2507 
2508 	lo = rd32(hw, GLTSYN_INCVAL_L(tmr_idx));
2509 	hi = rd32(hw, GLTSYN_INCVAL_H(tmr_idx));
2510 	incval = (u64)hi << 32 | lo;
2511 
2512 	status = ice_write_40b_phy_reg_e822(hw, port, P_REG_TIMETUS_L, incval);
2513 	if (status)
2514 		return status;
2515 
2516 	status = ice_ptp_one_port_cmd(hw, port, INIT_INCVAL, true);
2517 	if (status)
2518 		return status;
2519 
2520 	ice_ptp_exec_tmr_cmd(hw);
2521 
2522 	status = ice_read_phy_reg_e822(hw, port, P_REG_PS, &val);
2523 	if (status)
2524 		return status;
2525 
2526 	val |= P_REG_PS_SFT_RESET_M;
2527 	status = ice_write_phy_reg_e822(hw, port, P_REG_PS, val);
2528 	if (status)
2529 		return status;
2530 
2531 	val |= P_REG_PS_START_M;
2532 	status = ice_write_phy_reg_e822(hw, port, P_REG_PS, val);
2533 	if (status)
2534 		return status;
2535 
2536 	val &= ~P_REG_PS_SFT_RESET_M;
2537 	status = ice_write_phy_reg_e822(hw, port, P_REG_PS, val);
2538 	if (status)
2539 		return status;
2540 
2541 	status = ice_ptp_one_port_cmd(hw, port, INIT_INCVAL, true);
2542 	if (status)
2543 		return status;
2544 
2545 	ice_ptp_exec_tmr_cmd(hw);
2546 
2547 	val |= P_REG_PS_ENA_CLK_M;
2548 	status = ice_write_phy_reg_e822(hw, port, P_REG_PS, val);
2549 	if (status)
2550 		return status;
2551 
2552 	val |= P_REG_PS_LOAD_OFFSET_M;
2553 	status = ice_write_phy_reg_e822(hw, port, P_REG_PS, val);
2554 	if (status)
2555 		return status;
2556 
2557 	ice_ptp_exec_tmr_cmd(hw);
2558 
2559 	status = ice_sync_phy_timer_e822(hw, port);
2560 	if (status)
2561 		return status;
2562 
2563 	if (bypass) {
2564 		val |= P_REG_PS_BYPASS_MODE_M;
2565 		/* Enter BYPASS mode, enabling timestamps immediately. */
2566 		status = ice_write_phy_reg_e822(hw, port, P_REG_PS, val);
2567 		if (status)
2568 			return status;
2569 
2570 		/* Program the fixed Tx offset */
2571 		status = ice_phy_cfg_fixed_tx_offset_e822(hw, port);
2572 		if (status)
2573 			return status;
2574 
2575 		/* Program the fixed Rx offset */
2576 		status = ice_phy_cfg_fixed_rx_offset_e822(hw, port);
2577 		if (status)
2578 			return status;
2579 	}
2580 
2581 	ice_debug(hw, ICE_DBG_PTP, "Enabled clock on PHY port %u\n", port);
2582 
2583 	return ICE_SUCCESS;
2584 }
2585 
2586 /**
2587  * ice_phy_exit_bypass_e822 - Exit bypass mode, after vernier calculations
2588  * @hw: pointer to the HW struct
2589  * @port: the PHY port to configure
2590  *
2591  * After hardware finishes vernier calculations for the Tx and Rx offset, this
2592  * function can be used to exit bypass mode by updating the total Tx and Rx
2593  * offsets, and then disabling bypass. This will enable hardware to include
2594  * the more precise offset calibrations, increasing precision of the generated
2595  * timestamps.
2596  *
2597  * This cannot be done until hardware has measured the offsets, which requires
2598  * waiting until at least one packet has been sent and received by the device.
2599  */
ice_phy_exit_bypass_e822(struct ice_hw * hw,u8 port)2600 enum ice_status ice_phy_exit_bypass_e822(struct ice_hw *hw, u8 port)
2601 {
2602 	enum ice_status status;
2603 	u32 val;
2604 
2605 	status = ice_read_phy_reg_e822(hw, port, P_REG_TX_OV_STATUS, &val);
2606 	if (status) {
2607 		ice_debug(hw, ICE_DBG_PTP, "Failed to read TX_OV_STATUS for port %u, status %d\n",
2608 			  port, status);
2609 		return status;
2610 	}
2611 
2612 	if (!(val & P_REG_TX_OV_STATUS_OV_M)) {
2613 		ice_debug(hw, ICE_DBG_PTP, "Tx offset is not yet valid for port %u\n",
2614 			  port);
2615 		return ICE_ERR_NOT_READY;
2616 	}
2617 
2618 	status = ice_read_phy_reg_e822(hw, port, P_REG_RX_OV_STATUS, &val);
2619 	if (status) {
2620 		ice_debug(hw, ICE_DBG_PTP, "Failed to read RX_OV_STATUS for port %u, status %d\n",
2621 			  port, status);
2622 		return status;
2623 	}
2624 
2625 	if (!(val & P_REG_TX_OV_STATUS_OV_M)) {
2626 		ice_debug(hw, ICE_DBG_PTP, "Rx offset is not yet valid for port %u\n",
2627 			  port);
2628 		return ICE_ERR_NOT_READY;
2629 	}
2630 
2631 	status = ice_phy_cfg_tx_offset_e822(hw, port);
2632 	if (status) {
2633 		ice_debug(hw, ICE_DBG_PTP, "Failed to program total Tx offset for port %u, status %d\n",
2634 			  port, status);
2635 		return status;
2636 	}
2637 
2638 	status = ice_phy_cfg_rx_offset_e822(hw, port);
2639 	if (status) {
2640 		ice_debug(hw, ICE_DBG_PTP, "Failed to program total Rx offset for port %u, status %d\n",
2641 			  port, status);
2642 		return status;
2643 	}
2644 
2645 	/* Exit bypass mode now that the offset has been updated */
2646 	status = ice_read_phy_reg_e822(hw, port, P_REG_PS, &val);
2647 	if (status) {
2648 		ice_debug(hw, ICE_DBG_PTP, "Failed to read P_REG_PS for port %u, status %d\n",
2649 			  port, status);
2650 		return status;
2651 	}
2652 
2653 	if (!(val & P_REG_PS_BYPASS_MODE_M))
2654 		ice_debug(hw, ICE_DBG_PTP, "Port %u not in bypass mode\n",
2655 			  port);
2656 
2657 	val &= ~P_REG_PS_BYPASS_MODE_M;
2658 	status = ice_write_phy_reg_e822(hw, port, P_REG_PS, val);
2659 	if (status) {
2660 		ice_debug(hw, ICE_DBG_PTP, "Failed to disable bypass for port %u, status %d\n",
2661 			  port, status);
2662 		return status;
2663 	}
2664 
2665 	ice_info(hw, "Exiting bypass mode on PHY port %u\n", port);
2666 
2667 	return ICE_SUCCESS;
2668 }
2669 
2670 /* E810 functions
2671  *
2672  * The following functions operate on the E810 series devices which use
2673  * a separate external PHY.
2674  */
2675 
2676 /**
2677  * ice_read_phy_reg_e810_lp - Read register from external PHY on E810
2678  * @hw: pointer to the HW struct
2679  * @addr: the address to read from
2680  * @val: On return, the value read from the PHY
2681  * @lock_sbq: true if the sideband queue lock must be acquired
2682  *
2683  * Read a register from the external PHY on the E810 device.
2684  */
2685 static enum ice_status
ice_read_phy_reg_e810_lp(struct ice_hw * hw,u32 addr,u32 * val,bool lock_sbq)2686 ice_read_phy_reg_e810_lp(struct ice_hw *hw, u32 addr, u32 *val, bool lock_sbq)
2687 {
2688 	struct ice_sbq_msg_input msg = {0};
2689 	enum ice_status status;
2690 
2691 	msg.msg_addr_low = ICE_LO_WORD(addr);
2692 	msg.msg_addr_high = ICE_HI_WORD(addr);
2693 	msg.opcode = ice_sbq_msg_rd;
2694 	msg.dest_dev = rmn_0;
2695 
2696 	status = ice_sbq_rw_reg_lp(hw, &msg, lock_sbq);
2697 	if (status) {
2698 		ice_debug(hw, ICE_DBG_PTP, "Failed to send message to phy, status %d\n",
2699 			  status);
2700 		return status;
2701 	}
2702 
2703 	*val = msg.data;
2704 
2705 	return ICE_SUCCESS;
2706 }
2707 
2708 static enum ice_status
ice_read_phy_reg_e810(struct ice_hw * hw,u32 addr,u32 * val)2709 ice_read_phy_reg_e810(struct ice_hw *hw, u32 addr, u32 *val)
2710 {
2711 	return ice_read_phy_reg_e810_lp(hw, addr, val, true);
2712 }
2713 
2714 /**
2715  * ice_write_phy_reg_e810_lp - Write register on external PHY on E810
2716  * @hw: pointer to the HW struct
2717  * @addr: the address to writem to
2718  * @val: the value to write to the PHY
2719  * @lock_sbq: true if the sideband queue lock must be acquired
2720  *
2721  * Write a value to a register of the external PHY on the E810 device.
2722  */
2723 static enum ice_status
ice_write_phy_reg_e810_lp(struct ice_hw * hw,u32 addr,u32 val,bool lock_sbq)2724 ice_write_phy_reg_e810_lp(struct ice_hw *hw, u32 addr, u32 val, bool lock_sbq)
2725 {
2726 	struct ice_sbq_msg_input msg = {0};
2727 	enum ice_status status;
2728 
2729 	msg.msg_addr_low = ICE_LO_WORD(addr);
2730 	msg.msg_addr_high = ICE_HI_WORD(addr);
2731 	msg.opcode = ice_sbq_msg_wr;
2732 	msg.dest_dev = rmn_0;
2733 	msg.data = val;
2734 
2735 	status = ice_sbq_rw_reg_lp(hw, &msg, lock_sbq);
2736 	if (status) {
2737 		ice_debug(hw, ICE_DBG_PTP, "Failed to send message to phy, status %d\n",
2738 			  status);
2739 		return status;
2740 	}
2741 
2742 	return ICE_SUCCESS;
2743 }
2744 
2745 static enum ice_status
ice_write_phy_reg_e810(struct ice_hw * hw,u32 addr,u32 val)2746 ice_write_phy_reg_e810(struct ice_hw *hw, u32 addr, u32 val)
2747 {
2748 	return ice_write_phy_reg_e810_lp(hw, addr, val, true);
2749 }
2750 
2751 /**
2752  * ice_read_phy_tstamp_e810 - Read a PHY timestamp out of the external PHY
2753  * @hw: pointer to the HW struct
2754  * @lport: the lport to read from
2755  * @idx: the timestamp index to read
2756  * @tstamp: on return, the 40bit timestamp value
2757  *
2758  * Read a 40bit timestamp value out of the timestamp block of the external PHY
2759  * on the E810 device.
2760  */
2761 static enum ice_status
ice_read_phy_tstamp_e810(struct ice_hw * hw,u8 lport,u8 idx,u64 * tstamp)2762 ice_read_phy_tstamp_e810(struct ice_hw *hw, u8 lport, u8 idx, u64 *tstamp)
2763 {
2764 	enum ice_status status;
2765 	u32 lo_addr, hi_addr, lo, hi;
2766 
2767 	lo_addr = TS_EXT(LOW_TX_MEMORY_BANK_START, lport, idx);
2768 	hi_addr = TS_EXT(HIGH_TX_MEMORY_BANK_START, lport, idx);
2769 
2770 	status = ice_read_phy_reg_e810(hw, lo_addr, &lo);
2771 	if (status) {
2772 		ice_debug(hw, ICE_DBG_PTP, "Failed to read low PTP timestamp register, status %d\n",
2773 			  status);
2774 		return status;
2775 	}
2776 
2777 	status = ice_read_phy_reg_e810(hw, hi_addr, &hi);
2778 	if (status) {
2779 		ice_debug(hw, ICE_DBG_PTP, "Failed to read high PTP timestamp register, status %d\n",
2780 			  status);
2781 		return status;
2782 	}
2783 
2784 	/* For E810 devices, the timestamp is reported with the lower 32 bits
2785 	 * in the low register, and the upper 8 bits in the high register.
2786 	 */
2787 	*tstamp = ((u64)hi) << TS_HIGH_S | ((u64)lo & TS_LOW_M);
2788 
2789 	return ICE_SUCCESS;
2790 }
2791 
2792 /**
2793  * ice_clear_phy_tstamp_e810 - Clear a timestamp from the external PHY
2794  * @hw: pointer to the HW struct
2795  * @lport: the lport to read from
2796  * @idx: the timestamp index to reset
2797  *
2798  * Clear a timestamp, resetting its valid bit, from the timestamp block of the
2799  * external PHY on the E810 device.
2800  */
2801 static enum ice_status
ice_clear_phy_tstamp_e810(struct ice_hw * hw,u8 lport,u8 idx)2802 ice_clear_phy_tstamp_e810(struct ice_hw *hw, u8 lport, u8 idx)
2803 {
2804 	enum ice_status status;
2805 	u32 lo_addr, hi_addr;
2806 
2807 	lo_addr = TS_EXT(LOW_TX_MEMORY_BANK_START, lport, idx);
2808 	hi_addr = TS_EXT(HIGH_TX_MEMORY_BANK_START, lport, idx);
2809 
2810 	status = ice_write_phy_reg_e810(hw, lo_addr, 0);
2811 	if (status) {
2812 		ice_debug(hw, ICE_DBG_PTP, "Failed to clear low PTP timestamp register, status %d\n",
2813 			  status);
2814 		return status;
2815 	}
2816 
2817 	status = ice_write_phy_reg_e810(hw, hi_addr, 0);
2818 	if (status) {
2819 		ice_debug(hw, ICE_DBG_PTP, "Failed to clear high PTP timestamp register, status %d\n",
2820 			  status);
2821 		return status;
2822 	}
2823 
2824 	return ICE_SUCCESS;
2825 }
2826 
2827 /**
2828  * ice_ptp_init_phy_e810 - Enable PTP function on the external PHY
2829  * @hw: pointer to HW struct
2830  *
2831  * Enable the timesync PTP functionality for the external PHY connected to
2832  * this function.
2833  *
2834  * Note there is no equivalent function needed on E822 based devices.
2835  */
ice_ptp_init_phy_e810(struct ice_hw * hw)2836 enum ice_status ice_ptp_init_phy_e810(struct ice_hw *hw)
2837 {
2838 	enum ice_status status;
2839 	u8 tmr_idx;
2840 
2841 	tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
2842 	status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_ENA(tmr_idx),
2843 					GLTSYN_ENA_TSYN_ENA_M);
2844 	if (status)
2845 		ice_debug(hw, ICE_DBG_PTP, "PTP failed in ena_phy_time_syn %d\n",
2846 			  status);
2847 
2848 	return status;
2849 }
2850 
2851 /**
2852  * ice_ptp_init_phc_e810 - Perform E810 specific PHC initialization
2853  * @hw: pointer to HW struct
2854  *
2855  * Perform E810-specific PTP hardware clock initialization steps.
2856  */
ice_ptp_init_phc_e810(struct ice_hw * hw)2857 static enum ice_status ice_ptp_init_phc_e810(struct ice_hw *hw)
2858 {
2859 	/* Ensure synchronization delay is zero */
2860 	wr32(hw, GLTSYN_SYNC_DLAY, 0);
2861 
2862 	/* Initialize the PHY */
2863 	return ice_ptp_init_phy_e810(hw);
2864 }
2865 
2866 /**
2867  * ice_ptp_prep_phy_time_e810 - Prepare PHY port with initial time
2868  * @hw: Board private structure
2869  * @time: Time to initialize the PHY port clock to
2870  *
2871  * Program the PHY port ETH_GLTSYN_SHTIME registers in preparation setting the
2872  * initial clock time. The time will not actually be programmed until the
2873  * driver issues an INIT_TIME command.
2874  *
2875  * The time value is the upper 32 bits of the PHY timer, usually in units of
2876  * nominal nanoseconds.
2877  */
ice_ptp_prep_phy_time_e810(struct ice_hw * hw,u32 time)2878 static enum ice_status ice_ptp_prep_phy_time_e810(struct ice_hw *hw, u32 time)
2879 {
2880 	enum ice_status status;
2881 	u8 tmr_idx;
2882 
2883 	tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
2884 	status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHTIME_0(tmr_idx), 0);
2885 	if (status) {
2886 		ice_debug(hw, ICE_DBG_PTP, "Failed to write SHTIME_0, status %d\n",
2887 			  status);
2888 		return status;
2889 	}
2890 
2891 	status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHTIME_L(tmr_idx), time);
2892 	if (status) {
2893 		ice_debug(hw, ICE_DBG_PTP, "Failed to write SHTIME_L, status %d\n",
2894 			  status);
2895 		return status;
2896 	}
2897 
2898 	return ICE_SUCCESS;
2899 }
2900 
2901 /**
2902  * ice_ptp_prep_phy_adj_e810 - Prep PHY port for a time adjustment
2903  * @hw: pointer to HW struct
2904  * @adj: adjustment value to program
2905  * @lock_sbq: true if the sideband queue luck must be acquired
2906  *
2907  * Prepare the PHY port for an atomic adjustment by programming the PHY
2908  * ETH_GLTSYN_SHADJ_L and ETH_GLTSYN_SHADJ_H registers. The actual adjustment
2909  * is completed by issuing an ADJ_TIME sync command.
2910  *
2911  * The adjustment value only contains the portion used for the upper 32bits of
2912  * the PHY timer, usually in units of nominal nanoseconds. Negative
2913  * adjustments are supported using 2s complement arithmetic.
2914  */
2915 static enum ice_status
ice_ptp_prep_phy_adj_e810(struct ice_hw * hw,s32 adj,bool lock_sbq)2916 ice_ptp_prep_phy_adj_e810(struct ice_hw *hw, s32 adj, bool lock_sbq)
2917 {
2918 	enum ice_status status;
2919 	u8 tmr_idx;
2920 
2921 	tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
2922 
2923 	/* Adjustments are represented as signed 2's complement values in
2924 	 * nanoseconds. Sub-nanosecond adjustment is not supported.
2925 	 */
2926 	status = ice_write_phy_reg_e810_lp(hw, ETH_GLTSYN_SHADJ_L(tmr_idx),
2927 					   0, lock_sbq);
2928 	if (status) {
2929 		ice_debug(hw, ICE_DBG_PTP, "Failed to write adj to PHY SHADJ_L, status %d\n",
2930 			  status);
2931 		return status;
2932 	}
2933 
2934 	status = ice_write_phy_reg_e810_lp(hw, ETH_GLTSYN_SHADJ_H(tmr_idx),
2935 					   adj, lock_sbq);
2936 	if (status) {
2937 		ice_debug(hw, ICE_DBG_PTP, "Failed to write adj to PHY SHADJ_H, status %d\n",
2938 			  status);
2939 		return status;
2940 	}
2941 
2942 	return ICE_SUCCESS;
2943 }
2944 
2945 /**
2946  * ice_ptp_prep_phy_incval_e810 - Prep PHY port increment value change
2947  * @hw: pointer to HW struct
2948  * @incval: The new 40bit increment value to prepare
2949  *
2950  * Prepare the PHY port for a new increment value by programming the PHY
2951  * ETH_GLTSYN_SHADJ_L and ETH_GLTSYN_SHADJ_H registers. The actual change is
2952  * completed by issuing an INIT_INCVAL command.
2953  */
2954 static enum ice_status
ice_ptp_prep_phy_incval_e810(struct ice_hw * hw,u64 incval)2955 ice_ptp_prep_phy_incval_e810(struct ice_hw *hw, u64 incval)
2956 {
2957 	enum ice_status status;
2958 	u32 high, low;
2959 	u8 tmr_idx;
2960 
2961 	tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
2962 	low = ICE_LO_DWORD(incval);
2963 	high = ICE_HI_DWORD(incval);
2964 
2965 	status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHADJ_L(tmr_idx), low);
2966 	if (status) {
2967 		ice_debug(hw, ICE_DBG_PTP, "Failed to write incval to PHY SHADJ_L, status %d\n",
2968 			  status);
2969 		return status;
2970 	}
2971 
2972 	status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHADJ_H(tmr_idx), high);
2973 	if (status) {
2974 		ice_debug(hw, ICE_DBG_PTP, "Failed to write incval PHY SHADJ_H, status %d\n",
2975 			  status);
2976 		return status;
2977 	}
2978 
2979 	return ICE_SUCCESS;
2980 }
2981 
2982 /**
2983  * ice_ptp_prep_phy_adj_target_e810 - Prepare PHY port with adjust target
2984  * @hw: Board private structure
2985  * @target_time: Time to trigger the clock adjustment at
2986  *
2987  * Program the PHY port ETH_GLTSYN_SHTIME registers in preparation for
2988  * a target time adjust, which will trigger an adjustment of the clock in the
2989  * future. The actual adjustment will occur the next time the PHY port timer
2990  * crosses over the provided value after the driver issues an ADJ_TIME_AT_TIME
2991  * command.
2992  *
2993  * The time value is the upper 32 bits of the PHY timer, usually in units of
2994  * nominal nanoseconds.
2995  */
2996 static enum ice_status
ice_ptp_prep_phy_adj_target_e810(struct ice_hw * hw,u32 target_time)2997 ice_ptp_prep_phy_adj_target_e810(struct ice_hw *hw, u32 target_time)
2998 {
2999 	enum ice_status status;
3000 	u8 tmr_idx;
3001 
3002 	tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
3003 	status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHTIME_0(tmr_idx), 0);
3004 	if (status) {
3005 		ice_debug(hw, ICE_DBG_PTP, "Failed to write target time to SHTIME_0, status %d\n",
3006 			  status);
3007 		return status;
3008 	}
3009 
3010 	status = ice_write_phy_reg_e810(hw, ETH_GLTSYN_SHTIME_L(tmr_idx),
3011 					target_time);
3012 	if (status) {
3013 		ice_debug(hw, ICE_DBG_PTP, "Failed to write target time to SHTIME_L, status %d\n",
3014 			  status);
3015 		return status;
3016 	}
3017 
3018 	return ICE_SUCCESS;
3019 }
3020 
3021 /**
3022  * ice_ptp_port_cmd_e810 - Prepare all external PHYs for a timer command
3023  * @hw: pointer to HW struct
3024  * @cmd: Command to be sent to the port
3025  * @lock_sbq: true if the sideband queue lock must be acquired
3026  *
3027  * Prepare the external PHYs connected to this device for a timer sync
3028  * command.
3029  */
3030 static enum ice_status
ice_ptp_port_cmd_e810(struct ice_hw * hw,enum ice_ptp_tmr_cmd cmd,bool lock_sbq)3031 ice_ptp_port_cmd_e810(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd,
3032 		      bool lock_sbq)
3033 {
3034 	enum ice_status status;
3035 	u32 cmd_val, val;
3036 
3037 	switch (cmd) {
3038 	case INIT_TIME:
3039 		cmd_val = GLTSYN_CMD_INIT_TIME;
3040 		break;
3041 	case INIT_INCVAL:
3042 		cmd_val = GLTSYN_CMD_INIT_INCVAL;
3043 		break;
3044 	case ADJ_TIME:
3045 		cmd_val = GLTSYN_CMD_ADJ_TIME;
3046 		break;
3047 	case ADJ_TIME_AT_TIME:
3048 		cmd_val = GLTSYN_CMD_ADJ_INIT_TIME;
3049 		break;
3050 	case READ_TIME:
3051 		cmd_val = GLTSYN_CMD_READ_TIME;
3052 		break;
3053 	default:
3054 		ice_warn(hw, "Unknown timer command %u\n", cmd);
3055 		return ICE_ERR_PARAM;
3056 	}
3057 
3058 	/* Read, modify, write */
3059 	status = ice_read_phy_reg_e810_lp(hw, ETH_GLTSYN_CMD, &val, lock_sbq);
3060 	if (status) {
3061 		ice_debug(hw, ICE_DBG_PTP, "Failed to read GLTSYN_CMD, status %d\n",
3062 			  status);
3063 		return status;
3064 	}
3065 
3066 	/* Modify necessary bits only and perform write */
3067 	val &= ~TS_CMD_MASK_E810;
3068 	val |= cmd_val;
3069 
3070 	status = ice_write_phy_reg_e810_lp(hw, ETH_GLTSYN_CMD, val, lock_sbq);
3071 	if (status) {
3072 		ice_debug(hw, ICE_DBG_PTP, "Failed to write back GLTSYN_CMD, status %d\n",
3073 			  status);
3074 		return status;
3075 	}
3076 
3077 	return ICE_SUCCESS;
3078 }
3079 
3080 /* E810T SMA functions
3081  *
3082  * The following functions operate specifically on E810T hardware and are used
3083  * to access the extended GPIOs available.
3084  */
3085 
3086 /**
3087  * ice_get_pca9575_handle
3088  * @hw: pointer to the hw struct
3089  * @pca9575_handle: GPIO controller's handle
3090  *
3091  * Find and return the GPIO controller's handle in the netlist.
3092  * When found - the value will be cached in the hw structure and following calls
3093  * will return cached value
3094  */
3095 static enum ice_status
ice_get_pca9575_handle(struct ice_hw * hw,__le16 * pca9575_handle)3096 ice_get_pca9575_handle(struct ice_hw *hw, __le16 *pca9575_handle)
3097 {
3098 	struct ice_aqc_get_link_topo *cmd;
3099 	struct ice_aq_desc desc;
3100 	enum ice_status status;
3101 	u8 idx;
3102 
3103 	if (!hw || !pca9575_handle)
3104 		return ICE_ERR_PARAM;
3105 
3106 	/* If handle was read previously return cached value */
3107 	if (hw->io_expander_handle) {
3108 		*pca9575_handle = hw->io_expander_handle;
3109 		return ICE_SUCCESS;
3110 	}
3111 
3112 	/* If handle was not detected read it from the netlist */
3113 	cmd = &desc.params.get_link_topo;
3114 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_link_topo);
3115 
3116 	/* Set node type to GPIO controller */
3117 	cmd->addr.topo_params.node_type_ctx =
3118 		(ICE_AQC_LINK_TOPO_NODE_TYPE_M &
3119 		 ICE_AQC_LINK_TOPO_NODE_TYPE_GPIO_CTRL);
3120 
3121 #define SW_PCA9575_SFP_TOPO_IDX		2
3122 #define SW_PCA9575_QSFP_TOPO_IDX	1
3123 
3124 	/* Check if the SW IO expander controlling SMA exists in the netlist. */
3125 	if (hw->device_id == ICE_DEV_ID_E810C_SFP)
3126 		idx = SW_PCA9575_SFP_TOPO_IDX;
3127 	else if (hw->device_id == ICE_DEV_ID_E810C_QSFP)
3128 		idx = SW_PCA9575_QSFP_TOPO_IDX;
3129 	else
3130 		return ICE_ERR_NOT_SUPPORTED;
3131 
3132 	cmd->addr.topo_params.index = idx;
3133 
3134 	status = ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
3135 	if (status)
3136 		return ICE_ERR_NOT_SUPPORTED;
3137 
3138 	/* Verify if we found the right IO expander type */
3139 	if (desc.params.get_link_topo.node_part_num !=
3140 		ICE_ACQ_GET_LINK_TOPO_NODE_NR_PCA9575)
3141 		return ICE_ERR_NOT_SUPPORTED;
3142 
3143 	/* If present save the handle and return it */
3144 	hw->io_expander_handle = desc.params.get_link_topo.addr.handle;
3145 	*pca9575_handle = hw->io_expander_handle;
3146 
3147 	return ICE_SUCCESS;
3148 }
3149 
3150 /**
3151  * ice_read_e810t_pca9575_reg
3152  * @hw: pointer to the hw struct
3153  * @offset: GPIO controller register offset
3154  * @data: pointer to data to be read from the GPIO controller
3155  *
3156  * Read the register from the GPIO controller
3157  */
3158 enum ice_status
ice_read_e810t_pca9575_reg(struct ice_hw * hw,u8 offset,u8 * data)3159 ice_read_e810t_pca9575_reg(struct ice_hw *hw, u8 offset, u8 *data)
3160 {
3161 	struct ice_aqc_link_topo_addr link_topo;
3162 	enum ice_status status;
3163 	__le16 addr;
3164 
3165 	memset(&link_topo, 0, sizeof(link_topo));
3166 
3167 	status = ice_get_pca9575_handle(hw, &link_topo.handle);
3168 	if (status)
3169 		return status;
3170 
3171 	link_topo.topo_params.node_type_ctx =
3172 		(ICE_AQC_LINK_TOPO_NODE_CTX_PROVIDED <<
3173 		 ICE_AQC_LINK_TOPO_NODE_CTX_S);
3174 
3175 	addr = CPU_TO_LE16((u16)offset);
3176 
3177 	return ice_aq_read_i2c(hw, link_topo, 0, addr, 1, data, NULL);
3178 }
3179 
3180 /**
3181  * ice_write_e810t_pca9575_reg
3182  * @hw: pointer to the hw struct
3183  * @offset: GPIO controller register offset
3184  * @data: data to be written to the GPIO controller
3185  *
3186  * Write the data to the GPIO controller register
3187  */
3188 enum ice_status
ice_write_e810t_pca9575_reg(struct ice_hw * hw,u8 offset,u8 data)3189 ice_write_e810t_pca9575_reg(struct ice_hw *hw, u8 offset, u8 data)
3190 {
3191 	struct ice_aqc_link_topo_addr link_topo;
3192 	enum ice_status status;
3193 	__le16 addr;
3194 
3195 	memset(&link_topo, 0, sizeof(link_topo));
3196 
3197 	status = ice_get_pca9575_handle(hw, &link_topo.handle);
3198 	if (status)
3199 		return status;
3200 
3201 	link_topo.topo_params.node_type_ctx =
3202 		(ICE_AQC_LINK_TOPO_NODE_CTX_PROVIDED <<
3203 		 ICE_AQC_LINK_TOPO_NODE_CTX_S);
3204 
3205 	addr = CPU_TO_LE16((u16)offset);
3206 
3207 	return ice_aq_write_i2c(hw, link_topo, 0, addr, 1, &data, NULL);
3208 }
3209 
3210 /**
3211  * ice_read_sma_ctrl_e810t
3212  * @hw: pointer to the hw struct
3213  * @data: pointer to data to be read from the GPIO controller
3214  *
3215  * Read the SMA controller state. Only bits 3-7 in data are valid.
3216  */
ice_read_sma_ctrl_e810t(struct ice_hw * hw,u8 * data)3217 enum ice_status ice_read_sma_ctrl_e810t(struct ice_hw *hw, u8 *data)
3218 {
3219 	enum ice_status status;
3220 	u16 handle;
3221 	u8 i;
3222 
3223 	status = ice_get_pca9575_handle(hw, &handle);
3224 	if (status)
3225 		return status;
3226 
3227 	*data = 0;
3228 
3229 	for (i = ICE_E810T_SMA_MIN_BIT; i <= ICE_E810T_SMA_MAX_BIT; i++) {
3230 		bool pin;
3231 
3232 		status = ice_aq_get_gpio(hw, handle, i + ICE_E810T_P1_OFFSET,
3233 					 &pin, NULL);
3234 		if (status)
3235 			break;
3236 		*data |= (u8)(!pin) << i;
3237 	}
3238 
3239 	return status;
3240 }
3241 
3242 /**
3243  * ice_write_sma_ctrl_e810t
3244  * @hw: pointer to the hw struct
3245  * @data: data to be written to the GPIO controller
3246  *
3247  * Write the data to the SMA controller. Only bits 3-7 in data are valid.
3248  */
ice_write_sma_ctrl_e810t(struct ice_hw * hw,u8 data)3249 enum ice_status ice_write_sma_ctrl_e810t(struct ice_hw *hw, u8 data)
3250 {
3251 	enum ice_status status;
3252 	u16 handle;
3253 	u8 i;
3254 
3255 	status = ice_get_pca9575_handle(hw, &handle);
3256 	if (status)
3257 		return status;
3258 
3259 	for (i = ICE_E810T_SMA_MIN_BIT; i <= ICE_E810T_SMA_MAX_BIT; i++) {
3260 		bool pin;
3261 
3262 		pin = !(data & (1 << i));
3263 		status = ice_aq_set_gpio(hw, handle, i + ICE_E810T_P1_OFFSET,
3264 					 pin, NULL);
3265 		if (status)
3266 			break;
3267 	}
3268 
3269 	return status;
3270 }
3271 
3272 /**
3273  * ice_e810t_is_pca9575_present
3274  * @hw: pointer to the hw struct
3275  *
3276  * Check if the SW IO expander is present in the netlist
3277  */
ice_e810t_is_pca9575_present(struct ice_hw * hw)3278 bool ice_e810t_is_pca9575_present(struct ice_hw *hw)
3279 {
3280 	enum ice_status status;
3281 	__le16 handle = 0;
3282 
3283 	if (!ice_is_e810t(hw))
3284 		return false;
3285 
3286 	status = ice_get_pca9575_handle(hw, &handle);
3287 	if (!status && handle)
3288 		return true;
3289 
3290 	return false;
3291 }
3292 
3293 /* Device agnostic functions
3294  *
3295  * The following functions implement shared behavior common to both E822 and
3296  * E810 devices, possibly calling a device specific implementation where
3297  * necessary.
3298  */
3299 
3300 /**
3301  * ice_ptp_lock - Acquire PTP global semaphore register lock
3302  * @hw: pointer to the HW struct
3303  *
3304  * Acquire the global PTP hardware semaphore lock. Returns true if the lock
3305  * was acquired, false otherwise.
3306  *
3307  * The PFTSYN_SEM register sets the busy bit on read, returning the previous
3308  * value. If software sees the busy bit cleared, this means that this function
3309  * acquired the lock (and the busy bit is now set). If software sees the busy
3310  * bit set, it means that another function acquired the lock.
3311  *
3312  * Software must clear the busy bit with a write to release the lock for other
3313  * functions when done.
3314  */
ice_ptp_lock(struct ice_hw * hw)3315 bool ice_ptp_lock(struct ice_hw *hw)
3316 {
3317 	u32 hw_lock;
3318 	int i;
3319 
3320 #define MAX_TRIES 5
3321 
3322 	for (i = 0; i < MAX_TRIES; i++) {
3323 		hw_lock = rd32(hw, PFTSYN_SEM + (PFTSYN_SEM_BYTES * hw->pf_id));
3324 		hw_lock = hw_lock & PFTSYN_SEM_BUSY_M;
3325 		if (hw_lock) {
3326 			/* Somebody is holding the lock */
3327 			ice_msec_delay(10, true);
3328 			continue;
3329 		} else {
3330 			break;
3331 		}
3332 	}
3333 
3334 	return !hw_lock;
3335 }
3336 
3337 /**
3338  * ice_ptp_unlock - Release PTP global semaphore register lock
3339  * @hw: pointer to the HW struct
3340  *
3341  * Release the global PTP hardware semaphore lock. This is done by writing to
3342  * the PFTSYN_SEM register.
3343  */
ice_ptp_unlock(struct ice_hw * hw)3344 void ice_ptp_unlock(struct ice_hw *hw)
3345 {
3346 	wr32(hw, PFTSYN_SEM + (PFTSYN_SEM_BYTES * hw->pf_id), 0);
3347 }
3348 
3349 /**
3350  * ice_ptp_src_cmd - Prepare source timer for a timer command
3351  * @hw: pointer to HW structure
3352  * @cmd: Timer command
3353  *
3354  * Prepare the source timer for an upcoming timer sync command.
3355  */
ice_ptp_src_cmd(struct ice_hw * hw,enum ice_ptp_tmr_cmd cmd)3356 void ice_ptp_src_cmd(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd)
3357 {
3358 	u32 cmd_val;
3359 	u8 tmr_idx;
3360 
3361 	tmr_idx = ice_get_ptp_src_clock_index(hw);
3362 	cmd_val = tmr_idx << SEL_CPK_SRC;
3363 
3364 	switch (cmd) {
3365 	case INIT_TIME:
3366 		cmd_val |= GLTSYN_CMD_INIT_TIME;
3367 		break;
3368 	case INIT_INCVAL:
3369 		cmd_val |= GLTSYN_CMD_INIT_INCVAL;
3370 		break;
3371 	case ADJ_TIME:
3372 		cmd_val |= GLTSYN_CMD_ADJ_TIME;
3373 		break;
3374 	case ADJ_TIME_AT_TIME:
3375 		cmd_val |= GLTSYN_CMD_ADJ_INIT_TIME;
3376 		break;
3377 	case READ_TIME:
3378 		cmd_val |= GLTSYN_CMD_READ_TIME;
3379 		break;
3380 	default:
3381 		ice_warn(hw, "Unknown timer command %u\n", cmd);
3382 		return;
3383 	}
3384 
3385 	wr32(hw, GLTSYN_CMD, cmd_val);
3386 }
3387 
3388 /**
3389  * ice_ptp_tmr_cmd - Prepare and trigger a timer sync command
3390  * @hw: pointer to HW struct
3391  * @cmd: the command to issue
3392  * @lock_sbq: true if the sideband queue lock must be acquired
3393  *
3394  * Prepare the source timer and PHY timers and then trigger the requested
3395  * command. This causes the shadow registers previously written in preparation
3396  * for the command to be synchronously applied to both the source and PHY
3397  * timers.
3398  */
3399 static enum ice_status
ice_ptp_tmr_cmd(struct ice_hw * hw,enum ice_ptp_tmr_cmd cmd,bool lock_sbq)3400 ice_ptp_tmr_cmd(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd, bool lock_sbq)
3401 {
3402 	enum ice_status status;
3403 
3404 	/* First, prepare the source timer */
3405 	ice_ptp_src_cmd(hw, cmd);
3406 
3407 	/* Next, prepare the ports */
3408 	if (ice_is_e810(hw))
3409 		status = ice_ptp_port_cmd_e810(hw, cmd, lock_sbq);
3410 	else
3411 		status = ice_ptp_port_cmd_e822(hw, cmd, lock_sbq);
3412 	if (status) {
3413 		ice_debug(hw, ICE_DBG_PTP, "Failed to prepare PHY ports for timer command %u, status %d\n",
3414 			  cmd, status);
3415 		return status;
3416 	}
3417 
3418 	/* Write the sync command register to drive both source and PHY timer
3419 	 * commands synchronously
3420 	 */
3421 	ice_ptp_exec_tmr_cmd(hw);
3422 
3423 	return ICE_SUCCESS;
3424 }
3425 
3426 /**
3427  * ice_ptp_init_time - Initialize device time to provided value
3428  * @hw: pointer to HW struct
3429  * @time: 64bits of time (GLTSYN_TIME_L and GLTSYN_TIME_H)
3430  *
3431  * Initialize the device to the specified time provided. This requires a three
3432  * step process:
3433  *
3434  * 1) write the new init time to the source timer shadow registers
3435  * 2) write the new init time to the phy timer shadow registers
3436  * 3) issue an init_time timer command to synchronously switch both the source
3437  *    and port timers to the new init time value at the next clock cycle.
3438  */
ice_ptp_init_time(struct ice_hw * hw,u64 time)3439 enum ice_status ice_ptp_init_time(struct ice_hw *hw, u64 time)
3440 {
3441 	enum ice_status status;
3442 	u8 tmr_idx;
3443 
3444 	tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
3445 
3446 	/* Source timers */
3447 	wr32(hw, GLTSYN_SHTIME_L(tmr_idx), ICE_LO_DWORD(time));
3448 	wr32(hw, GLTSYN_SHTIME_H(tmr_idx), ICE_HI_DWORD(time));
3449 	wr32(hw, GLTSYN_SHTIME_0(tmr_idx), 0);
3450 
3451 	/* PHY Clks */
3452 	/* Fill Rx and Tx ports and send msg to PHY */
3453 	if (ice_is_e810(hw))
3454 		status = ice_ptp_prep_phy_time_e810(hw, time & 0xFFFFFFFF);
3455 	else
3456 		status = ice_ptp_prep_phy_time_e822(hw, time & 0xFFFFFFFF);
3457 	if (status)
3458 		return status;
3459 
3460 	return ice_ptp_tmr_cmd(hw, INIT_TIME, true);
3461 }
3462 
3463 /**
3464  * ice_ptp_write_incval - Program PHC with new increment value
3465  * @hw: pointer to HW struct
3466  * @incval: Source timer increment value per clock cycle
3467  *
3468  * Program the PHC with a new increment value. This requires a three-step
3469  * process:
3470  *
3471  * 1) Write the increment value to the source timer shadow registers
3472  * 2) Write the increment value to the PHY timer shadow registers
3473  * 3) Issue an INIT_INCVAL timer command to synchronously switch both the
3474  *    source and port timers to the new increment value at the next clock
3475  *    cycle.
3476  */
ice_ptp_write_incval(struct ice_hw * hw,u64 incval)3477 enum ice_status ice_ptp_write_incval(struct ice_hw *hw, u64 incval)
3478 {
3479 	enum ice_status status;
3480 	u8 tmr_idx;
3481 
3482 	tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
3483 
3484 	/* Shadow Adjust */
3485 	wr32(hw, GLTSYN_SHADJ_L(tmr_idx), ICE_LO_DWORD(incval));
3486 	wr32(hw, GLTSYN_SHADJ_H(tmr_idx), ICE_HI_DWORD(incval));
3487 
3488 	if (ice_is_e810(hw))
3489 		status = ice_ptp_prep_phy_incval_e810(hw, incval);
3490 	else
3491 		status = ice_ptp_prep_phy_incval_e822(hw, incval);
3492 	if (status)
3493 		return status;
3494 
3495 	return ice_ptp_tmr_cmd(hw, INIT_INCVAL, true);
3496 }
3497 
3498 /**
3499  * ice_ptp_write_incval_locked - Program new incval while holding semaphore
3500  * @hw: pointer to HW struct
3501  * @incval: Source timer increment value per clock cycle
3502  *
3503  * Program a new PHC incval while holding the PTP semaphore.
3504  */
ice_ptp_write_incval_locked(struct ice_hw * hw,u64 incval)3505 enum ice_status ice_ptp_write_incval_locked(struct ice_hw *hw, u64 incval)
3506 {
3507 	enum ice_status status;
3508 
3509 	if (!ice_ptp_lock(hw))
3510 		return ICE_ERR_NOT_READY;
3511 
3512 	status = ice_ptp_write_incval(hw, incval);
3513 
3514 	ice_ptp_unlock(hw);
3515 
3516 	return status;
3517 }
3518 
3519 /**
3520  * ice_ptp_adj_clock - Adjust PHC clock time atomically
3521  * @hw: pointer to HW struct
3522  * @adj: Adjustment in nanoseconds
3523  * @lock_sbq: true to lock the sbq sq_lock (the usual case); false if the
3524  *            sq_lock has already been locked at a higher level
3525  *
3526  * Perform an atomic adjustment of the PHC time by the specified number of
3527  * nanoseconds. This requires a three-step process:
3528  *
3529  * 1) Write the adjustment to the source timer shadow registers
3530  * 2) Write the adjustment to the PHY timer shadow registers
3531  * 3) Issue an ADJ_TIME timer command to synchronously apply the adjustment to
3532  *    both the source and port timers at the next clock cycle.
3533  */
ice_ptp_adj_clock(struct ice_hw * hw,s32 adj,bool lock_sbq)3534 enum ice_status ice_ptp_adj_clock(struct ice_hw *hw, s32 adj, bool lock_sbq)
3535 {
3536 	enum ice_status status;
3537 	u8 tmr_idx;
3538 
3539 	tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
3540 
3541 	/* Write the desired clock adjustment into the GLTSYN_SHADJ register.
3542 	 * For an ADJ_TIME command, this set of registers represents the value
3543 	 * to add to the clock time. It supports subtraction by interpreting
3544 	 * the value as a 2's complement integer.
3545 	 */
3546 	wr32(hw, GLTSYN_SHADJ_L(tmr_idx), 0);
3547 	wr32(hw, GLTSYN_SHADJ_H(tmr_idx), adj);
3548 
3549 	if (ice_is_e810(hw))
3550 		status = ice_ptp_prep_phy_adj_e810(hw, adj, lock_sbq);
3551 	else
3552 		status = ice_ptp_prep_phy_adj_e822(hw, adj, lock_sbq);
3553 	if (status)
3554 		return status;
3555 
3556 	return ice_ptp_tmr_cmd(hw, ADJ_TIME, lock_sbq);
3557 }
3558 
3559 /**
3560  * ice_ptp_adj_clock_at_time - Adjust PHC atomically at specified time
3561  * @hw: pointer to HW struct
3562  * @at_time: Time in nanoseconds at which to perform the adjustment
3563  * @adj: Adjustment in nanoseconds
3564  *
3565  * Perform an atomic adjustment to the PHC clock at the specified time. This
3566  * requires a five-step process:
3567  *
3568  * 1) Write the adjustment to the source timer shadow adjust registers
3569  * 2) Write the target time to the source timer shadow time registers
3570  * 3) Write the adjustment to the PHY timers shadow adjust registers
3571  * 4) Write the target time to the PHY timers shadow adjust registers
3572  * 5) Issue an ADJ_TIME_AT_TIME command to initiate the atomic adjustment.
3573  */
3574 enum ice_status
ice_ptp_adj_clock_at_time(struct ice_hw * hw,u64 at_time,s32 adj)3575 ice_ptp_adj_clock_at_time(struct ice_hw *hw, u64 at_time, s32 adj)
3576 {
3577 	enum ice_status status;
3578 	u32 time_lo, time_hi;
3579 	u8 tmr_idx;
3580 
3581 	tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
3582 	time_lo = ICE_LO_DWORD(at_time);
3583 	time_hi = ICE_HI_DWORD(at_time);
3584 
3585 	/* Write the desired clock adjustment into the GLTSYN_SHADJ register.
3586 	 * For an ADJ_TIME_AT_TIME command, this set of registers represents
3587 	 * the value to add to the clock time. It supports subtraction by
3588 	 * interpreting the value as a 2's complement integer.
3589 	 */
3590 	wr32(hw, GLTSYN_SHADJ_L(tmr_idx), 0);
3591 	wr32(hw, GLTSYN_SHADJ_H(tmr_idx), adj);
3592 
3593 	/* Write the target time to trigger the adjustment for source clock */
3594 	wr32(hw, GLTSYN_SHTIME_0(tmr_idx), 0);
3595 	wr32(hw, GLTSYN_SHTIME_L(tmr_idx), time_lo);
3596 	wr32(hw, GLTSYN_SHTIME_H(tmr_idx), time_hi);
3597 
3598 	/* Prepare PHY port adjustments */
3599 	if (ice_is_e810(hw))
3600 		status = ice_ptp_prep_phy_adj_e810(hw, adj, true);
3601 	else
3602 		status = ice_ptp_prep_phy_adj_e822(hw, adj, true);
3603 	if (status)
3604 		return status;
3605 
3606 	/* Set target time for each PHY port */
3607 	if (ice_is_e810(hw))
3608 		status = ice_ptp_prep_phy_adj_target_e810(hw, time_lo);
3609 	else
3610 		status = ice_ptp_prep_phy_adj_target_e822(hw, time_lo);
3611 	if (status)
3612 		return status;
3613 
3614 	return ice_ptp_tmr_cmd(hw, ADJ_TIME_AT_TIME, true);
3615 }
3616 
3617 /**
3618  * ice_read_phy_tstamp - Read a PHY timestamp from the timestamo block
3619  * @hw: pointer to the HW struct
3620  * @block: the block to read from
3621  * @idx: the timestamp index to read
3622  * @tstamp: on return, the 40bit timestamp value
3623  *
3624  * Read a 40bit timestamp value out of the timestamp block. For E822 devices,
3625  * the block is the quad to read from. For E810 devices, the block is the
3626  * logical port to read from.
3627  */
3628 enum ice_status
ice_read_phy_tstamp(struct ice_hw * hw,u8 block,u8 idx,u64 * tstamp)3629 ice_read_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx, u64 *tstamp)
3630 {
3631 	if (ice_is_e810(hw))
3632 		return ice_read_phy_tstamp_e810(hw, block, idx, tstamp);
3633 	else
3634 		return ice_read_phy_tstamp_e822(hw, block, idx, tstamp);
3635 }
3636 
3637 /**
3638  * ice_clear_phy_tstamp - Clear a timestamp from the timestamp block
3639  * @hw: pointer to the HW struct
3640  * @block: the block to read from
3641  * @idx: the timestamp index to reset
3642  *
3643  * Clear a timestamp, resetting its valid bit, from the timestamp block. For
3644  * E822 devices, the block is the quad to clear from. For E810 devices, the
3645  * block is the logical port to clear from.
3646  */
3647 enum ice_status
ice_clear_phy_tstamp(struct ice_hw * hw,u8 block,u8 idx)3648 ice_clear_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx)
3649 {
3650 	if (ice_is_e810(hw))
3651 		return ice_clear_phy_tstamp_e810(hw, block, idx);
3652 	else
3653 		return ice_clear_phy_tstamp_e822(hw, block, idx);
3654 }
3655 
3656 /**
3657  * ice_ptp_init_phc - Initialize PTP hardware clock
3658  * @hw: pointer to the HW struct
3659  *
3660  * Perform the steps required to initialize the PTP hardware clock.
3661  */
ice_ptp_init_phc(struct ice_hw * hw)3662 enum ice_status ice_ptp_init_phc(struct ice_hw *hw)
3663 {
3664 	u8 src_idx = hw->func_caps.ts_func_info.tmr_index_owned;
3665 
3666 	/* Enable source clocks */
3667 	wr32(hw, GLTSYN_ENA(src_idx), GLTSYN_ENA_TSYN_ENA_M);
3668 
3669 	/* Clear event status indications for auxiliary pins */
3670 	(void)rd32(hw, GLTSYN_STAT(src_idx));
3671 
3672 	if (ice_is_e810(hw))
3673 		return ice_ptp_init_phc_e810(hw);
3674 	else
3675 		return ice_ptp_init_phc_e822(hw);
3676 }
3677