xref: /freebsd/sys/contrib/alpine-hal/al_hal_serdes.h (revision 49b49cda41feabe3439f7318e8bf40e3896c7bf4)
1 /*-
2 *******************************************************************************
3 Copyright (C) 2015 Annapurna Labs Ltd.
4 
5 This file may be licensed under the terms of the Annapurna Labs Commercial
6 License Agreement.
7 
8 Alternatively, this file can be distributed under the terms of the GNU General
9 Public License V2 as published by the Free Software Foundation and can be
10 found at http://www.gnu.org/licenses/gpl-2.0.html
11 
12 Alternatively, redistribution and use in source and binary forms, with or
13 without modification, are permitted provided that the following conditions are
14 met:
15 
16     *     Redistributions of source code must retain the above copyright notice,
17 this list of conditions and the following disclaimer.
18 
19     *     Redistributions in binary form must reproduce the above copyright
20 notice, this list of conditions and the following disclaimer in
21 the documentation and/or other materials provided with the
22 distribution.
23 
24 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
25 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
28 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
31 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 
35 *******************************************************************************/
36 
37 /**
38  * @defgroup group_serdes_api API
39  * SerDes HAL driver API
40  * @ingroup group_serdes SerDes
41  * @{
42  *
43  * @file   al_hal_serdes.h
44  *
45  * @brief Header file for the SerDes HAL driver
46  *
47  */
48 
49 #ifndef __AL_HAL_SERDES_H__
50 #define __AL_HAL_SERDES_H__
51 
52 #include "al_hal_common.h"
53 
54 /* *INDENT-OFF* */
55 #ifdef __cplusplus
56 extern "C" {
57 #endif
58 /* *INDENT-ON* */
59 
60 struct al_serdes_obj;
61 
62 enum al_serdes_group {
63 	AL_SRDS_GRP_A = 0,
64 	AL_SRDS_GRP_B,
65 	AL_SRDS_GRP_C,
66 	AL_SRDS_GRP_D,
67 
68 	AL_SRDS_NUM_GROUPS,
69 };
70 
71 struct al_serdes_group_info {
72 	/*
73 	 * Group parent object - filled automatically by al_serdes_handle_init
74 	 */
75 	struct al_serdes_obj		*pobj;
76 
77 	/*
78 	 * Group specific register base - filled automatically by
79 	 * al_sedres_handle_init
80 	 */
81 	struct al_serdes_regs __iomem	*regs_base;
82 };
83 
84 struct al_serdes_obj {
85 	struct al_serdes_group_info	grp_info[AL_SRDS_NUM_GROUPS];
86 };
87 
88 enum al_serdes_reg_page {
89 	AL_SRDS_REG_PAGE_0_LANE_0 = 0,
90 	AL_SRDS_REG_PAGE_1_LANE_1,
91 	AL_SRDS_REG_PAGE_2_LANE_2,
92 	AL_SRDS_REG_PAGE_3_LANE_3,
93 	AL_SRDS_REG_PAGE_4_COMMON,
94 	AL_SRDS_REG_PAGE_0123_LANES_0123 = 7,
95 };
96 
97 enum al_serdes_reg_type {
98 	AL_SRDS_REG_TYPE_PMA = 0,
99 	AL_SRDS_REG_TYPE_PCS,
100 };
101 
102 enum al_serdes_lane {
103 	AL_SRDS_LANE_0 = AL_SRDS_REG_PAGE_0_LANE_0,
104 	AL_SRDS_LANE_1 = AL_SRDS_REG_PAGE_1_LANE_1,
105 	AL_SRDS_LANE_2 = AL_SRDS_REG_PAGE_2_LANE_2,
106 	AL_SRDS_LANE_3 = AL_SRDS_REG_PAGE_3_LANE_3,
107 
108 	AL_SRDS_NUM_LANES,
109 	AL_SRDS_LANES_0123 = AL_SRDS_REG_PAGE_0123_LANES_0123,
110 };
111 
112 /** Serdes loopback mode */
113 enum al_serdes_lb_mode {
114 	/** No loopback */
115 	AL_SRDS_LB_MODE_OFF,
116 
117 	/**
118 	 * Transmits the untimed, partial equalized RX signal out the transmit
119 	 * IO pins.
120 	 * No clock used (untimed)
121 	 */
122 	AL_SRDS_LB_MODE_PMA_IO_UN_TIMED_RX_TO_TX,
123 
124 	/**
125 	 * Loops back the TX serializer output into the CDR.
126 	 * CDR recovered bit clock used (without attenuation)
127 	 */
128 	AL_SRDS_LB_MODE_PMA_INTERNALLY_BUFFERED_SERIAL_TX_TO_RX,
129 
130 	/**
131 	 * Loops back the TX driver IO signal to the RX IO pins
132 	 * CDR recovered bit clock used (only through IO)
133 	 */
134 	AL_SRDS_LB_MODE_PMA_SERIAL_TX_IO_TO_RX_IO,
135 
136 	/**
137 	 * Parallel loopback from the PMA receive lane data ports, to the
138 	 * transmit lane data ports
139 	 * CDR recovered bit clock used
140 	 */
141 	AL_SRDS_LB_MODE_PMA_PARALLEL_RX_TO_TX,
142 
143 	/** Loops received data after elastic buffer to transmit path */
144 	AL_SRDS_LB_MODE_PCS_PIPE,
145 
146 	/** Loops TX data (to PMA) to RX path (instead of PMA data) */
147 	AL_SRDS_LB_MODE_PCS_NEAR_END,
148 
149 	/** Loops receive data prior to interface block to transmit path */
150 	AL_SRDS_LB_MODE_PCS_FAR_END,
151 };
152 
153 /** Serdes BIST pattern */
154 enum al_serdes_bist_pattern {
155 	AL_SRDS_BIST_PATTERN_USER,
156 	AL_SRDS_BIST_PATTERN_PRBS7,
157 	AL_SRDS_BIST_PATTERN_PRBS23,
158 	AL_SRDS_BIST_PATTERN_PRBS31,
159 	AL_SRDS_BIST_PATTERN_CLK1010,
160 };
161 
162 /** SerDes group rate */
163 enum al_serdes_rate {
164 	AL_SRDS_RATE_1_8,
165 	AL_SRDS_RATE_1_4,
166 	AL_SRDS_RATE_1_2,
167 	AL_SRDS_RATE_FULL,
168 };
169 
170 /** SerDes power mode */
171 enum al_serdes_pm {
172 	AL_SRDS_PM_PD,
173 	AL_SRDS_PM_P2,
174 	AL_SRDS_PM_P1,
175 	AL_SRDS_PM_P0S,
176 	AL_SRDS_PM_P0,
177 };
178 
179 /** SerDes PCIe Rate - values are important for proper behavior */
180 enum al_serdes_pcie_rate {
181 	AL_SRDS_PCIE_RATE_GEN1 = 0,
182 	AL_SRDS_PCIE_RATE_GEN2,
183 	AL_SRDS_PCIE_RATE_GEN3,
184 };
185 
186 /**
187  * Initializes a SERDES object
188  *
189  * @param  serdes_regs_base
190  *             The SERDES register file base pointer
191  *
192  * @param obj
193  *             An allocated, non initialized object context
194  *
195  *
196  * @return 0 if no error found.
197  *
198  */
199 int al_serdes_handle_init(
200 	void __iomem		*serdes_regs_base,
201 	struct al_serdes_obj	*obj);
202 
203 /**
204  * SERDES register read
205  *
206  * Reads a SERDES register
207  *
208  * @param  obj
209  *             The object context
210  *
211  * @param  grp
212  *             The SERDES group
213  *
214  * @param  page
215  *             The SERDES register page within the group
216  *
217  * @param  type
218  *             The SERDES register type (PMA /PCS)
219  *
220  * @param  offset
221  *             The SERDES register offset (0 - 4095)
222  *
223  * @param data
224  *             The read data
225  *
226  *
227  * @return 0 if no error found.
228  *
229  */
230 int al_serdes_reg_read(
231 	struct al_serdes_obj	*obj,
232 	enum al_serdes_group	grp,
233 	enum al_serdes_reg_page	page,
234 	enum al_serdes_reg_type	type,
235 	uint16_t		offset,
236 	uint8_t			*data);
237 
238 /**
239  * SERDES register write
240  *
241  * Writes a SERDES register
242  *
243  * @param  obj
244  *             The object context
245  *
246  * @param  grp
247  *             The SERDES group
248  *
249  * @param  page
250  *             The SERDES register page within the group
251  *
252  * @param  type
253  *             The SERDES register type (PMA /PCS)
254  *
255  * @param  offset
256  *             The SERDES register offset (0 - 4095)
257  *
258  * @param  data
259  *             The data to write
260  *
261  *
262  * @return 0 if no error found.
263  *
264  */
265 int al_serdes_reg_write(
266 	struct al_serdes_obj	*obj,
267 	enum al_serdes_group	grp,
268 	enum al_serdes_reg_page	page,
269 	enum al_serdes_reg_type	type,
270 	uint16_t		offset,
271 	uint8_t			data);
272 
273 /**
274  * Enable BIST required overrides
275  *
276  * @param	obj
277  *		The object context
278  * @param	grp
279  *		The SERDES group
280  * @param	rate
281  *		The required speed rate
282  */
283 void al_serdes_bist_overrides_enable(
284 	struct al_serdes_obj	*obj,
285 	enum al_serdes_group	grp,
286 	enum al_serdes_rate	rate);
287 
288 /**
289  * Disable BIST required overrides
290  *
291  * @param	obj
292  *		The object context
293  * @param	grp
294  *		The SERDES group
295  * @param	rate
296  *		The required speed rate
297  */
298 void al_serdes_bist_overrides_disable(
299 	struct al_serdes_obj	*obj,
300 	enum al_serdes_group	grp);
301 
302 /**
303  * Rx rate change
304  *
305  * @param	obj
306  *		The object context
307  * @param	grp
308  *		The SERDES group
309  * @param	rate
310  *		The Rx required rate
311  */
312 void al_serdes_rx_rate_change(
313 	struct al_serdes_obj *obj,
314 	enum al_serdes_group grp,
315 	enum al_serdes_rate rate);
316 
317 /**
318  * SERDES lane Rx rate change software flow enable
319  *
320  * @param	obj
321  *		The object context
322  * @param	grp
323  *		The SERDES group
324  * @param	lane
325  *		The SERDES lane within the group
326  */
327 void al_serdes_lane_rx_rate_change_sw_flow_en(
328 	struct al_serdes_obj	*obj,
329 	enum al_serdes_group	grp,
330 	enum al_serdes_lane	lane);
331 
332 /**
333  * SERDES lane Rx rate change software flow disable
334  *
335  * @param	obj
336  *		The object context
337  * @param	grp
338  *		The SERDES group
339  * @param	lane
340  *		The SERDES lane within the group
341  */
342 void al_serdes_lane_rx_rate_change_sw_flow_dis(
343 	struct al_serdes_obj	*obj,
344 	enum al_serdes_group	grp,
345 	enum al_serdes_lane	lane);
346 
347 /**
348  * PCIe lane rate override check
349  *
350  * @param	obj
351  *		The object context
352  * @param	grp
353  *		The SERDES group
354  * @param	lane
355  *		The SERDES lane within the group
356  * @returns	AL_TRUE if the override is enabled
357  */
358 al_bool al_serdes_lane_pcie_rate_override_is_enabled(
359 	struct al_serdes_obj		*obj,
360 	enum al_serdes_group		grp,
361 	enum al_serdes_lane		lane);
362 
363 /**
364  * PCIe lane rate override control
365  *
366  * @param	obj
367  *		The object context
368  * @param	grp
369  *		The SERDES group
370  * @param	lane
371  *		The SERDES lane within the group
372  * @param	en
373  *		Enable/disable
374  */
375 void al_serdes_lane_pcie_rate_override_enable_set(
376 	struct al_serdes_obj		*obj,
377 	enum al_serdes_group		grp,
378 	enum al_serdes_lane		lane,
379 	al_bool				en);
380 
381 /**
382  * PCIe lane rate get
383  *
384  * @param	obj
385  *		The object context
386  * @param	grp
387  *		The SERDES group
388  * @param	lane
389  *		The SERDES lane within the group
390  */
391 enum al_serdes_pcie_rate al_serdes_lane_pcie_rate_get(
392 	struct al_serdes_obj	*obj,
393 	enum al_serdes_group	grp,
394 	enum al_serdes_lane	lane);
395 
396 /**
397  * PCIe lane rate set
398  *
399  * @param	obj
400  *		The object context
401  * @param	grp
402  *		The SERDES group
403  * @param	lane
404  *		The SERDES lane within the group
405  * @param	rate
406  *		The required rate
407  */
408 void al_serdes_lane_pcie_rate_set(
409 	struct al_serdes_obj		*obj,
410 	enum al_serdes_group		grp,
411 	enum al_serdes_lane		lane,
412 	enum al_serdes_pcie_rate	rate);
413 
414 /**
415  * SERDES group power mode control
416  *
417  * @param	obj
418  *		The object context
419  * @param	grp
420  *		The SERDES group
421  * @param	pm
422  *		The required power mode
423  */
424 void al_serdes_group_pm_set(
425 	struct al_serdes_obj	*obj,
426 	enum al_serdes_group	grp,
427 	enum al_serdes_pm	pm);
428 
429 /**
430  * SERDES lane power mode control
431  *
432  * @param	obj
433  *		The object context
434  * @param	grp
435  *		The SERDES group
436  * @param	lane
437  *		The SERDES lane within the group
438  * @param	rx_pm
439  *		The required RX power mode
440  * @param	tx_pm
441  *		The required TX power mode
442  */
443 void al_serdes_lane_pm_set(
444 	struct al_serdes_obj	*obj,
445 	enum al_serdes_group	grp,
446 	enum al_serdes_lane	lane,
447 	enum al_serdes_pm	rx_pm,
448 	enum al_serdes_pm	tx_pm);
449 
450 /**
451  * SERDES group PMA hard reset
452  *
453  * Controls Serdes group PMA hard reset
454  *
455  * @param  obj
456  *             The object context
457  *
458  * @param  grp
459  *             The SERDES group
460  *
461  * @param  enable
462  *             Enable/disable hard reset
463  */
464 void al_serdes_pma_hard_reset_group(
465 	struct al_serdes_obj	*obj,
466 	enum al_serdes_group	grp,
467 	al_bool			enable);
468 
469 /**
470  * SERDES lane PMA hard reset
471  *
472  * Controls Serdes lane PMA hard reset
473  *
474  * @param  obj
475  *             The object context
476  *
477  * @param  grp
478  *             The SERDES group
479  *
480  * @param  lane
481  *             The SERDES lane within the group
482  *
483  * @param  enable
484  *             Enable/disable hard reset
485  */
486 void al_serdes_pma_hard_reset_lane(
487 	struct al_serdes_obj	*obj,
488 	enum al_serdes_group	grp,
489 	enum al_serdes_lane	lane,
490 	al_bool			enable);
491 
492 /**
493  * SERDES loopback control
494  *
495  * Controls the loopback
496  *
497  * @param  obj
498  *             The object context
499  *
500  * @param  grp
501  *             The SERDES group
502  *
503  * @param  lane
504  *             The SERDES lane within the group
505  *
506  * @param  mode
507  *             The requested loopback mode
508  *
509  */
510 void al_serdes_loopback_control(
511 	struct al_serdes_obj	*obj,
512 	enum al_serdes_group	grp,
513 	enum al_serdes_lane	lane,
514 	enum al_serdes_lb_mode	mode);
515 
516 /**
517  * SERDES BIST pattern selection
518  *
519  * Selects the BIST pattern to be used
520  *
521  * @param  obj
522  *             The object context
523  *
524  * @param  grp
525  *             The SERDES group
526  *
527  * @param  pattern
528  *             The pattern to set
529  *
530  * @param  user_data
531  *             The pattern user data (when pattern == AL_SRDS_BIST_PATTERN_USER)
532  *             80 bits (8 bytes array)
533  *
534  */
535 void al_serdes_bist_pattern_select(
536 	struct al_serdes_obj		*obj,
537 	enum al_serdes_group		grp,
538 	enum al_serdes_bist_pattern	pattern,
539 	uint8_t				*user_data);
540 
541 /**
542  * SERDES BIST TX Enable
543  *
544  * Enables/disables TX BIST per lane
545  *
546  * @param  obj
547  *             The object context
548  *
549  * @param  grp
550  *             The SERDES group
551  *
552  * @param  lane
553  *             The SERDES lane within the group
554  *
555  * @param  enable
556  *             Enable or disable TX BIST
557  */
558 void al_serdes_bist_tx_enable(
559 	struct al_serdes_obj	*obj,
560 	enum al_serdes_group	grp,
561 	enum al_serdes_lane	lane,
562 	al_bool			enable);
563 
564 /**
565  * SERDES BIST TX single bit error injection
566  *
567  * Injects single bit error during a TX BIST
568  *
569  * @param  obj
570  *             The object context
571  *
572  * @param  grp
573  *             The SERDES group
574  */
575 void al_serdes_bist_tx_err_inject(
576 	struct al_serdes_obj	*obj,
577 	enum al_serdes_group	grp);
578 
579 /**
580  * SERDES BIST RX Enable
581  *
582  * Enables/disables RX BIST per lane
583  *
584  * @param  obj
585  *             The object context
586  *
587  * @param  grp
588  *             The SERDES group
589  *
590  * @param  lane
591  *             The SERDES lane within the group
592  *
593  * @param  enable
594  *             Enable or disable TX BIST
595  */
596 void al_serdes_bist_rx_enable(
597 	struct al_serdes_obj	*obj,
598 	enum al_serdes_group	grp,
599 	enum al_serdes_lane	lane,
600 	al_bool			enable);
601 
602 /**
603  * SERDES BIST RX status
604  *
605  * Checks the RX BIST status for a specific SERDES lane
606  *
607  * @param  obj
608  *             The object context
609  *
610  * @param  grp
611  *             The SERDES group
612  *
613  * @param  lane
614  *             The SERDES lane within the group
615  *
616  * @param is_locked
617  *             An indication whether RX BIST is locked
618  *
619  * @param err_cnt_overflow
620  *             An indication whether error count overflow occured
621  *
622  * @param err_cnt
623  *             Current bit error count
624  */
625 void al_serdes_bist_rx_status(
626 	struct al_serdes_obj	*obj,
627 	enum al_serdes_group	grp,
628 	enum al_serdes_lane	lane,
629 	al_bool			*is_locked,
630 	al_bool			*err_cnt_overflow,
631 	uint16_t		*err_cnt);
632 
633 /**
634  * SERDES Digital Test Bus
635  *
636  * Samples the digital test bus of a specific SERDES lane
637  *
638  * @param  obj
639  *             The object context
640  *
641  * @param  grp
642  *             The SERDES group
643  *
644  * @param  lane
645  *             The SERDES lane within the group
646  *
647  * @param  sel
648  *             The selected sampling group (0 - 31)
649  *
650  * @param sampled_data
651  *             The sampled data (5 bytes array)
652  *
653  *
654  * @return 0 if no error found.
655  *
656  */
657 int al_serdes_digital_test_bus(
658 	struct al_serdes_obj	*obj,
659 	enum al_serdes_group	grp,
660 	enum al_serdes_lane	lane,
661 	uint8_t			sel,
662 	uint8_t			*sampled_data);
663 
664 
665 /* KR link training */
666 /**
667  * Set the tx de-emphasis to preset values
668  *
669  * @param obj The object context
670  *
671  * @param grp The SERDES group
672  *
673  * @param lane The SERDES lane within the group
674  *
675  */
676 void al_serdes_tx_deemph_preset(
677 		struct al_serdes_obj	*obj,
678 		enum al_serdes_group	grp,
679 		enum al_serdes_lane	lane);
680 
681 /**
682  * Tx de-emphasis parameters
683  */
684 enum al_serdes_tx_deemph_param {
685 	AL_SERDES_TX_DEEMP_C_ZERO,	/*< c(0) */
686 	AL_SERDES_TX_DEEMP_C_PLUS,	/*< c(1) */
687 	AL_SERDES_TX_DEEMP_C_MINUS,	/*< c(-1) */
688 };
689 
690 /**
691  * Increase tx de-emphasis param.
692  *
693  * @param obj The object context
694  *
695  * @param grp The SERDES group
696  *
697  * @param lane The SERDES lane within the group
698  *
699  * @param param which tx de-emphasis to change
700  *
701  * @return false in case max is reached. true otherwise.
702  */
703 al_bool al_serdes_tx_deemph_inc(
704 		struct al_serdes_obj	*obj,
705 		enum al_serdes_group	grp,
706 		enum al_serdes_lane	lane,
707 		enum al_serdes_tx_deemph_param param);
708 
709 /**
710  * Decrease tx de-emphasis param.
711  *
712  * @param obj The object context
713  *
714  * @param grp The SERDES group
715  *
716  * @param lane The SERDES lane within the group
717  *
718  * @param param which tx de-emphasis to change
719  *
720  * @return false in case min is reached. true otherwise.
721  */
722 al_bool al_serdes_tx_deemph_dec(
723 		struct al_serdes_obj	*obj,
724 		enum al_serdes_group	grp,
725 		enum al_serdes_lane	lane,
726 		enum al_serdes_tx_deemph_param param);
727 
728 /**
729  * run Rx eye measurement.
730  *
731  * @param obj The object context
732  *
733  * @param grp The SERDES group
734  *
735  * @param lane The SERDES lane within the group
736  *
737  * @param timeout timeout in uSec
738  *
739  * @param value Rx eye measurement value
740  *		(0 - completely closed eye, 0xffff - completely open eye).
741  *
742  * @return 0 if no error found.
743  */
744 int al_serdes_eye_measure_run(
745 		struct al_serdes_obj	*obj,
746 		enum al_serdes_group	grp,
747 		enum al_serdes_lane	lane,
748 		uint32_t		timeout,
749 		unsigned int		*value);
750 
751 /**
752  * Eye diagram single sampling
753  *
754  * @param obj The object context
755  *
756  * @param grp The SERDES group
757  *
758  * @param lane The SERDES lane within the group
759  *
760  * @param x Sampling X position (0 - 63 --> -1.00 UI ... 1.00 UI)
761  *
762  * @param y Sampling Y position (0 - 62 --> 500mV ... -500mV)
763  *
764  * @param timeout timeout in uSec
765  *
766  * @param value Eye diagram sample value (BER - 0x0000 - 0xffff)
767  *
768  * @return 0 if no error found.
769  */
770 int al_serdes_eye_diag_sample(
771 		struct al_serdes_obj	*obj,
772 		enum al_serdes_group	grp,
773 		enum al_serdes_lane	lane,
774 		unsigned int		x,
775 		int			y,
776 		unsigned int		timeout,
777 		unsigned int		*value);
778 
779 /**
780  * Check if signal is detected
781  *
782  * @param obj The object context
783  *
784  * @param grp The SERDES group
785  *
786  * @param lane The SERDES lane within the group
787  *
788  * @return true if signal is detected. false otherwise.
789  */
790 al_bool al_serdes_signal_is_detected(
791 		struct al_serdes_obj	*obj,
792 		enum al_serdes_group	grp,
793 		enum al_serdes_lane	lane);
794 
795 
796 struct al_serdes_adv_tx_params {
797 	/*
798 	 * select the input values location.
799 	 * When set to true the values will be taken from the internal registers
800 	 * that will be override with the next following parameters.
801 	 * When set to false the values will be taken from external pins (the
802 	 * other parameters in this case is not needed)
803 	 */
804 	al_bool				override;
805 	/*
806 	 * Transmit Amplitude control signal. Used to define the full-scale
807 	 * maximum swing of the driver.
808 	 *	000 - Not Supported
809 	 *	001 - 952mVdiff-pkpk
810 	 *	010 - 1024mVdiff-pkpk
811 	 *	011 - 1094mVdiff-pkpk
812 	 *	100 - 1163mVdiff-pkpk
813 	 *	101 - 1227mVdiff-pkpk
814 	 *	110 - 1283mVdiff-pkpk
815 	 *	111 - 1331mVdiff-pkpk
816 	 */
817 	uint8_t				amp;
818 	/* Defines the total number of driver units allocated in the driver */
819 	uint8_t				total_driver_units;
820 	/* Defines the total number of driver units allocated to the
821 	 * first post-cursor (C+1) tap. */
822 	uint8_t				c_plus_1;
823 	/* Defines the total number of driver units allocated to the
824 	 * second post-cursor (C+2) tap. */
825 	uint8_t				c_plus_2;
826 	/* Defines the total number of driver units allocated to the
827 	 * first pre-cursor (C-1) tap. */
828 	uint8_t				c_minus_1;
829 	/* TX driver Slew Rate control:
830 	 *	00 - 31ps
831 	 *	01 - 33ps
832 	 *	10 - 68ps
833 	 *	11 - 170ps
834 	 */
835 	uint8_t				slew_rate;
836 };
837 
838 struct al_serdes_adv_rx_params {
839 	/*
840 	 * select the input values location.
841 	 * When set to true the values will be taken from the internal registers
842 	 * that will be override with the next following parameters.
843 	 * When set to false the values will be taken based in the equalization
844 	 * results (the other parameters in this case is not needed)
845 	 */
846 	al_bool				override;
847 	/* RX agc high frequency dc gain:
848 	 *	-3'b000: -3dB
849 	 *	-3'b001: -2.5dB
850 	 *	-3'b010: -2dB
851 	 *	-3'b011: -1.5dB
852 	 *	-3'b100: -1dB
853 	 *	-3'b101: -0.5dB
854 	 *	-3'b110: -0dB
855 	 *	-3'b111: 0.5dB
856 	 */
857 	uint8_t				dcgain;
858 	/* DFE post-shaping tap 3dB frequency
859 	 *	-3'b000: 684MHz
860 	 *	-3'b001: 576MHz
861 	 *	-3'b010: 514MHz
862 	 *	-3'b011: 435MHz
863 	 *	-3'b100: 354MHz
864 	 *	-3'b101: 281MHz
865 	 *	-3'b110: 199MHz
866 	 *	-3'b111: 125MHz
867 	 */
868 	uint8_t				dfe_3db_freq;
869 	/* DFE post-shaping tap gain
870 	 *	0: no pulse shaping tap
871 	 *	1: -24mVpeak
872 	 *	2: -45mVpeak
873 	 *	3: -64mVpeak
874 	 *	4: -80mVpeak
875 	 *	5: -93mVpeak
876 	 *	6: -101mVpeak
877 	 *	7: -105mVpeak
878 	 */
879 	uint8_t				dfe_gain;
880 	/* DFE first tap gain control
881 	 *	-4'b0000: +1mVpeak
882 	 *	-4'b0001: +10mVpeak
883 	 *	....
884 	 *	-4'b0110: +55mVpeak
885 	 *	-4'b0111: +64mVpeak
886 	 *	-4'b1000: -1mVpeak
887 	 *	-4'b1001: -10mVpeak
888 	 *	....
889 	 *	-4'b1110: -55mVpeak
890 	 *	-4'b1111: -64mVpeak
891 	 */
892 	uint8_t				dfe_first_tap_ctrl;
893 	/* DFE second tap gain control
894 	 *	-4'b0000: +0mVpeak
895 	 *	-4'b0001: +9mVpeak
896 	 *	....
897 	 *	-4'b0110: +46mVpeak
898 	 *	-4'b0111: +53mVpeak
899 	 *	-4'b1000: -0mVpeak
900 	 *	-4'b1001: -9mVpeak
901 	 *	....
902 	 *	-4'b1110: -46mVpeak
903 	 *	-4'b1111: -53mVpeak
904 	 */
905 	uint8_t				dfe_secound_tap_ctrl;
906 	/* DFE third tap gain control
907 	 *	-4'b0000: +0mVpeak
908 	 *	-4'b0001: +7mVpeak
909 	 *	....
910 	 *	-4'b0110: +38mVpeak
911 	 *	-4'b0111: +44mVpeak
912 	 *	-4'b1000: -0mVpeak
913 	 *	-4'b1001: -7mVpeak
914 	 *	....
915 	 *	-4'b1110: -38mVpeak
916 	 *	-4'b1111: -44mVpeak
917 	 */
918 	uint8_t				dfe_third_tap_ctrl;
919 	/* DFE fourth tap gain control
920 	 *	-4'b0000: +0mVpeak
921 	 *	-4'b0001: +6mVpeak
922 	 *	....
923 	 *	-4'b0110: +29mVpeak
924 	 *	-4'b0111: +33mVpeak
925 	 *	-4'b1000: -0mVpeak
926 	 *	-4'b1001: -6mVpeak
927 	 *	....
928 	 *	-4'b1110: -29mVpeak
929 	 *	-4'b1111: -33mVpeak
930 	 */
931 	uint8_t				dfe_fourth_tap_ctrl;
932 	/* Low frequency agc gain (att) select
933 	 *	-3'b000: Disconnected
934 	 *	-3'b001: -18.5dB
935 	 *	-3'b010: -12.5dB
936 	 *	-3'b011: -9dB
937 	 *	-3'b100: -6.5dB
938 	 *	-3'b101: -4.5dB
939 	 *	-3'b110: -2.9dB
940 	 *	-3'b111: -1.6dB
941 	 */
942 	uint8_t				low_freq_agc_gain;
943 	/* Provides a RX Equalizer pre-hint, prior to beginning
944 	 * adaptive equalization */
945 	uint8_t				precal_code_sel;
946 	/* High frequency agc boost control
947 	 *	Min d0: Boost ~4dB
948 	 *	Max d31: Boost ~20dB
949 	 */
950 	uint8_t				high_freq_agc_boost;
951 };
952 
953 /**
954  * configure tx advanced parameters
955  *
956  * @param obj The object context
957  *
958  * @param grp The SERDES group
959  *
960  * @param lane The SERDES lane within the group
961  *
962  * @param params pointer to the tx parameters
963  */
964 void al_serdes_tx_advanced_params_set(struct al_serdes_obj	      	*obj,
965 				      enum al_serdes_group		grp,
966 				      enum al_serdes_lane		lane,
967 				      struct al_serdes_adv_tx_params  *params);
968 
969 /**
970  * read tx advanced parameters
971  *
972  * @param obj The object context
973  *
974  * @param grp The SERDES group
975  *
976  * @param lane The SERDES lane within the group
977  *
978  * @param params pointer to the tx parameters
979  */
980 void al_serdes_tx_advanced_params_get(struct al_serdes_obj	     	*obj,
981 				      enum al_serdes_group	      	grp,
982 				      enum al_serdes_lane		lane,
983 				      struct al_serdes_adv_tx_params *params);
984 
985 /**
986  * configure rx advanced parameters
987  *
988  * @param obj The object context
989  *
990  * @param grp The SERDES group
991  *
992  * @param lane The SERDES lane within the group
993  *
994  * @param params pointer to the rx parameters
995  */
996 void al_serdes_rx_advanced_params_set(struct al_serdes_obj	      *obj,
997 				      enum al_serdes_group	      grp,
998 				      enum al_serdes_lane	      lane,
999 				      struct al_serdes_adv_rx_params  *params);
1000 
1001 /**
1002  * read rx advanced parameters
1003  *
1004  * @param obj The object context
1005  *
1006  * @param grp The SERDES group
1007  *
1008  * @param lane The SERDES lane within the group
1009  *
1010  * @param params pointer to the rx parameters
1011  */
1012 void al_serdes_rx_advanced_params_get(struct al_serdes_obj           *obj,
1013 				      enum al_serdes_group	      grp,
1014 				      enum al_serdes_lane	      lane,
1015 				      struct al_serdes_adv_rx_params* params);
1016 
1017 /**
1018  *  Switch entire SerDes group to SGMII mode based on 156.25 Mhz reference clock
1019  *
1020  * @param obj The object context
1021  *
1022  * @param grp The SERDES group
1023  */
1024 void al_serdes_mode_set_sgmii(
1025 	struct al_serdes_obj	*obj,
1026 	enum al_serdes_group	grp);
1027 
1028 /**
1029  *  Switch entire SerDes group to KR mode based on 156.25 Mhz reference clock
1030  *
1031  * @param obj The object context
1032  *
1033  * @param grp The SERDES group
1034  */
1035 void al_serdes_mode_set_kr(
1036 	struct al_serdes_obj	*obj,
1037 	enum al_serdes_group	grp);
1038 
1039 /**
1040  * performs SerDes HW equalization test and update equalization parameters
1041  *
1042  * @param obj the object context
1043  *
1044  * @param grp the SERDES group
1045  *
1046  * @param lane The SERDES lane within the group
1047  */
1048 int al_serdes_rx_equalization(
1049 		struct al_serdes_obj	*obj,
1050 		enum al_serdes_group	grp,
1051 		enum al_serdes_lane	lane);
1052 
1053 /**
1054  * performs Rx equalization and compute the width and height of the eye
1055  *
1056  * @param obj the object context
1057  *
1058  * @param grp the SERDES group
1059  *
1060  * @param lane The SERDES lane within the group
1061  *
1062  * @param width the output width of the eye
1063  *
1064  * @param height the output height of the eye
1065  */
1066 int al_serdes_calc_eye_size(
1067 		struct al_serdes_obj *obj,
1068 		enum al_serdes_group grp,
1069 		enum al_serdes_lane  lane,
1070 		int*                 width,
1071 		int*                 height);
1072 
1073 /**
1074  * SRIS parameters
1075  */
1076 struct al_serdes_sris_params {
1077 	/* Controls the frequency accuracy threshold (ppm) for lock detection CDR */
1078 	uint16_t	ppm_drift_count;
1079 	/* Controls the frequency accuracy threshold (ppm) for lock detection in the CDR */
1080 	uint16_t	ppm_drift_max;
1081 	/* Controls the frequency accuracy threshold (ppm) for lock detection in PLL */
1082 	uint16_t	synth_ppm_drift_max;
1083 	/* Elastic buffer full threshold for PCIE modes: GEN1/GEN2 */
1084 	uint8_t		full_d2r1;
1085 	/* Elastic buffer full threshold for PCIE modes: GEN3 */
1086 	uint8_t		full_pcie_g3;
1087 	/* Elastic buffer midpoint threshold.
1088 	 * Sets the depth of the buffer while in PCIE mode, GEN1/GEN2
1089 	 */
1090 	uint8_t		rd_threshold_d2r1;
1091 	/* Elastic buffer midpoint threshold.
1092 	 * Sets the depth of the buffer while in PCIE mode, GEN3
1093 	 */
1094 	uint8_t		rd_threshold_pcie_g3;
1095 };
1096 
1097 /**
1098  * SRIS: Separate Refclk Independent SSC (Spread Spectrum Clocking)
1099  * Currently available only for PCIe interfaces.
1100  * When working with local Refclk, same SRIS configuration in both serdes sides
1101  * (EP and RC in PCIe interface) is required.
1102  *
1103  * performs SRIS configuration according to params
1104  *
1105  * @param obj the object context
1106  *
1107  * @param grp the SERDES group
1108  *
1109  * @param params the SRIS parameters
1110  */
1111 void al_serdes_sris_config(
1112 	struct al_serdes_obj		*obj,
1113 	enum al_serdes_group		grp,
1114 	struct al_serdes_sris_params	*params);
1115 
1116 /* *INDENT-OFF* */
1117 #ifdef __cplusplus
1118 }
1119 #endif
1120 
1121 /* *INDENT-ON* */
1122 #endif		/* __AL_SRDS__ */
1123 
1124 /** @} end of SERDES group */
1125 
1126