al_hal_serdes.c revision 303975
1/*-
2*******************************************************************************
3Copyright (C) 2015 Annapurna Labs Ltd.
4
5This file may be licensed under the terms of the Annapurna Labs Commercial
6License Agreement.
7
8Alternatively, this file can be distributed under the terms of the GNU General
9Public License V2 as published by the Free Software Foundation and can be
10found at http://www.gnu.org/licenses/gpl-2.0.html
11
12Alternatively, redistribution and use in source and binary forms, with or
13without modification, are permitted provided that the following conditions are
14met:
15
16    *     Redistributions of source code must retain the above copyright notice,
17this list of conditions and the following disclaimer.
18
19    *     Redistributions in binary form must reproduce the above copyright
20notice, this list of conditions and the following disclaimer in
21the documentation and/or other materials provided with the
22distribution.
23
24THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
25ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
28ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
31ANY 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
33SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
35*******************************************************************************/
36
37#include "al_hal_serdes.h"
38#include "al_hal_serdes_regs.h"
39#include "al_hal_serdes_internal_regs.h"
40
41#define SRDS_CORE_REG_ADDR(page, type, offset)\
42	(((page) << 13) | ((type) << 12) | (offset))
43
44/* Link Training configuration */
45#define AL_SERDES_TX_DEEMPH_SUM_MAX		0x1b
46
47/* c configurations */
48#define AL_SERDES_TX_DEEMPH_C_ZERO_MAX_VAL	0x1b
49#define AL_SERDES_TX_DEEMPH_C_ZERO_MIN_VAL	0
50#define AL_SERDES_TX_DEEMPH_C_ZERO_PRESET	AL_SERDES_TX_DEEMPH_C_ZERO_MAX_VAL
51
52/* c(+1) configurations */
53#define AL_SERDES_TX_DEEMPH_C_PLUS_MAX_VAL	0x9
54#define AL_SERDES_TX_DEEMPH_C_PLUS_MIN_VAL	0
55#define AL_SERDES_TX_DEEMPH_C_PLUS_PRESET	AL_SERDES_TX_DEEMPH_C_PLUS_MIN_VAL
56
57/* c(-1) configurations */
58#define AL_SERDES_TX_DEEMPH_C_MINUS_MAX_VAL	0x6
59#define AL_SERDES_TX_DEEMPH_C_MINUS_MIN_VAL	0
60#define AL_SERDES_TX_DEEMPH_C_MINUS_PRESET	AL_SERDES_TX_DEEMPH_C_MINUS_MIN_VAL
61
62/* Rx equal total delay = MDELAY * TRIES */
63#define AL_SERDES_RX_EQUAL_MDELAY		10
64#define AL_SERDES_RX_EQUAL_TRIES		50
65
66/* Rx eye calculation delay = MDELAY * TRIES */
67#define AL_SERDES_RX_EYE_CAL_MDELAY		50
68#define AL_SERDES_RX_EYE_CAL_TRIES		70
69
70
71/**
72 * Prototypes for _lane_ compatibility
73 */
74int al_serdes_lane_read(
75	struct al_serdes_obj	*obj,
76	enum al_serdes_group	grp,
77	enum al_serdes_lane	lane,
78	enum al_serdes_reg_type	type,
79	uint16_t		offset,
80	uint8_t			*data);
81
82int al_serdes_lane_write(
83	struct al_serdes_obj	*obj,
84	enum al_serdes_group	grp,
85	enum al_serdes_lane	lane,
86	enum al_serdes_reg_type	type,
87	uint16_t		offset,
88	uint8_t			data);
89
90
91/**
92 * SERDES core reg/lane read
93 */
94static inline uint8_t al_serdes_grp_reg_read(
95	struct al_serdes_group_info	*grp_info,
96	enum al_serdes_reg_page		page,
97	enum al_serdes_reg_type		type,
98	uint16_t			offset);
99
100static inline uint8_t al_serdes_grp_lane_read(
101	struct al_serdes_group_info	*grp_info,
102	enum al_serdes_lane		page,
103	enum al_serdes_reg_type		type,
104	uint16_t			offset);
105
106/**
107 * SERDES core reg/lane write
108 */
109static inline void al_serdes_grp_reg_write(
110	struct al_serdes_group_info	*grp_info,
111	enum al_serdes_reg_page		page,
112	enum al_serdes_reg_type		type,
113	uint16_t			offset,
114	uint8_t				data);
115
116static inline void al_serdes_grp_lane_write(
117	struct al_serdes_group_info	*grp_info,
118	enum al_serdes_lane		lane,
119	enum al_serdes_reg_type		type,
120	uint16_t			offset,
121	uint8_t				data);
122
123/**
124 * SERDES core masked reg/lane write
125 */
126static inline void al_serdes_grp_reg_masked_write(
127	struct al_serdes_group_info	*grp_info,
128	enum al_serdes_reg_page		page,
129	enum al_serdes_reg_type		type,
130	uint16_t			offset,
131	uint8_t				mask,
132	uint8_t				data);
133
134/**
135 * Lane Rx rate change software flow disable
136 */
137static void _al_serdes_lane_rx_rate_change_sw_flow_dis(
138	struct al_serdes_group_info	*grp_info,
139	enum al_serdes_lane		lane);
140
141/**
142 * Group Rx rate change software flow enable if all conditions met
143 */
144static void al_serdes_group_rx_rate_change_sw_flow_dis(
145	struct al_serdes_group_info	*grp_info);
146
147/**
148 * Lane Rx rate change software flow enable if all conditions met
149 */
150static void _al_serdes_lane_rx_rate_change_sw_flow_en_cond(
151	struct al_serdes_group_info	*grp_info,
152	enum al_serdes_lane		lane);
153
154/**
155 * Group Rx rate change software flow enable if all conditions met
156 */
157static void al_serdes_group_rx_rate_change_sw_flow_en_cond(
158	struct al_serdes_group_info	*grp_info);
159
160
161static inline void al_serdes_grp_lane_masked_write(
162	struct al_serdes_group_info	*grp_info,
163	enum al_serdes_lane		lane,
164	enum al_serdes_reg_type		type,
165	uint16_t			offset,
166	uint8_t				mask,
167	uint8_t				data);
168
169/******************************************************************************/
170/******************************************************************************/
171int al_serdes_handle_init(
172	void __iomem			*serdes_regs_base,
173	struct al_serdes_obj		*obj)
174{
175	int i;
176
177	al_dbg(
178		"%s(%p, %p)\n",
179		__func__,
180		serdes_regs_base,
181		obj);
182
183	al_assert(serdes_regs_base);
184
185	for (i = 0; i < AL_SRDS_NUM_GROUPS; i++) {
186		obj->grp_info[i].pobj = obj;
187
188		obj->grp_info[i].regs_base =
189			&((struct al_serdes_regs *)serdes_regs_base)[i];
190	}
191
192	return 0;
193}
194
195/******************************************************************************/
196/******************************************************************************/
197int al_serdes_reg_read(
198	struct al_serdes_obj	*obj,
199	enum al_serdes_group	grp,
200	enum al_serdes_reg_page	page,
201	enum al_serdes_reg_type	type,
202	uint16_t		offset,
203	uint8_t			*data)
204{
205	int status = 0;
206
207	al_dbg(
208		"%s(%p, %d, %d, %d, %u)\n",
209		__func__,
210		obj,
211		grp,
212		page,
213		type,
214		offset);
215
216	al_assert(obj);
217	al_assert(data);
218	al_assert(((int)grp) >= AL_SRDS_GRP_A);
219	al_assert(((int)grp) <= AL_SRDS_GRP_D);
220	al_assert(((int)page) >= AL_SRDS_REG_PAGE_0_LANE_0);
221	al_assert(((int)page) <= AL_SRDS_REG_PAGE_4_COMMON);
222	al_assert(((int)type) >= AL_SRDS_REG_TYPE_PMA);
223	al_assert(((int)type) <= AL_SRDS_REG_TYPE_PCS);
224
225	*data = al_serdes_grp_reg_read(
226		&obj->grp_info[grp],
227		page,
228		type,
229		offset);
230
231	al_dbg(
232		"%s: return(%u)\n",
233		__func__,
234		*data);
235
236	return status;
237}
238
239int al_serdes_lane_read(
240	struct al_serdes_obj	*obj,
241	enum al_serdes_group	grp,
242	enum al_serdes_lane	lane,
243	enum al_serdes_reg_type	type,
244	uint16_t		offset,
245	uint8_t			*data)
246{
247	return al_serdes_reg_read(obj, grp, (enum al_serdes_reg_page)lane, type,
248				  offset, data);
249}
250/******************************************************************************/
251/******************************************************************************/
252int al_serdes_reg_write(
253	struct al_serdes_obj	*obj,
254	enum al_serdes_group	grp,
255	enum al_serdes_reg_page	page,
256	enum al_serdes_reg_type	type,
257	uint16_t		offset,
258	uint8_t			data)
259{
260	int status = 0;
261
262	al_dbg(
263		"%s(%p, %d, %d, %d, %u, %u)\n",
264		__func__,
265		obj,
266		grp,
267		page,
268		type,
269		offset,
270		data);
271
272	al_assert(obj);
273	al_assert(((int)grp) >= AL_SRDS_GRP_A);
274	al_assert(((int)grp) <= AL_SRDS_GRP_D);
275	al_assert(((int)page) >= AL_SRDS_REG_PAGE_0_LANE_0);
276	al_assert(((int)page) <= AL_SRDS_REG_PAGE_0123_LANES_0123);
277	al_assert(((int)type) >= AL_SRDS_REG_TYPE_PMA);
278	al_assert(((int)type) <= AL_SRDS_REG_TYPE_PCS);
279
280	al_serdes_grp_reg_write(
281		&obj->grp_info[grp],
282		page,
283		type,
284		offset,
285		data);
286
287	return status;
288}
289
290int al_serdes_lane_write(
291	struct al_serdes_obj	*obj,
292	enum al_serdes_group	grp,
293	enum al_serdes_lane	lane,
294	enum al_serdes_reg_type	type,
295	uint16_t		offset,
296	uint8_t			data)
297{
298	return al_serdes_reg_write(obj, grp, (enum al_serdes_reg_page)lane,
299				   type, offset, data);
300}
301/******************************************************************************/
302/******************************************************************************/
303#if (SERDES_IREG_FLD_PCSRX_DATAWIDTH_REG_NUM != SERDES_IREG_FLD_PCSTX_DATAWIDTH_REG_NUM)
304#error "Wrong assumption!"
305#endif
306#if (SERDES_IREG_FLD_PCSRX_DIVRATE_REG_NUM != SERDES_IREG_FLD_PCSTX_DIVRATE_REG_NUM)
307#error "Wrong assumption!"
308#endif
309#if (SERDES_IREG_FLD_CMNPCIEGEN3_LOCWREN_REG_NUM != SERDES_IREG_FLD_CMNPCS_LOCWREN_REG_NUM)
310#error "Wrong assumption!"
311#endif
312#if (SERDES_IREG_FLD_CMNPCIEGEN3_LOCWREN_REG_NUM != SERDES_IREG_FLD_CMNPCSBIST_LOCWREN_REG_NUM)
313#error "Wrong assumption!"
314#endif
315#if (SERDES_IREG_FLD_CMNPCIEGEN3_LOCWREN_REG_NUM != SERDES_IREG_FLD_CMNPCSPSTATE_LOCWREN_REG_NUM)
316#error "Wrong assumption!"
317#endif
318#if (SERDES_IREG_FLD_LANEPCSPSTATE_LOCWREN_REG_NUM != SERDES_IREG_FLD_LB_LOCWREN_REG_NUM)
319#error "Wrong assumption!"
320#endif
321#if (SERDES_IREG_FLD_LANEPCSPSTATE_LOCWREN_REG_NUM != SERDES_IREG_FLD_PCSRX_LOCWREN_REG_NUM)
322#error "Wrong assumption!"
323#endif
324#if (SERDES_IREG_FLD_LANEPCSPSTATE_LOCWREN_REG_NUM != SERDES_IREG_FLD_PCSRXBIST_LOCWREN_REG_NUM)
325#error "Wrong assumption!"
326#endif
327#if (SERDES_IREG_FLD_LANEPCSPSTATE_LOCWREN_REG_NUM != SERDES_IREG_FLD_PCSRXEQ_LOCWREN_REG_NUM)
328#error "Wrong assumption!"
329#endif
330#if (SERDES_IREG_FLD_LANEPCSPSTATE_LOCWREN_REG_NUM != SERDES_IREG_FLD_PCSTX_LOCWREN_REG_NUM)
331#error "Wrong assumption!"
332#endif
333void al_serdes_bist_overrides_enable(
334	struct al_serdes_obj	*obj,
335	enum al_serdes_group	grp,
336	enum al_serdes_rate	rate)
337{
338	struct al_serdes_group_info *grp_info = &obj->grp_info[grp];
339	int i;
340
341	uint8_t rx_rate_val;
342	uint8_t tx_rate_val;
343
344	switch (rate) {
345	case AL_SRDS_RATE_1_8:
346		rx_rate_val = SERDES_IREG_FLD_PCSRX_DIVRATE_VAL_1_8;
347		tx_rate_val = SERDES_IREG_FLD_PCSTX_DIVRATE_VAL_1_8;
348		break;
349	case AL_SRDS_RATE_1_4:
350		rx_rate_val = SERDES_IREG_FLD_PCSRX_DIVRATE_VAL_1_4;
351		tx_rate_val = SERDES_IREG_FLD_PCSTX_DIVRATE_VAL_1_4;
352		break;
353	case AL_SRDS_RATE_1_2:
354		rx_rate_val = SERDES_IREG_FLD_PCSRX_DIVRATE_VAL_1_2;
355		tx_rate_val = SERDES_IREG_FLD_PCSTX_DIVRATE_VAL_1_2;
356		break;
357	case AL_SRDS_RATE_FULL:
358		rx_rate_val = SERDES_IREG_FLD_PCSRX_DIVRATE_VAL_1_1;
359		tx_rate_val = SERDES_IREG_FLD_PCSTX_DIVRATE_VAL_1_1;
360		break;
361	default:
362		al_err("%s: invalid rate (%d)\n",  __func__, rate);
363		al_assert(0);
364		rx_rate_val = SERDES_IREG_FLD_PCSRX_DIVRATE_VAL_1_1;
365		tx_rate_val = SERDES_IREG_FLD_PCSTX_DIVRATE_VAL_1_1;
366	}
367
368	for (i = 0; i < AL_SRDS_NUM_LANES; i++) {
369		al_serdes_grp_reg_masked_write(
370			grp_info,
371			(enum al_serdes_reg_page)i,
372			AL_SRDS_REG_TYPE_PMA,
373			SERDES_IREG_FLD_PCSRX_DATAWIDTH_REG_NUM,
374			SERDES_IREG_FLD_PCSRX_DATAWIDTH_MASK |
375			SERDES_IREG_FLD_PCSTX_DATAWIDTH_MASK,
376			SERDES_IREG_FLD_PCSRX_DATAWIDTH_VAL_20 |
377			SERDES_IREG_FLD_PCSTX_DATAWIDTH_VAL_20);
378
379		al_serdes_grp_reg_masked_write(
380			grp_info,
381			(enum al_serdes_reg_page)i,
382			AL_SRDS_REG_TYPE_PMA,
383			SERDES_IREG_FLD_PCSRX_DIVRATE_REG_NUM,
384			SERDES_IREG_FLD_PCSRX_DIVRATE_MASK |
385			SERDES_IREG_FLD_PCSTX_DIVRATE_MASK,
386			rx_rate_val | tx_rate_val);
387	}
388
389	al_serdes_grp_reg_masked_write(
390		grp_info,
391		AL_SRDS_REG_PAGE_4_COMMON,
392		AL_SRDS_REG_TYPE_PMA,
393		SERDES_IREG_FLD_CMNPCIEGEN3_LOCWREN_REG_NUM,
394		SERDES_IREG_FLD_CMNPCIEGEN3_LOCWREN |
395		SERDES_IREG_FLD_CMNPCS_LOCWREN |
396		SERDES_IREG_FLD_CMNPCSBIST_LOCWREN |
397		SERDES_IREG_FLD_CMNPCSPSTATE_LOCWREN,
398		0);
399
400	al_serdes_grp_reg_masked_write(
401		grp_info,
402		AL_SRDS_REG_PAGE_4_COMMON,
403		AL_SRDS_REG_TYPE_PMA,
404		SERDES_IREG_FLD_CMNPCIEGEN3_LOCWREN_REG_NUM,
405		SERDES_IREG_FLD_CMNPCIEGEN3_LOCWREN |
406		SERDES_IREG_FLD_CMNPCS_LOCWREN |
407		SERDES_IREG_FLD_CMNPCSBIST_LOCWREN |
408		SERDES_IREG_FLD_CMNPCSPSTATE_LOCWREN,
409		0);
410
411	al_serdes_grp_reg_masked_write(
412		grp_info,
413		AL_SRDS_REG_PAGE_4_COMMON,
414		AL_SRDS_REG_TYPE_PMA,
415		SERDES_IREG_FLD_PCS_LOCWREN_REG_NUM,
416		SERDES_IREG_FLD_PCS_LOCWREN,
417		0);
418
419	al_serdes_grp_reg_masked_write(
420		grp_info,
421		AL_SRDS_REG_PAGE_4_COMMON,
422		AL_SRDS_REG_TYPE_PMA,
423		SERDES_IREG_FLD_CMNPCS_TXENABLE_REG_NUM,
424		SERDES_IREG_FLD_CMNPCS_TXENABLE,
425		SERDES_IREG_FLD_CMNPCS_TXENABLE);
426
427	for (i = 0; i < AL_SRDS_NUM_LANES; i++) {
428		al_serdes_grp_reg_masked_write(
429			grp_info,
430			(enum al_serdes_reg_page)i,
431			AL_SRDS_REG_TYPE_PMA,
432			SERDES_IREG_FLD_LANEPCSPSTATE_LOCWREN_REG_NUM,
433			SERDES_IREG_FLD_LANEPCSPSTATE_LOCWREN |
434			SERDES_IREG_FLD_LB_LOCWREN |
435			SERDES_IREG_FLD_PCSRX_LOCWREN |
436			SERDES_IREG_FLD_PCSRXBIST_LOCWREN |
437			SERDES_IREG_FLD_PCSRXEQ_LOCWREN |
438			SERDES_IREG_FLD_PCSTX_LOCWREN,
439			0);
440
441		al_serdes_grp_reg_masked_write(
442			grp_info,
443			(enum al_serdes_reg_page)i,
444			AL_SRDS_REG_TYPE_PMA,
445			SERDES_IREG_FLD_PCSTXBIST_LOCWREN_REG_NUM,
446			SERDES_IREG_FLD_PCSTXBIST_LOCWREN,
447			0);
448
449		al_serdes_grp_reg_masked_write(
450			grp_info,
451			(enum al_serdes_reg_page)i,
452			AL_SRDS_REG_TYPE_PMA,
453			SERDES_IREG_FLD_TX_DRV_OVERRIDE_EN_REG_NUM,
454			SERDES_IREG_FLD_TX_DRV_OVERRIDE_EN,
455			0);
456
457		al_serdes_grp_reg_masked_write(
458			grp_info,
459			(enum al_serdes_reg_page)i,
460			AL_SRDS_REG_TYPE_PMA,
461			SERDES_IREG_FLD_RXLOCK2REF_OVREN_REG_NUM,
462			SERDES_IREG_FLD_RXLOCK2REF_OVREN,
463			SERDES_IREG_FLD_RXLOCK2REF_OVREN);
464	}
465}
466
467/******************************************************************************/
468/******************************************************************************/
469void al_serdes_bist_overrides_disable(
470	struct al_serdes_obj	*obj,
471	enum al_serdes_group	grp)
472{
473	struct al_serdes_group_info *grp_info = &obj->grp_info[grp];
474	int i;
475
476	al_serdes_grp_reg_masked_write(
477		grp_info,
478		AL_SRDS_REG_PAGE_4_COMMON,
479		AL_SRDS_REG_TYPE_PMA,
480		SERDES_IREG_FLD_CMNPCIEGEN3_LOCWREN_REG_NUM,
481		SERDES_IREG_FLD_CMNPCSBIST_LOCWREN,
482		SERDES_IREG_FLD_CMNPCSBIST_LOCWREN);
483
484	for (i = 0; i < AL_SRDS_NUM_LANES; i++) {
485		al_serdes_grp_reg_masked_write(
486			grp_info,
487			(enum al_serdes_reg_page)i,
488			AL_SRDS_REG_TYPE_PMA,
489			SERDES_IREG_FLD_LANEPCSPSTATE_LOCWREN_REG_NUM,
490			SERDES_IREG_FLD_LB_LOCWREN |
491			SERDES_IREG_FLD_PCSRXBIST_LOCWREN,
492			SERDES_IREG_FLD_LB_LOCWREN |
493			SERDES_IREG_FLD_PCSRXBIST_LOCWREN);
494
495		al_serdes_grp_reg_masked_write(
496			grp_info,
497			(enum al_serdes_reg_page)i,
498			AL_SRDS_REG_TYPE_PMA,
499			SERDES_IREG_FLD_PCSTXBIST_LOCWREN_REG_NUM,
500			SERDES_IREG_FLD_PCSTXBIST_LOCWREN,
501			SERDES_IREG_FLD_PCSTXBIST_LOCWREN);
502	}
503}
504
505/******************************************************************************/
506/******************************************************************************/
507void al_serdes_rx_rate_change(
508	struct al_serdes_obj *obj,
509	enum al_serdes_group grp,
510	enum al_serdes_rate rate)
511{
512	struct al_serdes_group_info *grp_info = &obj->grp_info[grp];
513	int i;
514
515	uint8_t rx_rate_val;
516
517	switch (rate) {
518	case AL_SRDS_RATE_1_8:
519		rx_rate_val = SERDES_IREG_FLD_PCSRX_DIVRATE_VAL_1_8;
520		break;
521	case AL_SRDS_RATE_1_4:
522		rx_rate_val = SERDES_IREG_FLD_PCSRX_DIVRATE_VAL_1_4;
523		break;
524	case AL_SRDS_RATE_1_2:
525		rx_rate_val = SERDES_IREG_FLD_PCSRX_DIVRATE_VAL_1_2;
526		break;
527	case AL_SRDS_RATE_FULL:
528		rx_rate_val = SERDES_IREG_FLD_PCSRX_DIVRATE_VAL_1_1;
529		break;
530	default:
531		al_err("%s: invalid rate (%d)\n",  __func__, rate);
532		rx_rate_val = SERDES_IREG_FLD_PCSRX_DIVRATE_VAL_1_1;
533		break;
534	}
535
536	for (i = 0; i < AL_SRDS_NUM_LANES; i++) {
537		al_serdes_grp_reg_masked_write(
538				   grp_info,
539				   (enum al_serdes_reg_page)i,
540				   AL_SRDS_REG_TYPE_PMA,
541				   SERDES_IREG_FLD_PCSRX_DIVRATE_REG_NUM,
542				   SERDES_IREG_FLD_PCSRX_DIVRATE_MASK,
543				   rx_rate_val);
544	}
545}
546
547/******************************************************************************/
548/******************************************************************************/
549void al_serdes_group_pm_set(
550	struct al_serdes_obj	*obj,
551	enum al_serdes_group	grp,
552	enum al_serdes_pm	pm)
553{
554	struct al_serdes_group_info *grp_info = &obj->grp_info[grp];
555
556	uint8_t pm_val;
557
558	switch (pm) {
559	case AL_SRDS_PM_PD:
560		pm_val = SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_VAL_PD;
561		break;
562	case AL_SRDS_PM_P2:
563		pm_val = SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_VAL_P2;
564		break;
565	case AL_SRDS_PM_P1:
566		pm_val = SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_VAL_P1;
567		break;
568	case AL_SRDS_PM_P0S:
569		pm_val = SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_VAL_P0S;
570		break;
571	case AL_SRDS_PM_P0:
572		pm_val = SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_VAL_P0;
573		break;
574	default:
575		al_err("%s: invalid power mode (%d)\n",  __func__, pm);
576		al_assert(0);
577		pm_val = SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_VAL_P0;
578	}
579
580	if (pm == AL_SRDS_PM_PD)
581		al_serdes_group_rx_rate_change_sw_flow_dis(grp_info);
582
583	al_serdes_grp_reg_masked_write(
584		grp_info,
585		AL_SRDS_REG_PAGE_4_COMMON,
586		AL_SRDS_REG_TYPE_PMA,
587		SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_REG_NUM,
588		SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_MASK,
589		pm_val);
590
591	if (pm != AL_SRDS_PM_PD)
592		al_serdes_group_rx_rate_change_sw_flow_en_cond(grp_info);
593}
594
595/******************************************************************************/
596/******************************************************************************/
597void al_serdes_lane_rx_rate_change_sw_flow_en(
598	struct al_serdes_obj	*obj,
599	enum al_serdes_group	grp,
600	enum al_serdes_lane	lane)
601{
602	al_serdes_lane_write(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, 201, 0xfc);
603	al_serdes_lane_write(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, 202, 0xff);
604	al_serdes_lane_write(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, 203, 0xff);
605	al_serdes_lane_write(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, 204, 0xff);
606	al_serdes_lane_write(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, 205, 0x7f);
607	al_serdes_lane_write(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, 205, 0xff);
608}
609
610/******************************************************************************/
611/******************************************************************************/
612void al_serdes_lane_rx_rate_change_sw_flow_dis(
613	struct al_serdes_obj	*obj,
614	enum al_serdes_group	grp,
615	enum al_serdes_lane	lane)
616{
617	al_serdes_lane_write(obj, grp, lane, AL_SRDS_REG_TYPE_PMA, 205, 0x7f);
618}
619
620/******************************************************************************/
621/******************************************************************************/
622void al_serdes_lane_pcie_rate_override_enable_set(
623	struct al_serdes_obj		*obj,
624	enum al_serdes_group		grp,
625	enum al_serdes_lane		lane,
626	al_bool				en)
627{
628	struct al_serdes_group_info *grp_info = &obj->grp_info[grp];
629
630	al_serdes_grp_reg_masked_write(
631		grp_info,
632		(enum al_serdes_reg_page)lane,
633		AL_SRDS_REG_TYPE_PCS,
634		SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_ENA_REG_NUM,
635		SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_ENA,
636		en ? SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_ENA : 0);
637}
638
639/******************************************************************************/
640/******************************************************************************/
641al_bool al_serdes_lane_pcie_rate_override_is_enabled(
642	struct al_serdes_obj		*obj,
643	enum al_serdes_group		grp,
644	enum al_serdes_lane		lane)
645{
646	struct al_serdes_group_info *grp_info = &obj->grp_info[grp];
647
648	return (al_serdes_grp_lane_read(
649		grp_info,
650		lane,
651		AL_SRDS_REG_TYPE_PCS,
652		SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_ENA_REG_NUM) &
653		SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_ENA) ? AL_TRUE : AL_FALSE;
654}
655
656/******************************************************************************/
657/******************************************************************************/
658enum al_serdes_pcie_rate al_serdes_lane_pcie_rate_get(
659	struct al_serdes_obj	*obj,
660	enum al_serdes_group	grp,
661	enum al_serdes_lane	lane)
662{
663	struct al_serdes_group_info *grp_info = &obj->grp_info[grp];
664
665	return (al_serdes_grp_reg_read(
666		grp_info,
667		(enum al_serdes_reg_page)lane,
668		AL_SRDS_REG_TYPE_PCS,
669		SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_REG_NUM) &
670		SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_MASK) >>
671		SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_SHIFT;
672}
673
674/******************************************************************************/
675/******************************************************************************/
676void al_serdes_lane_pcie_rate_set(
677	struct al_serdes_obj		*obj,
678	enum al_serdes_group		grp,
679	enum al_serdes_lane		lane,
680	enum al_serdes_pcie_rate	rate)
681{
682	struct al_serdes_group_info *grp_info = &obj->grp_info[grp];
683
684	al_serdes_grp_reg_masked_write(
685		grp_info,
686		(enum al_serdes_reg_page)lane,
687		AL_SRDS_REG_TYPE_PCS,
688		SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_REG_NUM,
689		SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_MASK,
690		rate << SERDES_IREG_FLD_PCS_VPCSIF_OVR_RATE_SHIFT);
691}
692
693/******************************************************************************/
694/******************************************************************************/
695void al_serdes_lane_pm_set(
696	struct al_serdes_obj	*obj,
697	enum al_serdes_group	grp,
698	enum al_serdes_lane	lane,
699	enum al_serdes_pm	rx_pm,
700	enum al_serdes_pm	tx_pm)
701{
702	struct al_serdes_group_info *grp_info = &obj->grp_info[grp];
703
704	uint8_t rx_pm_val;
705	uint8_t tx_pm_val;
706
707	switch (rx_pm) {
708	case AL_SRDS_PM_PD:
709		rx_pm_val = SERDES_IREG_FLD_LANEPCSPSTATE_RX_VAL_PD;
710		break;
711	case AL_SRDS_PM_P2:
712		rx_pm_val = SERDES_IREG_FLD_LANEPCSPSTATE_RX_VAL_P2;
713		break;
714	case AL_SRDS_PM_P1:
715		rx_pm_val = SERDES_IREG_FLD_LANEPCSPSTATE_RX_VAL_P1;
716		break;
717	case AL_SRDS_PM_P0S:
718		rx_pm_val = SERDES_IREG_FLD_LANEPCSPSTATE_RX_VAL_P0S;
719		break;
720	case AL_SRDS_PM_P0:
721		rx_pm_val = SERDES_IREG_FLD_LANEPCSPSTATE_RX_VAL_P0;
722		break;
723	default:
724		al_err("%s: invalid rx power mode (%d)\n",  __func__, rx_pm);
725		al_assert(0);
726		rx_pm_val = SERDES_IREG_FLD_LANEPCSPSTATE_RX_VAL_P0;
727	}
728
729	switch (tx_pm) {
730	case AL_SRDS_PM_PD:
731		tx_pm_val = SERDES_IREG_FLD_LANEPCSPSTATE_TX_VAL_PD;
732		break;
733	case AL_SRDS_PM_P2:
734		tx_pm_val = SERDES_IREG_FLD_LANEPCSPSTATE_TX_VAL_P2;
735		break;
736	case AL_SRDS_PM_P1:
737		tx_pm_val = SERDES_IREG_FLD_LANEPCSPSTATE_TX_VAL_P1;
738		break;
739	case AL_SRDS_PM_P0S:
740		tx_pm_val = SERDES_IREG_FLD_LANEPCSPSTATE_TX_VAL_P0S;
741		break;
742	case AL_SRDS_PM_P0:
743		tx_pm_val = SERDES_IREG_FLD_LANEPCSPSTATE_TX_VAL_P0;
744		break;
745	default:
746		al_err("%s: invalid tx power mode (%d)\n",  __func__, tx_pm);
747		al_assert(0);
748		tx_pm_val = SERDES_IREG_FLD_LANEPCSPSTATE_TX_VAL_P0;
749	}
750
751	if (rx_pm == AL_SRDS_PM_PD)
752		_al_serdes_lane_rx_rate_change_sw_flow_dis(grp_info, lane);
753
754	al_serdes_grp_reg_masked_write(
755		grp_info,
756		(enum al_serdes_reg_page)lane,
757		AL_SRDS_REG_TYPE_PMA,
758		SERDES_IREG_FLD_LANEPCSPSTATE_RX_REG_NUM,
759		SERDES_IREG_FLD_LANEPCSPSTATE_RX_MASK,
760		rx_pm_val);
761
762	al_serdes_grp_reg_masked_write(
763		grp_info,
764		(enum al_serdes_reg_page)lane,
765		AL_SRDS_REG_TYPE_PMA,
766		SERDES_IREG_FLD_LANEPCSPSTATE_TX_REG_NUM,
767		SERDES_IREG_FLD_LANEPCSPSTATE_TX_MASK,
768		tx_pm_val);
769
770	if (rx_pm != AL_SRDS_PM_PD)
771		_al_serdes_lane_rx_rate_change_sw_flow_en_cond(grp_info, lane);
772}
773
774/******************************************************************************/
775/******************************************************************************/
776void al_serdes_pma_hard_reset_group(
777	struct al_serdes_obj	*obj,
778	enum al_serdes_group	grp,
779	al_bool			enable)
780{
781	struct al_serdes_group_info *grp_info = &obj->grp_info[grp];
782
783	if (enable)
784		al_serdes_group_rx_rate_change_sw_flow_dis(grp_info);
785
786	/* Enable Hard Reset Override */
787	al_serdes_grp_reg_masked_write(
788		grp_info,
789		AL_SRDS_REG_PAGE_4_COMMON,
790		AL_SRDS_REG_TYPE_PMA,
791		SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_SYNTH_REG_NUM,
792		SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_SYNTH_MASK,
793		SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_SYNTH_VAL_REGS);
794
795	/* Assert/Deassert Hard Reset Override */
796	al_serdes_grp_reg_masked_write(
797		grp_info,
798		AL_SRDS_REG_PAGE_4_COMMON,
799		AL_SRDS_REG_TYPE_PMA,
800		SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_SYNTH_REG_NUM,
801		SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_SYNTH_MASK,
802		enable ?
803		SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_SYNTH_VAL_ASSERT :
804		SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_SYNTH_VAL_DEASSERT);
805
806	if (!enable)
807		al_serdes_group_rx_rate_change_sw_flow_en_cond(grp_info);
808}
809
810/******************************************************************************/
811/******************************************************************************/
812void al_serdes_pma_hard_reset_lane(
813	struct al_serdes_obj	*obj,
814	enum al_serdes_group	grp,
815	enum al_serdes_lane	lane,
816	al_bool			enable)
817{
818	struct al_serdes_group_info *grp_info = &obj->grp_info[grp];
819
820	if (enable)
821		_al_serdes_lane_rx_rate_change_sw_flow_dis(grp_info, lane);
822
823	/* Enable Hard Reset Override */
824	al_serdes_grp_reg_masked_write(
825		grp_info,
826		(enum al_serdes_reg_page)lane,
827		AL_SRDS_REG_TYPE_PMA,
828		SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_REG_NUM,
829		SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_MASK,
830		SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_VAL_REGS);
831
832	/* Assert/Deassert Hard Reset Override */
833	al_serdes_grp_reg_masked_write(
834		grp_info,
835		(enum al_serdes_reg_page)lane,
836		AL_SRDS_REG_TYPE_PMA,
837		SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_REG_NUM,
838		SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_MASK,
839		enable ?
840		SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_VAL_ASSERT :
841		SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_VAL_DEASSERT);
842
843	if (!enable)
844		_al_serdes_lane_rx_rate_change_sw_flow_en_cond(grp_info, lane);
845}
846
847/******************************************************************************/
848/******************************************************************************/
849#if	(SERDES_IREG_FLD_LB_RX2TXUNTIMEDEN_REG_NUM !=\
850	SERDES_IREG_FLD_LB_TX2RXBUFTIMEDEN_REG_NUM) ||\
851	(SERDES_IREG_FLD_LB_TX2RXBUFTIMEDEN_REG_NUM !=\
852	SERDES_IREG_FLD_LB_TX2RXIOTIMEDEN_REG_NUM) ||\
853	(SERDES_IREG_FLD_LB_TX2RXIOTIMEDEN_REG_NUM !=\
854	 SERDES_IREG_FLD_LB_PARRX2TXTIMEDEN_REG_NUM) ||\
855	(SERDES_IREG_FLD_LB_PARRX2TXTIMEDEN_REG_NUM !=\
856	 SERDES_IREG_FLD_LB_CDRCLK2TXEN_REG_NUM)
857#error Wrong assumption
858#endif
859
860void al_serdes_loopback_control(
861	struct al_serdes_obj	*obj,
862	enum al_serdes_group	grp,
863	enum al_serdes_lane	lane,
864	enum al_serdes_lb_mode	mode)
865{
866	struct al_serdes_group_info *grp_info = &obj->grp_info[grp];
867	uint8_t val = 0;
868
869	switch (mode) {
870	case AL_SRDS_LB_MODE_OFF:
871		break;
872	case AL_SRDS_LB_MODE_PMA_IO_UN_TIMED_RX_TO_TX:
873		val = SERDES_IREG_FLD_LB_RX2TXUNTIMEDEN;
874		break;
875	case AL_SRDS_LB_MODE_PMA_INTERNALLY_BUFFERED_SERIAL_TX_TO_RX:
876		val = SERDES_IREG_FLD_LB_TX2RXBUFTIMEDEN;
877		break;
878	case AL_SRDS_LB_MODE_PMA_SERIAL_TX_IO_TO_RX_IO:
879		val = SERDES_IREG_FLD_LB_TX2RXIOTIMEDEN;
880		break;
881	case AL_SRDS_LB_MODE_PMA_PARALLEL_RX_TO_TX:
882		val = SERDES_IREG_FLD_LB_PARRX2TXTIMEDEN |
883			SERDES_IREG_FLD_LB_CDRCLK2TXEN;
884		break;
885	default:
886		al_err("%s: invalid mode (%d)\n",  __func__, mode);
887		al_assert(0);
888	}
889
890	al_serdes_grp_reg_masked_write(
891		grp_info,
892		(enum al_serdes_reg_page)lane,
893		AL_SRDS_REG_TYPE_PMA,
894		SERDES_IREG_FLD_LB_RX2TXUNTIMEDEN_REG_NUM,
895		SERDES_IREG_FLD_LB_RX2TXUNTIMEDEN |
896		SERDES_IREG_FLD_LB_TX2RXBUFTIMEDEN |
897		SERDES_IREG_FLD_LB_TX2RXIOTIMEDEN |
898		SERDES_IREG_FLD_LB_PARRX2TXTIMEDEN |
899		SERDES_IREG_FLD_LB_CDRCLK2TXEN,
900		val);
901}
902
903/******************************************************************************/
904/******************************************************************************/
905void al_serdes_bist_pattern_select(
906	struct al_serdes_obj		*obj,
907	enum al_serdes_group		grp,
908	enum al_serdes_bist_pattern	pattern,
909	uint8_t				*user_data)
910{
911	struct al_serdes_group_info *grp_info = &obj->grp_info[grp];
912	uint8_t val = 0;
913
914	switch (pattern) {
915	case AL_SRDS_BIST_PATTERN_USER:
916		al_assert(user_data);
917		val = SERDES_IREG_FLD_CMNPCSBIST_MODESEL_VAL_USER;
918		break;
919	case AL_SRDS_BIST_PATTERN_PRBS7:
920		val = SERDES_IREG_FLD_CMNPCSBIST_MODESEL_VAL_PRBS7;
921		break;
922	case AL_SRDS_BIST_PATTERN_PRBS23:
923		val = SERDES_IREG_FLD_CMNPCSBIST_MODESEL_VAL_PRBS23;
924		break;
925	case AL_SRDS_BIST_PATTERN_PRBS31:
926		val = SERDES_IREG_FLD_CMNPCSBIST_MODESEL_VAL_PRBS31;
927		break;
928	case AL_SRDS_BIST_PATTERN_CLK1010:
929		val = SERDES_IREG_FLD_CMNPCSBIST_MODESEL_VAL_CLK1010;
930		break;
931	default:
932		al_err("%s: invalid pattern (%d)\n", __func__, pattern);
933		al_assert(0);
934	}
935
936	if (pattern == AL_SRDS_BIST_PATTERN_USER) {
937		int i;
938
939		for (i = 0; i < SERDES_IREG_FLD_TX_BIST_PAT_NUM_BYTES; i++)
940			al_serdes_grp_reg_write(
941				grp_info,
942				AL_SRDS_REG_PAGE_4_COMMON,
943				AL_SRDS_REG_TYPE_PMA,
944				SERDES_IREG_FLD_TX_BIST_PAT_REG_NUM(i),
945				user_data[i]);
946	}
947
948	al_serdes_grp_reg_masked_write(
949		grp_info,
950		AL_SRDS_REG_PAGE_4_COMMON,
951		AL_SRDS_REG_TYPE_PMA,
952		SERDES_IREG_FLD_CMNPCSBIST_MODESEL_REG_NUM,
953		SERDES_IREG_FLD_CMNPCSBIST_MODESEL_MASK,
954		val);
955}
956
957/******************************************************************************/
958/******************************************************************************/
959void al_serdes_bist_tx_enable(
960	struct al_serdes_obj	*obj,
961	enum al_serdes_group	grp,
962	enum al_serdes_lane	lane,
963	al_bool			enable)
964{
965	struct al_serdes_group_info *grp_info = &obj->grp_info[grp];
966
967	al_serdes_grp_reg_masked_write(
968		grp_info,
969		(enum al_serdes_reg_page)lane,
970		AL_SRDS_REG_TYPE_PMA,
971		SERDES_IREG_FLD_PCSTXBIST_EN_REG_NUM,
972		SERDES_IREG_FLD_PCSTXBIST_EN,
973		enable ? SERDES_IREG_FLD_PCSTXBIST_EN : 0);
974}
975
976/******************************************************************************/
977/******************************************************************************/
978void al_serdes_bist_tx_err_inject(
979	struct al_serdes_obj	*obj,
980	enum al_serdes_group	grp)
981{
982	struct al_serdes_group_info *grp_info = &obj->grp_info[grp];
983
984	al_serdes_grp_reg_masked_write(
985		grp_info,
986		AL_SRDS_REG_PAGE_4_COMMON,
987		AL_SRDS_REG_TYPE_PMA,
988		SERDES_IREG_FLD_TXBIST_BITERROR_EN_REG_NUM,
989		SERDES_IREG_FLD_TXBIST_BITERROR_EN,
990		SERDES_IREG_FLD_TXBIST_BITERROR_EN);
991
992	al_serdes_grp_reg_masked_write(
993		grp_info,
994		AL_SRDS_REG_PAGE_4_COMMON,
995		AL_SRDS_REG_TYPE_PMA,
996		SERDES_IREG_FLD_TXBIST_BITERROR_EN_REG_NUM,
997		SERDES_IREG_FLD_TXBIST_BITERROR_EN,
998		0);
999}
1000
1001/******************************************************************************/
1002/******************************************************************************/
1003void al_serdes_bist_rx_enable(
1004	struct al_serdes_obj	*obj,
1005	enum al_serdes_group	grp,
1006	enum al_serdes_lane	lane,
1007	al_bool			enable)
1008{
1009	struct al_serdes_group_info *grp_info = &obj->grp_info[grp];
1010
1011	al_serdes_grp_reg_masked_write(
1012		grp_info,
1013		(enum al_serdes_reg_page)lane,
1014		AL_SRDS_REG_TYPE_PMA,
1015		SERDES_IREG_FLD_PCSRXBIST_EN_REG_NUM,
1016		SERDES_IREG_FLD_PCSRXBIST_EN,
1017		enable ? SERDES_IREG_FLD_PCSRXBIST_EN : 0);
1018}
1019
1020/******************************************************************************/
1021/******************************************************************************/
1022#if	(SERDES_IREG_FLD_RXBIST_ERRCOUNT_OVERFLOW_REG_NUM !=\
1023	SERDES_IREG_FLD_RXBIST_RXLOCKED_REG_NUM)
1024#error Wrong assumption
1025#endif
1026
1027void al_serdes_bist_rx_status(
1028	struct al_serdes_obj	*obj,
1029	enum al_serdes_group	grp,
1030	enum al_serdes_lane	lane,
1031	al_bool			*is_locked,
1032	al_bool			*err_cnt_overflow,
1033	uint16_t		*err_cnt)
1034{
1035	struct al_serdes_group_info *grp_info = &obj->grp_info[grp];
1036	uint8_t status_reg_val;
1037	uint16_t err_cnt_msb_reg_val;
1038	uint16_t err_cnt_lsb_reg_val;
1039
1040	status_reg_val = al_serdes_grp_reg_read(
1041		grp_info,
1042		(enum al_serdes_reg_page)lane,
1043		AL_SRDS_REG_TYPE_PMA,
1044		SERDES_IREG_FLD_RXBIST_RXLOCKED_REG_NUM);
1045
1046	err_cnt_msb_reg_val = al_serdes_grp_reg_read(
1047		grp_info,
1048		(enum al_serdes_reg_page)lane,
1049		AL_SRDS_REG_TYPE_PMA,
1050		SERDES_IREG_FLD_RXBIST_ERRCOUNT_MSB_REG_NUM);
1051
1052	err_cnt_lsb_reg_val = al_serdes_grp_reg_read(
1053		grp_info,
1054		(enum al_serdes_reg_page)lane,
1055		AL_SRDS_REG_TYPE_PMA,
1056		SERDES_IREG_FLD_RXBIST_ERRCOUNT_LSB_REG_NUM);
1057
1058	*is_locked =
1059		(status_reg_val & SERDES_IREG_FLD_RXBIST_RXLOCKED) ?
1060		AL_TRUE : AL_FALSE;
1061
1062	*err_cnt_overflow =
1063		(status_reg_val & SERDES_IREG_FLD_RXBIST_ERRCOUNT_OVERFLOW) ?
1064		AL_TRUE : AL_FALSE;
1065
1066	*err_cnt = (err_cnt_msb_reg_val << 8) + err_cnt_lsb_reg_val;
1067}
1068
1069/******************************************************************************/
1070/******************************************************************************/
1071static inline uint8_t al_serdes_grp_reg_read(
1072	struct al_serdes_group_info	*grp_info,
1073	enum al_serdes_reg_page		page,
1074	enum al_serdes_reg_type		type,
1075	uint16_t			offset)
1076{
1077	al_reg_write32(
1078		&grp_info->regs_base->gen.reg_addr,
1079		SRDS_CORE_REG_ADDR(page, type, offset));
1080
1081	return al_reg_read32(&grp_info->regs_base->gen.reg_data);
1082}
1083
1084static inline uint8_t al_serdes_grp_lane_read(
1085	struct al_serdes_group_info	*grp_info,
1086	enum al_serdes_lane		page,
1087	enum al_serdes_reg_type		type,
1088	uint16_t			offset)
1089{
1090	return al_serdes_grp_reg_read(grp_info, (enum al_serdes_reg_page)page,
1091				      type, offset);
1092}
1093
1094/******************************************************************************/
1095/******************************************************************************/
1096static inline void al_serdes_grp_reg_write(
1097	struct al_serdes_group_info	*grp_info,
1098	enum al_serdes_reg_page		page,
1099	enum al_serdes_reg_type		type,
1100	uint16_t			offset,
1101	uint8_t				data)
1102{
1103	al_reg_write32(
1104		&grp_info->regs_base->gen.reg_addr,
1105		SRDS_CORE_REG_ADDR(page, type, offset));
1106
1107	al_reg_write32(&grp_info->regs_base->gen.reg_data, data);
1108}
1109
1110
1111static inline void al_serdes_grp_lane_write(
1112	struct al_serdes_group_info	*grp_info,
1113	enum al_serdes_lane		lane,
1114	enum al_serdes_reg_type		type,
1115	uint16_t			offset,
1116	uint8_t				data)
1117{
1118	al_serdes_grp_reg_write(grp_info, (enum al_serdes_reg_page)lane,
1119				type, offset, data);
1120}
1121
1122/******************************************************************************/
1123/******************************************************************************/
1124static inline void al_serdes_ns_delay(int cnt)
1125{
1126	al_udelay((cnt + 999) / 1000);
1127}
1128
1129/******************************************************************************/
1130/******************************************************************************/
1131static inline void al_serdes_grp_reg_masked_write(
1132	struct al_serdes_group_info	*grp_info,
1133	enum al_serdes_reg_page		page,
1134	enum al_serdes_reg_type		type,
1135	uint16_t			offset,
1136	uint8_t				mask,
1137	uint8_t				data)
1138{
1139	uint8_t val;
1140	enum al_serdes_reg_page	start_page = page;
1141	enum al_serdes_reg_page	end_page   = page;
1142	enum al_serdes_reg_page	iter_page;
1143
1144	if (page == AL_SRDS_REG_PAGE_0123_LANES_0123) {
1145		start_page = AL_SRDS_REG_PAGE_0_LANE_0;
1146		end_page   = AL_SRDS_REG_PAGE_3_LANE_3;
1147	}
1148
1149	for(iter_page = start_page; iter_page <= end_page; ++iter_page) {
1150		val = al_serdes_grp_reg_read(grp_info, iter_page, type, offset);
1151		val &= ~mask;
1152		val |= data;
1153		al_serdes_grp_reg_write(grp_info, iter_page, type, offset, val);
1154	}
1155}
1156
1157static inline void al_serdes_grp_lane_masked_write(
1158	struct al_serdes_group_info	*grp_info,
1159	enum al_serdes_lane		lane,
1160	enum al_serdes_reg_type		type,
1161	uint16_t			offset,
1162	uint8_t				mask,
1163	uint8_t				data)
1164{
1165	al_serdes_grp_reg_masked_write(grp_info, (enum al_serdes_reg_page)lane,
1166				       type, offset, mask, data);
1167}
1168
1169/******************************************************************************/
1170/******************************************************************************/
1171static void _al_serdes_lane_rx_rate_change_sw_flow_dis(
1172	struct al_serdes_group_info	*grp_info,
1173	enum al_serdes_lane		lane)
1174{
1175	al_bool lane_sw_flow_enabled;
1176
1177	al_assert(lane != AL_SRDS_LANES_0123);
1178
1179	lane_sw_flow_enabled =
1180		(al_serdes_grp_reg_read(grp_info, (enum al_serdes_reg_page)lane,
1181			AL_SRDS_REG_TYPE_PMA, 201) == 0xfc) &&
1182		(al_serdes_grp_reg_read(grp_info, (enum al_serdes_reg_page)lane,
1183			AL_SRDS_REG_TYPE_PMA, 202) == 0xff) &&
1184		(al_serdes_grp_reg_read(grp_info, (enum al_serdes_reg_page)lane,
1185			AL_SRDS_REG_TYPE_PMA, 203) == 0xff) &&
1186		(al_serdes_grp_reg_read(grp_info, (enum al_serdes_reg_page)lane,
1187			AL_SRDS_REG_TYPE_PMA, 204) == 0xff) &&
1188		(al_serdes_grp_reg_read(grp_info, (enum al_serdes_reg_page)lane,
1189			AL_SRDS_REG_TYPE_PMA, 205) == 0xff);
1190
1191	/**
1192	 * Disable the Rx rate change software flow by clearing bit 7 of lane PMA register 205
1193	 * (RSTPDOVR_RX_OVREN)
1194	 */
1195	if (lane_sw_flow_enabled) {
1196		al_dbg("%s(%d): actually disabling\n", __func__, lane);
1197		al_serdes_grp_reg_masked_write(grp_info, (enum al_serdes_reg_page)lane,
1198			AL_SRDS_REG_TYPE_PMA, 205, 0x80, 0x00);
1199	}
1200}
1201
1202/******************************************************************************/
1203/******************************************************************************/
1204static void al_serdes_group_rx_rate_change_sw_flow_dis(
1205	struct al_serdes_group_info	*grp_info)
1206{
1207	int lane;
1208
1209	for (lane = AL_SRDS_LANE_0; lane < AL_SRDS_NUM_LANES; lane++)
1210		_al_serdes_lane_rx_rate_change_sw_flow_dis(grp_info, lane);
1211}
1212
1213/******************************************************************************/
1214/******************************************************************************/
1215static void _al_serdes_lane_rx_rate_change_sw_flow_en_cond(
1216	struct al_serdes_group_info	*grp_info,
1217	enum al_serdes_lane		lane)
1218{
1219	al_bool lane_sw_flow_almost_enabled;
1220	al_bool group_reset_enabled;
1221	al_bool lane_reset_enabled;
1222	al_bool group_pd_enabled;
1223	al_bool lane_pd_enabled;
1224
1225	al_assert(lane != AL_SRDS_LANES_0123);
1226
1227	lane_sw_flow_almost_enabled =
1228		(al_serdes_grp_reg_read(grp_info, (enum al_serdes_reg_page)lane,
1229			AL_SRDS_REG_TYPE_PMA, 201) == 0xfc) &&
1230		(al_serdes_grp_reg_read(grp_info, (enum al_serdes_reg_page)lane,
1231			AL_SRDS_REG_TYPE_PMA, 202) == 0xff) &&
1232		(al_serdes_grp_reg_read(grp_info, (enum al_serdes_reg_page)lane,
1233			AL_SRDS_REG_TYPE_PMA, 203) == 0xff) &&
1234		(al_serdes_grp_reg_read(grp_info, (enum al_serdes_reg_page)lane,
1235			AL_SRDS_REG_TYPE_PMA, 204) == 0xff) &&
1236		(al_serdes_grp_reg_read(grp_info, (enum al_serdes_reg_page)lane,
1237			AL_SRDS_REG_TYPE_PMA, 205) == 0x7f);
1238
1239	group_reset_enabled =
1240		((al_serdes_grp_reg_read(
1241			grp_info, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA,
1242			SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_SYNTH_REG_NUM) &
1243		SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_SYNTH_MASK) ==
1244		SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_SYNTH_VAL_REGS) &&
1245		((al_serdes_grp_reg_read(
1246			grp_info, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA,
1247			SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_SYNTH_REG_NUM) &
1248			SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_SYNTH_MASK) ==
1249		SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_SYNTH_VAL_ASSERT);
1250
1251	lane_reset_enabled =
1252		((al_serdes_grp_reg_read(
1253			grp_info, (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA,
1254			SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_REG_NUM) &
1255		SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_MASK) ==
1256		SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASSEN_VAL_REGS) &&
1257		((al_serdes_grp_reg_read(
1258			grp_info, (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA,
1259			SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_REG_NUM) &
1260			SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_MASK) ==
1261		SERDES_IREG_FLD_CMNCTLPOR_HARDRSTBYPASS_VAL_ASSERT);
1262
1263	group_pd_enabled =
1264		(al_serdes_grp_reg_read(
1265			grp_info, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA,
1266			SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_REG_NUM) &
1267		SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_MASK) ==
1268		SERDES_IREG_FLD_CMNPCSPSTATE_SYNTH_VAL_PD;
1269
1270	lane_pd_enabled =
1271		(al_serdes_grp_reg_read(
1272			grp_info, (enum al_serdes_reg_page)lane, AL_SRDS_REG_TYPE_PMA,
1273			SERDES_IREG_FLD_LANEPCSPSTATE_RX_REG_NUM) &
1274		SERDES_IREG_FLD_LANEPCSPSTATE_RX_MASK) ==
1275		SERDES_IREG_FLD_LANEPCSPSTATE_RX_VAL_PD;
1276
1277	/**
1278	 * Enable the Rx rate change software flow by setting bit 7 of lane PMA register 205
1279	 * (RSTPDOVR_RX_OVREN)
1280	 */
1281	if (lane_sw_flow_almost_enabled && !group_reset_enabled && !lane_reset_enabled &&
1282		!group_pd_enabled && !lane_pd_enabled) {
1283		al_dbg("%s(%d): actually enabling\n", __func__, lane);
1284
1285		al_serdes_ns_delay(500);
1286		al_serdes_grp_reg_masked_write(grp_info, (enum al_serdes_reg_page)lane,
1287			AL_SRDS_REG_TYPE_PMA, 205, 0x80, 0x80);
1288	}
1289}
1290
1291/******************************************************************************/
1292/******************************************************************************/
1293static void al_serdes_group_rx_rate_change_sw_flow_en_cond(
1294	struct al_serdes_group_info	*grp_info)
1295{
1296	int lane;
1297
1298	for (lane = AL_SRDS_LANE_0; lane < AL_SRDS_NUM_LANES; lane++)
1299		_al_serdes_lane_rx_rate_change_sw_flow_en_cond(grp_info, lane);
1300}
1301
1302/******************************************************************************/
1303/******************************************************************************/
1304int al_serdes_eye_measure_run(
1305		struct al_serdes_obj	*obj,
1306		enum al_serdes_group	grp,
1307		enum al_serdes_lane	lane,
1308		uint32_t		timeout,
1309		unsigned int		*value)
1310{
1311	uint32_t reg = 0;
1312	uint32_t i;
1313	struct serdes_lane *lane_regs;
1314
1315	lane_regs = &obj->grp_info[grp].regs_base->lane[lane];
1316
1317	al_reg_write32(&lane_regs->ictl_multi_rxeq,
1318		       SERDES_LANE_ICTL_MULTI_RXEQ_START_L_A);
1319
1320	for (i = 0 ; i < timeout ; i++) {
1321		reg = al_reg_read32(&lane_regs->octl_multi);
1322
1323		if (reg & SERDES_LANE_OCTL_MULTI_RXEQ_DONE_L_A)
1324			break;
1325
1326		al_msleep(10);
1327	}
1328
1329	if (i == timeout) {
1330		al_err("%s: measure eye failed on timeout\n", __func__);
1331		return -ETIMEDOUT;
1332	}
1333
1334	*value = al_reg_read32(&lane_regs->odat_multi_rxeq);
1335
1336	al_reg_write32(&lane_regs->ictl_multi_rxeq, 0);
1337
1338	return 0;
1339}
1340
1341/******************************************************************************/
1342/******************************************************************************/
1343int al_serdes_eye_diag_sample(
1344		struct al_serdes_obj	*obj,
1345		enum al_serdes_group	grp,
1346		enum al_serdes_lane	lane,
1347		unsigned int		x,
1348		int			y,
1349		unsigned int		timeout,
1350		unsigned int		*value)
1351{
1352	enum al_serdes_reg_page	page = (enum al_serdes_reg_page)lane;
1353	struct al_serdes_group_info *grp_info;
1354	uint32_t i;
1355	uint8_t sample_count_orig_msb;
1356	uint8_t sample_count_orig_lsb;
1357
1358	al_assert(obj);
1359	al_assert(((int)grp) >= AL_SRDS_GRP_A);
1360	al_assert(((int)grp) <= AL_SRDS_GRP_D);
1361	al_assert(((int)page) >= AL_SRDS_REG_PAGE_0_LANE_0);
1362	al_assert(((int)page) <= AL_SRDS_REG_PAGE_0123_LANES_0123);
1363
1364	grp_info = &obj->grp_info[grp];
1365
1366	/* Obtain sample count by reading RXCALROAMEYEMEAS_COUNT */
1367	sample_count_orig_msb = al_serdes_grp_reg_read(grp_info,
1368		AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA,
1369		SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_MSB_REG_NUM);
1370	sample_count_orig_lsb = al_serdes_grp_reg_read(grp_info,
1371		AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA,
1372		SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_LSB_REG_NUM);
1373
1374	/* Set sample count to ~100000 samples */
1375	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
1376		AL_SRDS_REG_TYPE_PMA,
1377		SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_MSB_REG_NUM, 0x13);
1378	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
1379		AL_SRDS_REG_TYPE_PMA,
1380		SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_LSB_REG_NUM, 0x88);
1381
1382	/* BER Contour Overwrite */
1383	al_serdes_grp_reg_masked_write(grp_info, page, AL_SRDS_REG_TYPE_PMA,
1384		SERDES_IREG_FLD_RXCALROAMEYEMEASIN_LOCWREN_REG_NUM,
1385		SERDES_IREG_FLD_RXCALROAMEYEMEASIN_LOCWREN,
1386		0);
1387	al_serdes_grp_reg_masked_write(grp_info, page, AL_SRDS_REG_TYPE_PMA,
1388		SERDES_IREG_FLD_RXCALROAMXADJUST_LOCWREN_REG_NUM,
1389		SERDES_IREG_FLD_RXCALROAMXADJUST_LOCWREN,
1390		0);
1391	al_serdes_grp_reg_masked_write(grp_info, page, AL_SRDS_REG_TYPE_PMA,
1392		SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN_REG_NUM,
1393		SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN,
1394		0);
1395
1396	/* RXROAM_XORBITSEL = 0x1 or 0x0 */
1397	al_serdes_grp_reg_masked_write(grp_info, page, AL_SRDS_REG_TYPE_PMA,
1398		SERDES_IREG_FLD_RXROAM_XORBITSEL_REG_NUM,
1399		SERDES_IREG_FLD_RXROAM_XORBITSEL,
1400		SERDES_IREG_FLD_RXROAM_XORBITSEL_2ND);
1401
1402	/* Set X */
1403	al_serdes_grp_reg_write(grp_info, page, AL_SRDS_REG_TYPE_PMA,
1404		SERDES_IREG_FLD_RXCALROAMXADJUST_REG_NUM, x);
1405
1406	/* Set Y */
1407	al_serdes_grp_reg_write(grp_info, page, AL_SRDS_REG_TYPE_PMA,
1408		SERDES_IREG_FLD_RXCALROAMYADJUST_REG_NUM,
1409		y < 32 ? 31 - y : y + 1);
1410
1411	/* Start Measurement by setting RXCALROAMEYEMEASIN_CYCLEEN = 0x1 */
1412	al_serdes_grp_reg_masked_write(grp_info, page, AL_SRDS_REG_TYPE_PMA,
1413		SERDES_IREG_FLD_RXCALROAMEYEMEASIN_CYCLEEN_REG_NUM,
1414		SERDES_IREG_FLD_RXCALROAMEYEMEASIN_CYCLEEN_START,
1415		SERDES_IREG_FLD_RXCALROAMEYEMEASIN_CYCLEEN_START);
1416
1417	/* Check RXCALROAMEYEMEASDONE Signal (Polling Until 0x1) */
1418	for (i = 0 ; i < timeout ; i++) {
1419		if (al_serdes_grp_reg_read(grp_info, page, AL_SRDS_REG_TYPE_PMA,
1420			SERDES_IREG_FLD_RXCALROAMEYEMEASDONE_REG_NUM) &
1421			SERDES_IREG_FLD_RXCALROAMEYEMEASDONE)
1422			break;
1423		al_udelay(1);
1424	}
1425	if (i == timeout) {
1426		al_err("%s: eye diagram sampling timed out!\n", __func__);
1427		return -ETIMEDOUT;
1428	}
1429
1430	/* Stop Measurement by setting RXCALROAMEYEMEASIN_CYCLEEN = 0x0 */
1431	al_serdes_grp_reg_masked_write(grp_info, page, AL_SRDS_REG_TYPE_PMA,
1432		SERDES_IREG_FLD_RXCALROAMEYEMEASIN_CYCLEEN_REG_NUM,
1433		SERDES_IREG_FLD_RXCALROAMEYEMEASIN_CYCLEEN_START,
1434		0);
1435
1436	/* Obtain Error Counts by reading RXCALROAMEYEMEAS_ACC */
1437	*value = ((unsigned int)al_serdes_grp_reg_read(grp_info, page,
1438		AL_SRDS_REG_TYPE_PMA,
1439		SERDES_IREG_FLD_RXCALROAMEYEMEAS_ACC_MSB_REG_NUM)) << 8 |
1440		al_serdes_grp_reg_read(grp_info, page, AL_SRDS_REG_TYPE_PMA,
1441		SERDES_IREG_FLD_RXCALROAMEYEMEAS_ACC_LSB_REG_NUM);
1442
1443	/* BER Contour Overwrite */
1444	al_serdes_grp_reg_masked_write(grp_info, page, AL_SRDS_REG_TYPE_PMA,
1445		SERDES_IREG_FLD_RXCALROAMEYEMEASIN_LOCWREN_REG_NUM,
1446		SERDES_IREG_FLD_RXCALROAMEYEMEASIN_LOCWREN,
1447		SERDES_IREG_FLD_RXCALROAMEYEMEASIN_LOCWREN);
1448	al_serdes_grp_reg_masked_write(grp_info, page, AL_SRDS_REG_TYPE_PMA,
1449		SERDES_IREG_FLD_RXCALROAMXADJUST_LOCWREN_REG_NUM,
1450		SERDES_IREG_FLD_RXCALROAMXADJUST_LOCWREN,
1451		SERDES_IREG_FLD_RXCALROAMXADJUST_LOCWREN);
1452	al_serdes_grp_reg_masked_write(grp_info, page, AL_SRDS_REG_TYPE_PMA,
1453		SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN_REG_NUM,
1454		SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN,
1455		SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN);
1456
1457	/* Restore sample count */
1458	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
1459		AL_SRDS_REG_TYPE_PMA,
1460		SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_MSB_REG_NUM,
1461		sample_count_orig_msb);
1462	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
1463		AL_SRDS_REG_TYPE_PMA,
1464		SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_LSB_REG_NUM,
1465		sample_count_orig_lsb);
1466
1467	return 0;
1468}
1469
1470/******************************************************************************/
1471/******************************************************************************/
1472static void al_serdes_tx_deemph_set(
1473		struct al_serdes_obj	*obj,
1474		enum al_serdes_group	grp,
1475		enum al_serdes_lane	lane,
1476		uint32_t		c_zero,
1477		uint32_t		c_plus_1,
1478		uint32_t		c_minus_1)
1479{
1480	al_serdes_grp_lane_masked_write(
1481			&obj->grp_info[grp],
1482			lane,
1483			AL_SRDS_REG_TYPE_PMA,
1484			SERDES_IREG_TX_DRV_1_REG_NUM,
1485			SERDES_IREG_TX_DRV_1_LEVN_MASK,
1486			((c_zero + c_plus_1 + c_minus_1)
1487				<< SERDES_IREG_TX_DRV_1_LEVN_SHIFT));
1488
1489	al_serdes_grp_lane_masked_write(
1490			&obj->grp_info[grp],
1491			lane,
1492			AL_SRDS_REG_TYPE_PMA,
1493			SERDES_IREG_TX_DRV_2_REG_NUM,
1494			SERDES_IREG_TX_DRV_2_LEVNM1_MASK,
1495			(c_plus_1 << SERDES_IREG_TX_DRV_2_LEVNM1_SHIFT));
1496
1497	al_serdes_grp_lane_masked_write(
1498			&obj->grp_info[grp],
1499			lane,
1500			AL_SRDS_REG_TYPE_PMA,
1501			SERDES_IREG_TX_DRV_3_REG_NUM,
1502			SERDES_IREG_TX_DRV_3_LEVNP1_MASK,
1503			(c_minus_1 << SERDES_IREG_TX_DRV_3_LEVNP1_SHIFT));
1504}
1505
1506static void al_serdes_tx_deemph_get(
1507		struct al_serdes_obj	*obj,
1508		enum al_serdes_group	grp,
1509		enum al_serdes_lane	lane,
1510		uint32_t		*c_zero,
1511		uint32_t		*c_plus_1,
1512		uint32_t		*c_minus_1)
1513{
1514	uint32_t reg = 0;
1515
1516	reg = al_serdes_grp_lane_read(
1517			&obj->grp_info[grp],
1518			lane,
1519			AL_SRDS_REG_TYPE_PMA,
1520			SERDES_IREG_TX_DRV_2_REG_NUM);
1521
1522	*c_plus_1 = ((reg & SERDES_IREG_TX_DRV_2_LEVNM1_MASK) >>
1523					SERDES_IREG_TX_DRV_2_LEVNM1_SHIFT);
1524
1525	reg = al_serdes_grp_lane_read(
1526			&obj->grp_info[grp],
1527			lane,
1528			AL_SRDS_REG_TYPE_PMA,
1529			SERDES_IREG_TX_DRV_3_REG_NUM);
1530
1531	*c_minus_1 = ((reg & SERDES_IREG_TX_DRV_3_LEVNP1_MASK) >>
1532					SERDES_IREG_TX_DRV_3_LEVNP1_SHIFT);
1533
1534	reg = al_serdes_grp_lane_read(
1535			&obj->grp_info[grp],
1536			lane,
1537			AL_SRDS_REG_TYPE_PMA,
1538			SERDES_IREG_TX_DRV_1_REG_NUM);
1539
1540	*c_zero = (((reg & SERDES_IREG_TX_DRV_1_LEVN_MASK) >>
1541		SERDES_IREG_TX_DRV_1_LEVN_SHIFT) - *c_plus_1 - *c_minus_1);
1542}
1543
1544al_bool al_serdes_tx_deemph_inc(
1545		struct al_serdes_obj	*obj,
1546		enum al_serdes_group	grp,
1547		enum al_serdes_lane	lane,
1548		enum al_serdes_tx_deemph_param param)
1549{
1550	al_bool ret = AL_TRUE;
1551	uint32_t c0;
1552	uint32_t c1;
1553	uint32_t c_1;
1554
1555	al_serdes_tx_deemph_get(obj, grp, lane, &c0, &c1, &c_1);
1556
1557	al_dbg("%s: current txdeemph: c0 = 0x%x c1 = 0x%x c-1 = 0x%x\n",
1558		__func__, c0, c1, c_1);
1559
1560	switch (param) {
1561	case AL_SERDES_TX_DEEMP_C_ZERO:
1562
1563		if (c0 == AL_SERDES_TX_DEEMPH_C_ZERO_MAX_VAL)
1564			return AL_FALSE;
1565
1566		c0++;
1567
1568		break;
1569	case AL_SERDES_TX_DEEMP_C_PLUS:
1570
1571		if (c1 == AL_SERDES_TX_DEEMPH_C_PLUS_MAX_VAL)
1572			return AL_FALSE;
1573
1574		c1++;
1575
1576		break;
1577	case AL_SERDES_TX_DEEMP_C_MINUS:
1578
1579		if (c_1 == AL_SERDES_TX_DEEMPH_C_MINUS_MAX_VAL)
1580			return AL_FALSE;
1581
1582		c_1++;
1583
1584		break;
1585	}
1586
1587	if ((c0 + c1 + c_1) > AL_SERDES_TX_DEEMPH_SUM_MAX) {
1588		al_dbg("%s: sum of all tx de-emphasis over the max limit\n",
1589			__func__);
1590
1591		return AL_FALSE;
1592	}
1593
1594	al_dbg("%s: new txdeemph: c0 = 0x%x c1 = 0x%x c-1 = 0x%x\n",
1595		__func__, c0, c1, c_1);
1596
1597	al_serdes_tx_deemph_set(obj, grp, lane, c0, c1, c_1);
1598
1599	return ret;
1600}
1601
1602al_bool al_serdes_tx_deemph_dec(
1603		struct al_serdes_obj	*obj,
1604		enum al_serdes_group	grp,
1605		enum al_serdes_lane	lane,
1606		enum al_serdes_tx_deemph_param param)
1607{
1608	al_bool ret = AL_TRUE;
1609	uint32_t c0;
1610	uint32_t c1;
1611	uint32_t c_1;
1612
1613	al_serdes_tx_deemph_get(obj, grp, lane, &c0, &c1, &c_1);
1614
1615	al_dbg("%s: current txdeemph: c0 = 0x%x c1 = 0x%x c-1 = 0x%x\n",
1616		__func__, c0, c1, c_1);
1617
1618	switch (param) {
1619	case AL_SERDES_TX_DEEMP_C_ZERO:
1620
1621		if (c0 == AL_SERDES_TX_DEEMPH_C_ZERO_MIN_VAL)
1622			return AL_FALSE;
1623
1624		c0--;
1625
1626		break;
1627	case AL_SERDES_TX_DEEMP_C_PLUS:
1628
1629		if (c1 == AL_SERDES_TX_DEEMPH_C_PLUS_MIN_VAL)
1630			return AL_FALSE;
1631
1632		c1--;
1633
1634		break;
1635	case AL_SERDES_TX_DEEMP_C_MINUS:
1636
1637		if (c_1 == AL_SERDES_TX_DEEMPH_C_MINUS_MIN_VAL)
1638			return AL_FALSE;
1639
1640		c_1--;
1641
1642		break;
1643	}
1644
1645	al_dbg("%s: new txdeemph: c0 = 0x%x c1 = 0x%x c-1 = 0x%x\n",
1646		__func__, c0, c1, c_1);
1647
1648	al_serdes_tx_deemph_set(obj, grp, lane, c0, c1, c_1);
1649
1650	return ret;
1651}
1652
1653void al_serdes_tx_deemph_preset(
1654		struct al_serdes_obj	*obj,
1655		enum al_serdes_group	grp,
1656		enum al_serdes_lane	lane)
1657{
1658	uint32_t c0;
1659	uint32_t c1;
1660	uint32_t c_1;
1661
1662	c0 = AL_SERDES_TX_DEEMPH_C_ZERO_PRESET;
1663
1664	c1 = AL_SERDES_TX_DEEMPH_C_PLUS_PRESET;
1665
1666	c_1 = AL_SERDES_TX_DEEMPH_C_MINUS_PRESET;
1667
1668	al_dbg("preset: new txdeemph: c0 = 0x%x c1 = 0x%x c-1 = 0x%x\n",
1669		c0, c1, c_1);
1670
1671	al_serdes_tx_deemph_set(obj, grp, lane, c0, c1, c_1);
1672}
1673
1674al_bool al_serdes_signal_is_detected(
1675		struct al_serdes_obj	*obj,
1676		enum al_serdes_group	grp,
1677		enum al_serdes_lane	lane)
1678{
1679	uint32_t reg = 0;
1680
1681	reg = al_serdes_grp_lane_read(
1682			&obj->grp_info[grp],
1683			lane,
1684			AL_SRDS_REG_TYPE_PMA,
1685			SERDES_IREG_FLD_RXRANDET_REG_NUM);
1686
1687	return ((reg & SERDES_IREG_FLD_RXRANDET_STAT) ? AL_TRUE : AL_FALSE);
1688}
1689
1690void al_serdes_tx_advanced_params_set(struct al_serdes_obj		*obj,
1691				      enum al_serdes_group		grp,
1692				      enum al_serdes_lane		lane,
1693				      struct al_serdes_adv_tx_params	*params)
1694{
1695	uint8_t reg = 0;
1696
1697	if(!params->override) {
1698		al_serdes_grp_lane_masked_write(&obj->grp_info[grp],
1699			lane,
1700			AL_SRDS_REG_TYPE_PMA,
1701			SERDES_IREG_FLD_TX_DRV_OVERRIDE_EN_REG_NUM,
1702			SERDES_IREG_FLD_TX_DRV_OVERRIDE_EN,
1703			SERDES_IREG_FLD_TX_DRV_OVERRIDE_EN);
1704
1705		return;
1706	}
1707
1708	al_serdes_grp_lane_masked_write(&obj->grp_info[grp],
1709			lane,
1710			AL_SRDS_REG_TYPE_PMA,
1711			SERDES_IREG_FLD_TX_DRV_OVERRIDE_EN_REG_NUM,
1712			SERDES_IREG_FLD_TX_DRV_OVERRIDE_EN,
1713			0);
1714
1715	AL_REG_FIELD_SET(reg,
1716			 SERDES_IREG_TX_DRV_1_HLEV_MASK,
1717			 SERDES_IREG_TX_DRV_1_HLEV_SHIFT,
1718			 params->amp);
1719
1720	AL_REG_FIELD_SET(reg,
1721			 SERDES_IREG_TX_DRV_1_LEVN_MASK,
1722			 SERDES_IREG_TX_DRV_1_LEVN_SHIFT,
1723			 params->total_driver_units);
1724
1725	al_serdes_grp_lane_write(&obj->grp_info[grp],
1726				lane,
1727				AL_SRDS_REG_TYPE_PMA,
1728				SERDES_IREG_TX_DRV_1_REG_NUM,
1729				reg);
1730
1731	reg = 0;
1732	AL_REG_FIELD_SET(reg,
1733			 SERDES_IREG_TX_DRV_2_LEVNM1_MASK,
1734			 SERDES_IREG_TX_DRV_2_LEVNM1_SHIFT,
1735			 params->c_plus_1);
1736
1737	AL_REG_FIELD_SET(reg,
1738			 SERDES_IREG_TX_DRV_2_LEVNM2_MASK,
1739			 SERDES_IREG_TX_DRV_2_LEVNM2_SHIFT,
1740			 params->c_plus_2);
1741
1742	al_serdes_grp_lane_write(&obj->grp_info[grp],
1743				lane,
1744				AL_SRDS_REG_TYPE_PMA,
1745				SERDES_IREG_TX_DRV_2_REG_NUM,
1746				reg);
1747
1748	reg = 0;
1749	AL_REG_FIELD_SET(reg,
1750			 SERDES_IREG_TX_DRV_3_LEVNP1_MASK,
1751			 SERDES_IREG_TX_DRV_3_LEVNP1_SHIFT,
1752			 params->c_minus_1);
1753
1754	AL_REG_FIELD_SET(reg,
1755			 SERDES_IREG_TX_DRV_3_SLEW_MASK,
1756			 SERDES_IREG_TX_DRV_3_SLEW_SHIFT,
1757			 params->slew_rate);
1758
1759	al_serdes_grp_lane_write(&obj->grp_info[grp],
1760				lane,
1761				AL_SRDS_REG_TYPE_PMA,
1762				SERDES_IREG_TX_DRV_3_REG_NUM,
1763				reg);
1764
1765}
1766
1767void al_serdes_tx_advanced_params_get(struct al_serdes_obj	     	*obj,
1768				      enum al_serdes_group	      	grp,
1769				      enum al_serdes_lane		lane,
1770				      struct al_serdes_adv_tx_params *tx_params)
1771{
1772	uint8_t reg_val = 0;
1773
1774	al_serdes_lane_read(obj, grp, lane, AL_SRDS_REG_TYPE_PMA,
1775			SERDES_IREG_TX_DRV_1_REG_NUM,
1776			&reg_val);
1777	tx_params->amp = (reg_val & SERDES_IREG_TX_DRV_1_HLEV_MASK) >>
1778				SERDES_IREG_TX_DRV_1_HLEV_SHIFT;
1779	tx_params->total_driver_units = (reg_val &
1780					SERDES_IREG_TX_DRV_1_LEVN_MASK) >>
1781					SERDES_IREG_TX_DRV_1_LEVN_SHIFT;
1782
1783	al_serdes_lane_read(obj, grp, lane, AL_SRDS_REG_TYPE_PMA,
1784			SERDES_IREG_TX_DRV_2_REG_NUM,
1785			&reg_val);
1786	tx_params->c_plus_1 = (reg_val & SERDES_IREG_TX_DRV_2_LEVNM1_MASK) >>
1787				SERDES_IREG_TX_DRV_2_LEVNM1_SHIFT;
1788	tx_params->c_plus_2 = (reg_val & SERDES_IREG_TX_DRV_2_LEVNM2_MASK) >>
1789				SERDES_IREG_TX_DRV_2_LEVNM2_SHIFT;
1790
1791	al_serdes_lane_read(obj, grp, lane, AL_SRDS_REG_TYPE_PMA,
1792			SERDES_IREG_TX_DRV_3_REG_NUM,
1793			&reg_val);
1794	tx_params->c_minus_1 = (reg_val & SERDES_IREG_TX_DRV_3_LEVNP1_MASK) >>
1795				SERDES_IREG_TX_DRV_3_LEVNP1_SHIFT;
1796	tx_params->slew_rate = (reg_val & SERDES_IREG_TX_DRV_3_SLEW_MASK) >>
1797				SERDES_IREG_TX_DRV_3_SLEW_SHIFT;
1798
1799	al_serdes_lane_read(obj, grp, lane, AL_SRDS_REG_TYPE_PMA,
1800			SERDES_IREG_FLD_TX_DRV_OVERRIDE_EN_REG_NUM,
1801			&reg_val);
1802	tx_params->override = ((reg_val & SERDES_IREG_FLD_TX_DRV_OVERRIDE_EN) == 0);
1803}
1804
1805
1806void al_serdes_rx_advanced_params_set(struct al_serdes_obj	      *obj,
1807				      enum al_serdes_group	      grp,
1808				      enum al_serdes_lane	      lane,
1809				      struct al_serdes_adv_rx_params  *params)
1810{
1811	uint8_t reg = 0;
1812
1813	if(!params->override) {
1814		al_serdes_grp_lane_masked_write(&obj->grp_info[grp],
1815			lane,
1816			AL_SRDS_REG_TYPE_PMA,
1817			SERDES_IREG_FLD_RX_DRV_OVERRIDE_EN_REG_NUM,
1818			SERDES_IREG_FLD_RX_DRV_OVERRIDE_EN,
1819			SERDES_IREG_FLD_RX_DRV_OVERRIDE_EN);
1820
1821		return;
1822	}
1823
1824	al_serdes_grp_lane_masked_write(&obj->grp_info[grp],
1825			lane,
1826			AL_SRDS_REG_TYPE_PMA,
1827			SERDES_IREG_FLD_RX_DRV_OVERRIDE_EN_REG_NUM,
1828			SERDES_IREG_FLD_RX_DRV_OVERRIDE_EN,
1829			0);
1830
1831	AL_REG_FIELD_SET(reg,
1832			 SERDES_IREG_RX_CALEQ_1_DCGAIN_MASK,
1833			 SERDES_IREG_RX_CALEQ_1_DCGAIN_SHIFT,
1834			 params->dcgain);
1835
1836	AL_REG_FIELD_SET(reg,
1837			 SERDES_IREG_RX_CALEQ_1_DFEPSTAP3DB_MASK,
1838			 SERDES_IREG_RX_CALEQ_1_DFEPSTAP3DB_SHIFT,
1839			 params->dfe_3db_freq);
1840
1841	al_serdes_grp_lane_write(&obj->grp_info[grp],
1842				lane,
1843				AL_SRDS_REG_TYPE_PMA,
1844				SERDES_IREG_RX_CALEQ_1_REG_NUM,
1845				reg);
1846
1847	reg = 0;
1848	AL_REG_FIELD_SET(reg,
1849			 SERDES_IREG_RX_CALEQ_2_DFEPSTAPGAIN_MASK,
1850			 SERDES_IREG_RX_CALEQ_2_DFEPSTAPGAIN_SHIFT,
1851			 params->dfe_gain);
1852
1853	AL_REG_FIELD_SET(reg,
1854			 SERDES_IREG_RX_CALEQ_2_DFETAP1GAIN_MASK,
1855			 SERDES_IREG_RX_CALEQ_2_DFETAP1GAIN_SHIFT,
1856			 params->dfe_first_tap_ctrl);
1857
1858	al_serdes_grp_lane_write(&obj->grp_info[grp],
1859				lane,
1860				AL_SRDS_REG_TYPE_PMA,
1861				SERDES_IREG_RX_CALEQ_2_REG_NUM,
1862				reg);
1863
1864	reg = 0;
1865	AL_REG_FIELD_SET(reg,
1866			 SERDES_IREG_RX_CALEQ_3_DFETAP2GAIN_MASK,
1867			 SERDES_IREG_RX_CALEQ_3_DFETAP2GAIN_SHIFT,
1868			 params->dfe_secound_tap_ctrl);
1869
1870	AL_REG_FIELD_SET(reg,
1871			 SERDES_IREG_RX_CALEQ_3_DFETAP3GAIN_MASK,
1872			 SERDES_IREG_RX_CALEQ_3_DFETAP3GAIN_SHIFT,
1873			 params->dfe_third_tap_ctrl);
1874
1875	al_serdes_grp_lane_write(&obj->grp_info[grp],
1876				lane,
1877				AL_SRDS_REG_TYPE_PMA,
1878				SERDES_IREG_RX_CALEQ_3_REG_NUM,
1879				reg);
1880
1881	reg = 0;
1882	AL_REG_FIELD_SET(reg,
1883			 SERDES_IREG_RX_CALEQ_4_DFETAP4GAIN_MASK,
1884			 SERDES_IREG_RX_CALEQ_4_DFETAP4GAIN_SHIFT,
1885			 params->dfe_fourth_tap_ctrl);
1886
1887	AL_REG_FIELD_SET(reg,
1888			 SERDES_IREG_RX_CALEQ_4_LOFREQAGCGAIN_MASK,
1889			 SERDES_IREG_RX_CALEQ_4_LOFREQAGCGAIN_SHIFT,
1890			 params->low_freq_agc_gain);
1891
1892	al_serdes_grp_lane_write(&obj->grp_info[grp],
1893				lane,
1894				AL_SRDS_REG_TYPE_PMA,
1895				SERDES_IREG_RX_CALEQ_4_REG_NUM,
1896				reg);
1897
1898	reg = 0;
1899	AL_REG_FIELD_SET(reg,
1900			 SERDES_IREG_RX_CALEQ_5_PRECAL_CODE_SEL_MASK,
1901			 SERDES_IREG_RX_CALEQ_5_PRECAL_CODE_SEL_SHIFT,
1902			 params->precal_code_sel);
1903
1904	AL_REG_FIELD_SET(reg,
1905			 SERDES_IREG_RX_CALEQ_5_HIFREQAGCCAP_MASK,
1906			 SERDES_IREG_RX_CALEQ_5_HIFREQAGCCAP_SHIFT,
1907			 params->high_freq_agc_boost);
1908
1909	al_serdes_grp_lane_write(&obj->grp_info[grp],
1910				lane,
1911				AL_SRDS_REG_TYPE_PMA,
1912				SERDES_IREG_RX_CALEQ_5_REG_NUM,
1913				reg);
1914}
1915
1916static inline void al_serdes_common_cfg_eth(struct al_serdes_group_info *grp_info)
1917{
1918	al_serdes_grp_reg_masked_write(
1919				grp_info,
1920				AL_SRDS_REG_PAGE_4_COMMON,
1921				AL_SRDS_REG_TYPE_PMA,
1922				SERDES_IREG_FLD_RXEQ_LOOKUP_CODE_EN_REG_NUM,
1923				SERDES_IREG_FLD_RXEQ_LOOKUP_CODE_EN_MASK,
1924				(0x1 << SERDES_IREG_FLD_RXEQ_LOOKUP_CODE_EN_SHIFT));
1925
1926	al_serdes_grp_reg_masked_write(
1927				grp_info,
1928				AL_SRDS_REG_PAGE_4_COMMON,
1929				AL_SRDS_REG_TYPE_PMA,
1930				SERDES_IREG_FLD_RXEQ_LOOKUP_LASTCODE_REG_NUM,
1931				SERDES_IREG_FLD_RXEQ_LOOKUP_LASTCODE_MASK,
1932				(0 << SERDES_IREG_FLD_RXEQ_LOOKUP_LASTCODE_SHIFT));
1933
1934	al_serdes_grp_reg_masked_write(
1935				grp_info,
1936				AL_SRDS_REG_PAGE_4_COMMON,
1937				AL_SRDS_REG_TYPE_PMA,
1938				SERDES_IREG_FLD_RXEQ_COARSE_RUN1_MASK_REG_NUM,
1939				SERDES_IREG_FLD_RXEQ_COARSE_RUN1_MASK_MASK,
1940				(0x2 << SERDES_IREG_FLD_RXEQ_COARSE_RUN1_MASK_SHIFT));
1941
1942	al_serdes_grp_reg_masked_write(
1943				grp_info,
1944				AL_SRDS_REG_PAGE_4_COMMON,
1945				AL_SRDS_REG_TYPE_PMA,
1946				SERDES_IREG_FLD_RXEQ_COARSE_RUN2_MASK_REG_NUM,
1947				SERDES_IREG_FLD_RXEQ_COARSE_RUN2_MASK_MASK,
1948				(0 << SERDES_IREG_FLD_RXEQ_COARSE_RUN2_MASK_SHIFT));
1949
1950	al_serdes_grp_reg_masked_write(
1951				grp_info,
1952				AL_SRDS_REG_PAGE_4_COMMON,
1953				AL_SRDS_REG_TYPE_PMA,
1954				SERDES_IREG_FLD_RXEQ_COARSE_STEP_REG_NUM,
1955				SERDES_IREG_FLD_RXEQ_COARSE_STEP_MASK,
1956				(0x1 << SERDES_IREG_FLD_RXEQ_COARSE_STEP_SHIFT));
1957
1958	al_serdes_grp_reg_masked_write(
1959				grp_info,
1960				AL_SRDS_REG_PAGE_4_COMMON,
1961				AL_SRDS_REG_TYPE_PMA,
1962				SERDES_IREG_FLD_RXEQ_COARSE_ITER_NUM_REG_NUM,
1963				SERDES_IREG_FLD_RXEQ_COARSE_ITER_NUM_MASK,
1964				(0x1 << SERDES_IREG_FLD_RXEQ_COARSE_ITER_NUM_SHIFT));
1965
1966	al_serdes_grp_reg_masked_write(
1967				grp_info,
1968				AL_SRDS_REG_PAGE_4_COMMON,
1969				AL_SRDS_REG_TYPE_PMA,
1970				SERDES_IREG_FLD_RXEQ_FINE_RUN1_MASK_REG_NUM,
1971				SERDES_IREG_FLD_RXEQ_FINE_RUN1_MASK_MASK,
1972				(0xf0 << SERDES_IREG_FLD_RXEQ_FINE_RUN1_MASK_SHIFT));
1973
1974	al_serdes_grp_reg_masked_write(
1975				grp_info,
1976				AL_SRDS_REG_PAGE_4_COMMON,
1977				AL_SRDS_REG_TYPE_PMA,
1978				SERDES_IREG_FLD_RXEQ_FINE_RUN2_MASK_REG_NUM,
1979				SERDES_IREG_FLD_RXEQ_FINE_RUN2_MASK_MASK,
1980				(0 << SERDES_IREG_FLD_RXEQ_FINE_RUN2_MASK_SHIFT));
1981
1982	al_serdes_grp_reg_masked_write(
1983				grp_info,
1984				AL_SRDS_REG_PAGE_4_COMMON,
1985				AL_SRDS_REG_TYPE_PMA,
1986				SERDES_IREG_FLD_RXEQ_FINE_STEP_REG_NUM,
1987				SERDES_IREG_FLD_RXEQ_FINE_STEP_MASK,
1988				(1 << SERDES_IREG_FLD_RXEQ_FINE_STEP_SHIFT));
1989
1990	al_serdes_grp_reg_masked_write(
1991				grp_info,
1992				AL_SRDS_REG_PAGE_4_COMMON,
1993				AL_SRDS_REG_TYPE_PMA,
1994				SERDES_IREG_FLD_RXEQ_FINE_ITER_NUM_REG_NUM,
1995				SERDES_IREG_FLD_RXEQ_FINE_ITER_NUM_MASK,
1996				(0x8 << SERDES_IREG_FLD_RXEQ_FINE_ITER_NUM_SHIFT));
1997
1998	al_serdes_grp_reg_masked_write(
1999				grp_info,
2000				AL_SRDS_REG_PAGE_4_COMMON,
2001				AL_SRDS_REG_TYPE_PMA,
2002				SERDES_IREG_FLD_RXCALEYEDIAGFSM_BERTHRESHOLD1_REG_NUM,
2003				SERDES_IREG_FLD_RXCALEYEDIAGFSM_BERTHRESHOLD1_MASK,
2004				(0 << SERDES_IREG_FLD_RXCALEYEDIAGFSM_BERTHRESHOLD1_SHIFT));
2005
2006	al_serdes_grp_reg_masked_write(
2007				grp_info,
2008				AL_SRDS_REG_PAGE_4_COMMON,
2009				AL_SRDS_REG_TYPE_PMA,
2010				SERDES_IREG_FLD_RXCALEYEDIAGFSM_BERTHRESHOLD2_REG_NUM,
2011				SERDES_IREG_FLD_RXCALEYEDIAGFSM_BERTHRESHOLD2_MASK,
2012				(0x64 << SERDES_IREG_FLD_RXCALEYEDIAGFSM_BERTHRESHOLD2_SHIFT));
2013
2014	al_serdes_grp_reg_masked_write(
2015				grp_info,
2016				AL_SRDS_REG_PAGE_4_COMMON,
2017				AL_SRDS_REG_TYPE_PMA,
2018				SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALCOARSE_REG_NUM,
2019				SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALCOARSE_MASK,
2020				(0x3 << SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALCOARSE_SHIFT));
2021
2022	al_serdes_grp_reg_masked_write(
2023				grp_info,
2024				AL_SRDS_REG_PAGE_4_COMMON,
2025				AL_SRDS_REG_TYPE_PMA,
2026				SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALFINE_REG_NUM,
2027				SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALFINE_MASK,
2028				(0x1 << SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALFINE_SHIFT));
2029
2030	al_serdes_grp_reg_masked_write(
2031				grp_info,
2032				AL_SRDS_REG_PAGE_4_COMMON,
2033				AL_SRDS_REG_TYPE_PMA,
2034				SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALCOARSE_REG_NUM,
2035				SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALCOARSE_MASK,
2036				(3 << SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALCOARSE_SHIFT));
2037
2038	al_serdes_grp_reg_masked_write(
2039				grp_info,
2040				AL_SRDS_REG_PAGE_4_COMMON,
2041				AL_SRDS_REG_TYPE_PMA,
2042				SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALFINE_REG_NUM,
2043				SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALFINE_MASK,
2044				(1 << SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALFINE_SHIFT));
2045
2046	al_serdes_grp_reg_masked_write(
2047				grp_info,
2048				AL_SRDS_REG_PAGE_4_COMMON,
2049				AL_SRDS_REG_TYPE_PMA,
2050				SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_MSB_REG_NUM,
2051				SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_MSB_MASK,
2052				(0xc << SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_MSB_SHIFT));
2053
2054	al_serdes_grp_reg_masked_write(
2055				grp_info,
2056				AL_SRDS_REG_PAGE_4_COMMON,
2057				AL_SRDS_REG_TYPE_PMA,
2058				SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_LSB_REG_NUM,
2059				SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_LSB_MASK,
2060				(0xcc << SERDES_IREG_FLD_EYE_DIAG_SAMPLE_CNT_LSB_SHIFT));
2061}
2062
2063struct al_serdes_mode_rx_tx_inv_state {
2064	al_bool		restore;
2065	uint32_t	pipe_rst;
2066	uint32_t	ipd_multi[AL_SRDS_NUM_LANES];
2067	uint8_t		inv_value[AL_SRDS_NUM_LANES];
2068};
2069
2070static void al_serdes_mode_rx_tx_inv_state_save(
2071	struct al_serdes_group_info		*grp_info,
2072	struct al_serdes_mode_rx_tx_inv_state	*state)
2073{
2074	if (al_reg_read32(&grp_info->regs_base->gen.irst) & SERDES_GEN_IRST_POR_B_A) {
2075		int i;
2076
2077		state->restore = AL_TRUE;
2078		state->pipe_rst = al_reg_read32(&grp_info->regs_base->gen.irst);
2079
2080		for (i = 0; i < AL_SRDS_NUM_LANES; i++) {
2081			state->inv_value[i] = al_serdes_grp_reg_read(
2082				grp_info,
2083				i,
2084				AL_SRDS_REG_TYPE_PMA,
2085				SERDES_IREG_FLD_POLARITY_RX_REG_NUM);
2086			state->ipd_multi[i] =
2087				al_reg_read32(&grp_info->regs_base->lane[i].ipd_multi);
2088		}
2089	} else {
2090		state->restore = AL_FALSE;
2091	}
2092}
2093
2094static void al_serdes_mode_rx_tx_inv_state_restore(
2095	struct al_serdes_group_info		*grp_info,
2096	struct al_serdes_mode_rx_tx_inv_state	*state)
2097{
2098	if (state->restore) {
2099		int i;
2100
2101		for (i = 0; i < AL_SRDS_NUM_LANES; i++) {
2102			al_serdes_grp_reg_write(
2103				grp_info,
2104				i,
2105				AL_SRDS_REG_TYPE_PMA,
2106				SERDES_IREG_FLD_POLARITY_RX_REG_NUM,
2107				state->inv_value[i]);
2108			al_reg_write32(
2109				&grp_info->regs_base->lane[i].ipd_multi, state->ipd_multi[i]);
2110			al_reg_write32_masked(
2111				&grp_info->regs_base->gen.irst,
2112				(SERDES_GEN_IRST_PIPE_RST_L0_B_A_SEL >> i) |
2113				(SERDES_GEN_IRST_PIPE_RST_L0_B_A >> i),
2114				state->pipe_rst);
2115		}
2116	}
2117}
2118
2119void al_serdes_mode_set_sgmii(
2120	struct al_serdes_obj	*obj,
2121	enum al_serdes_group	grp)
2122{
2123	struct al_serdes_group_info *grp_info;
2124	struct al_serdes_mode_rx_tx_inv_state rx_tx_inv_state;
2125
2126	al_assert(obj);
2127	al_assert(((int)grp) >= AL_SRDS_GRP_A);
2128	al_assert(((int)grp) <= AL_SRDS_GRP_D);
2129
2130	grp_info = &obj->grp_info[grp];
2131
2132	al_serdes_mode_rx_tx_inv_state_save(grp_info, &rx_tx_inv_state);
2133
2134	al_reg_write32(&grp_info->regs_base->gen.irst, 0x000000);
2135	al_reg_write32(&grp_info->regs_base->lane[0].ictl_multi, 0x10110010);
2136	al_reg_write32(&grp_info->regs_base->lane[1].ictl_multi, 0x10110010);
2137	al_reg_write32(&grp_info->regs_base->lane[2].ictl_multi, 0x10110010);
2138	al_reg_write32(&grp_info->regs_base->lane[3].ictl_multi, 0x10110010);
2139	al_reg_write32(&grp_info->regs_base->gen.ipd_multi_synth , 0x0001);
2140	al_reg_write32(&grp_info->regs_base->lane[0].ipd_multi, 0x0003);
2141	al_reg_write32(&grp_info->regs_base->lane[1].ipd_multi, 0x0003);
2142	al_reg_write32(&grp_info->regs_base->lane[2].ipd_multi, 0x0003);
2143	al_reg_write32(&grp_info->regs_base->lane[3].ipd_multi, 0x0003);
2144	al_reg_write32(&grp_info->regs_base->gen.ictl_pcs , 0);
2145	al_reg_write32(&grp_info->regs_base->gen.irst, 0x001000);
2146	al_serdes_ns_delay(800);
2147	al_reg_write32(&grp_info->regs_base->gen.irst, 0x000000);
2148	al_serdes_ns_delay(500);
2149	al_reg_write32(&grp_info->regs_base->gen.irst, 0x001000);
2150	al_serdes_ns_delay(500);
2151
2152	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123,
2153		AL_SRDS_REG_TYPE_PMA, 101, 183);
2154	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123,
2155		AL_SRDS_REG_TYPE_PMA, 102, 183);
2156	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123,
2157		AL_SRDS_REG_TYPE_PMA, 103, 12);
2158	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123,
2159		AL_SRDS_REG_TYPE_PMA, 104, 12);
2160	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123,
2161		AL_SRDS_REG_TYPE_PMA, 105, 26);
2162	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123,
2163		AL_SRDS_REG_TYPE_PMA, 106, 26);
2164	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123,
2165		AL_SRDS_REG_TYPE_PMA, 107, 2);
2166	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123,
2167		AL_SRDS_REG_TYPE_PMA, 108, 2);
2168	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123,
2169		AL_SRDS_REG_TYPE_PMA, 109, 17);
2170	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123,
2171		AL_SRDS_REG_TYPE_PMA, 110, 13);
2172	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2173		AL_SRDS_REG_TYPE_PMA, 101, 153);
2174	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2175		AL_SRDS_REG_TYPE_PMA, 102, 0);
2176	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2177		AL_SRDS_REG_TYPE_PMA, 103, 108);
2178	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2179		AL_SRDS_REG_TYPE_PMA, 104, 183);
2180	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2181		AL_SRDS_REG_TYPE_PMA, 105, 183);
2182	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2183		AL_SRDS_REG_TYPE_PMA, 106, 12);
2184	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2185		AL_SRDS_REG_TYPE_PMA, 107, 12);
2186	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2187		AL_SRDS_REG_TYPE_PMA, 108, 26);
2188	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2189		AL_SRDS_REG_TYPE_PMA, 109, 26);
2190	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2191		AL_SRDS_REG_TYPE_PMA, 110, 7);
2192	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2193		AL_SRDS_REG_TYPE_PMA, 111, 12);
2194	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2195		AL_SRDS_REG_TYPE_PMA, 112, 8);
2196	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2197		AL_SRDS_REG_TYPE_PMA, 113, 0);
2198	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2199		AL_SRDS_REG_TYPE_PMA, 114, 8);
2200	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2201		AL_SRDS_REG_TYPE_PMA, 115, 0);
2202	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2203		AL_SRDS_REG_TYPE_PMA, 116, 255);
2204	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2205		AL_SRDS_REG_TYPE_PMA, 117, 179);
2206	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2207		AL_SRDS_REG_TYPE_PMA, 118, 246);
2208	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2209		AL_SRDS_REG_TYPE_PMA, 119, 208);
2210	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2211		AL_SRDS_REG_TYPE_PMA, 120, 239);
2212	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2213		AL_SRDS_REG_TYPE_PMA, 121, 251);
2214	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2215		AL_SRDS_REG_TYPE_PMA, 122, 255);
2216	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2217		AL_SRDS_REG_TYPE_PMA, 123, 255);
2218	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2219		AL_SRDS_REG_TYPE_PMA, 124, 255);
2220	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2221		AL_SRDS_REG_TYPE_PMA, 125, 255);
2222	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2223		AL_SRDS_REG_TYPE_PMA, 126, 255);
2224	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2225		AL_SRDS_REG_TYPE_PMA, 127, 211);
2226	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2227		AL_SRDS_REG_TYPE_PMA, 128, 211);
2228	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2229		AL_SRDS_REG_TYPE_PMA, 129, 226);
2230	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2231		AL_SRDS_REG_TYPE_PMA, 130, 239);
2232	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2233		AL_SRDS_REG_TYPE_PMA, 131, 251);
2234	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2235		AL_SRDS_REG_TYPE_PMA, 132, 251);
2236	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2237		AL_SRDS_REG_TYPE_PMA, 133, 255);
2238	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2239		AL_SRDS_REG_TYPE_PMA, 134, 239);
2240	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2241		AL_SRDS_REG_TYPE_PMA, 135, 255);
2242	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2243		AL_SRDS_REG_TYPE_PMA, 136, 255);
2244	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2245		AL_SRDS_REG_TYPE_PMA, 137, 211);
2246	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2247		AL_SRDS_REG_TYPE_PMA, 138, 211);
2248	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2249		AL_SRDS_REG_TYPE_PMA, 139, 226);
2250	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2251		AL_SRDS_REG_TYPE_PMA, 140, 239);
2252	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2253		AL_SRDS_REG_TYPE_PMA, 141, 251);
2254	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2255		AL_SRDS_REG_TYPE_PMA, 142, 251);
2256	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2257		AL_SRDS_REG_TYPE_PMA, 143, 255);
2258	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2259		AL_SRDS_REG_TYPE_PMA, 144, 239);
2260	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2261		AL_SRDS_REG_TYPE_PMA, 145, 255);
2262	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2263		AL_SRDS_REG_TYPE_PMA, 146, 255);
2264	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2265		AL_SRDS_REG_TYPE_PMA, 147, 251);
2266	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2267		AL_SRDS_REG_TYPE_PMA, 148, 255);
2268	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2269		AL_SRDS_REG_TYPE_PMA, 149, 63);
2270	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2271		AL_SRDS_REG_TYPE_PMA, 150, 0);
2272	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2273		AL_SRDS_REG_TYPE_PMA, 151, 100);
2274	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2275		AL_SRDS_REG_TYPE_PMA, 152, 0);
2276	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2277		AL_SRDS_REG_TYPE_PMA, 153, 4);
2278	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2279		AL_SRDS_REG_TYPE_PMA, 154, 2);
2280	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2281		AL_SRDS_REG_TYPE_PMA, 155, 5);
2282	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2283		AL_SRDS_REG_TYPE_PMA, 156, 5);
2284	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2285		AL_SRDS_REG_TYPE_PMA, 157, 4);
2286	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2287		AL_SRDS_REG_TYPE_PMA, 158, 0);
2288	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2289		AL_SRDS_REG_TYPE_PMA, 159, 0);
2290	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2291		AL_SRDS_REG_TYPE_PMA, 160, 8);
2292	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2293		AL_SRDS_REG_TYPE_PMA, 161, 4);
2294	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2295		AL_SRDS_REG_TYPE_PMA, 162, 0);
2296	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2297		AL_SRDS_REG_TYPE_PMA, 163, 0);
2298	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2299		AL_SRDS_REG_TYPE_PMA, 164, 4);
2300	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0_LANE_0,
2301		AL_SRDS_REG_TYPE_PMA, 7, 0);
2302	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_1_LANE_1,
2303		AL_SRDS_REG_TYPE_PMA, 7, 0);
2304	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_2_LANE_2,
2305		AL_SRDS_REG_TYPE_PMA, 7, 0);
2306	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_3_LANE_3,
2307		AL_SRDS_REG_TYPE_PMA, 7, 0);
2308	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2309		AL_SRDS_REG_TYPE_PMA, 13, 16);
2310	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2311		AL_SRDS_REG_TYPE_PMA, 48, 0);
2312	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2313		AL_SRDS_REG_TYPE_PMA, 49, 0);
2314	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2315		AL_SRDS_REG_TYPE_PMA, 54, 0);
2316	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2317		AL_SRDS_REG_TYPE_PMA, 55, 180);
2318	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2319		AL_SRDS_REG_TYPE_PMA, 93, 2);
2320	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2321		AL_SRDS_REG_TYPE_PMA, 165, 3);
2322	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123,
2323		AL_SRDS_REG_TYPE_PMA, 41, 6);
2324	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2325		AL_SRDS_REG_TYPE_PMA, 354, 3);
2326	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2327		AL_SRDS_REG_TYPE_PMA, 355, 58);
2328	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2329		AL_SRDS_REG_TYPE_PMA, 356, 9);
2330	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2331		AL_SRDS_REG_TYPE_PMA, 357, 3);
2332	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2333		AL_SRDS_REG_TYPE_PMA, 358, 62);
2334	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2335		AL_SRDS_REG_TYPE_PMA, 359, 12);
2336	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123,
2337		AL_SRDS_REG_TYPE_PMA, 701, 0);
2338	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123,
2339		AL_SRDS_REG_TYPE_PMA, 87, 0x1f);
2340
2341	al_serdes_common_cfg_eth(grp_info);
2342
2343	al_serdes_mode_rx_tx_inv_state_restore(grp_info, &rx_tx_inv_state);
2344
2345	al_reg_write32(&grp_info->regs_base->gen.irst, 0x0011F0);
2346	al_serdes_ns_delay(500);
2347}
2348
2349void al_serdes_mode_set_kr(
2350	struct al_serdes_obj	*obj,
2351	enum al_serdes_group	grp)
2352{
2353	struct al_serdes_group_info *grp_info;
2354	struct al_serdes_mode_rx_tx_inv_state rx_tx_inv_state;
2355
2356	al_assert(obj);
2357	al_assert(((int)grp) >= AL_SRDS_GRP_A);
2358	al_assert(((int)grp) <= AL_SRDS_GRP_D);
2359
2360	grp_info = &obj->grp_info[grp];
2361
2362	al_serdes_mode_rx_tx_inv_state_save(grp_info, &rx_tx_inv_state);
2363
2364	al_reg_write32(&grp_info->regs_base->gen.irst, 0x000000);
2365	al_reg_write32(&grp_info->regs_base->lane[0].ictl_multi, 0x30330030);
2366	al_reg_write32(&grp_info->regs_base->lane[1].ictl_multi, 0x30330030);
2367	al_reg_write32(&grp_info->regs_base->lane[2].ictl_multi, 0x30330030);
2368	al_reg_write32(&grp_info->regs_base->lane[3].ictl_multi, 0x30330030);
2369	al_reg_write32(&grp_info->regs_base->gen.ipd_multi_synth , 0x0001);
2370	al_reg_write32(&grp_info->regs_base->lane[0].ipd_multi, 0x0003);
2371	al_reg_write32(&grp_info->regs_base->lane[1].ipd_multi, 0x0003);
2372	al_reg_write32(&grp_info->regs_base->lane[2].ipd_multi, 0x0003);
2373	al_reg_write32(&grp_info->regs_base->lane[3].ipd_multi, 0x0003);
2374	al_reg_write32(&grp_info->regs_base->gen.ictl_pcs , 0);
2375	al_reg_write32(&grp_info->regs_base->gen.irst, 0x001000);
2376	al_serdes_ns_delay(800);
2377	al_reg_write32(&grp_info->regs_base->gen.irst, 0x000000);
2378	al_serdes_ns_delay(500);
2379	al_reg_write32(&grp_info->regs_base->gen.irst, 0x001000);
2380	al_serdes_ns_delay(500);
2381
2382	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123,
2383		AL_SRDS_REG_TYPE_PMA, 101, 189);
2384	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123,
2385		AL_SRDS_REG_TYPE_PMA, 102, 189);
2386	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123,
2387		AL_SRDS_REG_TYPE_PMA, 103, 6);
2388	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123,
2389		AL_SRDS_REG_TYPE_PMA, 104, 6);
2390	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123,
2391		AL_SRDS_REG_TYPE_PMA, 105, 27);
2392	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123,
2393		AL_SRDS_REG_TYPE_PMA, 106, 27);
2394	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123,
2395		AL_SRDS_REG_TYPE_PMA, 107, 1);
2396	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123,
2397		AL_SRDS_REG_TYPE_PMA, 108, 1);
2398	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123,
2399		AL_SRDS_REG_TYPE_PMA, 109, 119);
2400	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123,
2401		AL_SRDS_REG_TYPE_PMA, 110, 5);
2402	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2403		AL_SRDS_REG_TYPE_PMA, 101, 170);
2404	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2405		AL_SRDS_REG_TYPE_PMA, 102, 0);
2406	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2407		AL_SRDS_REG_TYPE_PMA, 103, 108);
2408	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2409		AL_SRDS_REG_TYPE_PMA, 104, 189);
2410	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2411		AL_SRDS_REG_TYPE_PMA, 105, 189);
2412	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2413		AL_SRDS_REG_TYPE_PMA, 106, 6);
2414	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2415		AL_SRDS_REG_TYPE_PMA, 107, 6);
2416	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2417		AL_SRDS_REG_TYPE_PMA, 108, 27);
2418	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2419		AL_SRDS_REG_TYPE_PMA, 109, 27);
2420	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2421		AL_SRDS_REG_TYPE_PMA, 110, 7);
2422	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2423		AL_SRDS_REG_TYPE_PMA, 111, 12);
2424	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2425		AL_SRDS_REG_TYPE_PMA, 112, 16);
2426	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2427		AL_SRDS_REG_TYPE_PMA, 113, 0);
2428	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2429		AL_SRDS_REG_TYPE_PMA, 114, 16);
2430	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2431		AL_SRDS_REG_TYPE_PMA, 115, 0);
2432	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2433		AL_SRDS_REG_TYPE_PMA, 116, 255);
2434	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2435		AL_SRDS_REG_TYPE_PMA, 117, 179);
2436	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2437		AL_SRDS_REG_TYPE_PMA, 118, 246);
2438	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2439		AL_SRDS_REG_TYPE_PMA, 119, 208);
2440	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2441		AL_SRDS_REG_TYPE_PMA, 120, 239);
2442	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2443		AL_SRDS_REG_TYPE_PMA, 121, 251);
2444	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2445		AL_SRDS_REG_TYPE_PMA, 122, 255);
2446	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2447		AL_SRDS_REG_TYPE_PMA, 123, 255);
2448	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2449		AL_SRDS_REG_TYPE_PMA, 124, 255);
2450	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2451		AL_SRDS_REG_TYPE_PMA, 125, 255);
2452	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2453		AL_SRDS_REG_TYPE_PMA, 126, 255);
2454	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2455		AL_SRDS_REG_TYPE_PMA, 127, 211);
2456	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2457		AL_SRDS_REG_TYPE_PMA, 128, 211);
2458	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2459		AL_SRDS_REG_TYPE_PMA, 129, 226);
2460	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2461		AL_SRDS_REG_TYPE_PMA, 130, 239);
2462	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2463		AL_SRDS_REG_TYPE_PMA, 131, 251);
2464	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2465		AL_SRDS_REG_TYPE_PMA, 132, 251);
2466	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2467		AL_SRDS_REG_TYPE_PMA, 133, 255);
2468	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2469		AL_SRDS_REG_TYPE_PMA, 134, 239);
2470	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2471		AL_SRDS_REG_TYPE_PMA, 135, 255);
2472	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2473		AL_SRDS_REG_TYPE_PMA, 136, 255);
2474	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2475		AL_SRDS_REG_TYPE_PMA, 137, 211);
2476	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2477		AL_SRDS_REG_TYPE_PMA, 138, 211);
2478	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2479		AL_SRDS_REG_TYPE_PMA, 139, 226);
2480	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2481		AL_SRDS_REG_TYPE_PMA, 140, 239);
2482	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2483		AL_SRDS_REG_TYPE_PMA, 141, 251);
2484	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2485		AL_SRDS_REG_TYPE_PMA, 142, 251);
2486	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2487		AL_SRDS_REG_TYPE_PMA, 143, 255);
2488	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2489		AL_SRDS_REG_TYPE_PMA, 144, 239);
2490	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2491		AL_SRDS_REG_TYPE_PMA, 145, 255);
2492	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2493		AL_SRDS_REG_TYPE_PMA, 146, 255);
2494	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2495		AL_SRDS_REG_TYPE_PMA, 147, 251);
2496	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2497		AL_SRDS_REG_TYPE_PMA, 148, 255);
2498	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2499		AL_SRDS_REG_TYPE_PMA, 149, 63);
2500	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2501		AL_SRDS_REG_TYPE_PMA, 150, 0);
2502	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2503		AL_SRDS_REG_TYPE_PMA, 151, 50);
2504	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2505		AL_SRDS_REG_TYPE_PMA, 152, 17);
2506	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2507		AL_SRDS_REG_TYPE_PMA, 153, 2);
2508	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2509		AL_SRDS_REG_TYPE_PMA, 154, 1);
2510	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2511		AL_SRDS_REG_TYPE_PMA, 155, 0);
2512	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2513		AL_SRDS_REG_TYPE_PMA, 156, 0);
2514	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2515		AL_SRDS_REG_TYPE_PMA, 157, 4);
2516	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2517		AL_SRDS_REG_TYPE_PMA, 158, 0);
2518	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2519		AL_SRDS_REG_TYPE_PMA, 159, 0);
2520	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2521		AL_SRDS_REG_TYPE_PMA, 160, 8);
2522	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2523		AL_SRDS_REG_TYPE_PMA, 161, 4);
2524	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2525		AL_SRDS_REG_TYPE_PMA, 162, 0);
2526	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2527		AL_SRDS_REG_TYPE_PMA, 163, 0);
2528	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2529		AL_SRDS_REG_TYPE_PMA, 164, 4);
2530	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0_LANE_0,
2531		AL_SRDS_REG_TYPE_PMA, 7, 0);
2532	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_1_LANE_1,
2533		AL_SRDS_REG_TYPE_PMA, 7, 0);
2534	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_2_LANE_2,
2535		AL_SRDS_REG_TYPE_PMA, 7, 0);
2536	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_3_LANE_3,
2537		AL_SRDS_REG_TYPE_PMA, 7, 0);
2538	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2539		AL_SRDS_REG_TYPE_PMA, 13, 16);
2540	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2541		AL_SRDS_REG_TYPE_PMA, 48, 0);
2542	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2543		AL_SRDS_REG_TYPE_PMA, 49, 0);
2544	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2545		AL_SRDS_REG_TYPE_PMA, 54, 0);
2546	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2547		AL_SRDS_REG_TYPE_PMA, 55, 149); /*Was 182*/
2548	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2549		AL_SRDS_REG_TYPE_PMA, 93, 2);
2550	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2551		AL_SRDS_REG_TYPE_PMA, 165, 3);
2552	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123,
2553		AL_SRDS_REG_TYPE_PMA, 41, 6);
2554	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2555		AL_SRDS_REG_TYPE_PMA, 354, 3);
2556	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2557		AL_SRDS_REG_TYPE_PMA, 355, 58);
2558	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2559		AL_SRDS_REG_TYPE_PMA, 356, 9);
2560	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2561		AL_SRDS_REG_TYPE_PMA, 357, 3);
2562	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2563		AL_SRDS_REG_TYPE_PMA, 358, 62);
2564	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON,
2565		AL_SRDS_REG_TYPE_PMA, 359, 12);
2566	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123,
2567		AL_SRDS_REG_TYPE_PMA, 701, 0);
2568	al_serdes_grp_reg_write(grp_info, AL_SRDS_REG_PAGE_0123_LANES_0123,
2569		AL_SRDS_REG_TYPE_PMA, 87, 0x1f);
2570
2571	al_serdes_common_cfg_eth(grp_info);
2572
2573	al_serdes_mode_rx_tx_inv_state_restore(grp_info, &rx_tx_inv_state);
2574
2575	al_reg_write32(&grp_info->regs_base->gen.irst, 0x0011F0);
2576	al_serdes_ns_delay(500);
2577}
2578
2579void al_serdes_rx_advanced_params_get(struct al_serdes_obj           *obj,
2580				      enum al_serdes_group	      grp,
2581				      enum al_serdes_lane	      lane,
2582				      struct al_serdes_adv_rx_params* rx_params)
2583{
2584	uint8_t temp_val;
2585
2586	al_serdes_lane_read(
2587			obj, grp, lane, AL_SRDS_REG_TYPE_PMA,
2588			SERDES_IREG_RX_CALEQ_1_REG_NUM,
2589			&temp_val);
2590	rx_params->dcgain = (temp_val & SERDES_IREG_RX_CALEQ_1_DCGAIN_MASK) >>
2591				SERDES_IREG_RX_CALEQ_1_DCGAIN_SHIFT;
2592	rx_params->dfe_3db_freq = (temp_val &
2593				SERDES_IREG_RX_CALEQ_1_DFEPSTAP3DB_MASK) >>
2594				SERDES_IREG_RX_CALEQ_1_DFEPSTAP3DB_SHIFT;
2595
2596	al_serdes_lane_read(
2597			obj, grp, lane, AL_SRDS_REG_TYPE_PMA,
2598			SERDES_IREG_RX_CALEQ_2_REG_NUM,
2599			&temp_val);
2600	rx_params->dfe_gain = (temp_val &
2601				SERDES_IREG_RX_CALEQ_2_DFEPSTAPGAIN_MASK) >>
2602				SERDES_IREG_RX_CALEQ_2_DFEPSTAPGAIN_SHIFT;
2603	rx_params->dfe_first_tap_ctrl = (temp_val &
2604			SERDES_IREG_RX_CALEQ_2_DFETAP1GAIN_MASK) >>
2605			SERDES_IREG_RX_CALEQ_2_DFETAP1GAIN_SHIFT;
2606
2607	al_serdes_lane_read(
2608			obj, grp, lane, AL_SRDS_REG_TYPE_PMA,
2609			SERDES_IREG_RX_CALEQ_3_REG_NUM,
2610			&temp_val);
2611	rx_params->dfe_secound_tap_ctrl = (temp_val &
2612			SERDES_IREG_RX_CALEQ_3_DFETAP2GAIN_MASK) >>
2613			SERDES_IREG_RX_CALEQ_3_DFETAP2GAIN_SHIFT;
2614	rx_params->dfe_third_tap_ctrl = (temp_val &
2615			SERDES_IREG_RX_CALEQ_3_DFETAP3GAIN_MASK) >>
2616			SERDES_IREG_RX_CALEQ_3_DFETAP3GAIN_SHIFT;
2617
2618	al_serdes_lane_read(
2619			obj, grp, lane, AL_SRDS_REG_TYPE_PMA,
2620			SERDES_IREG_RX_CALEQ_4_REG_NUM,
2621			&temp_val);
2622	rx_params->dfe_fourth_tap_ctrl = (temp_val &
2623			SERDES_IREG_RX_CALEQ_4_DFETAP4GAIN_MASK) >>
2624			SERDES_IREG_RX_CALEQ_4_DFETAP4GAIN_SHIFT;
2625	rx_params->low_freq_agc_gain = (temp_val &
2626			SERDES_IREG_RX_CALEQ_4_LOFREQAGCGAIN_MASK) >>
2627			SERDES_IREG_RX_CALEQ_4_LOFREQAGCGAIN_SHIFT;
2628
2629	al_serdes_lane_read(
2630			obj, grp, lane, AL_SRDS_REG_TYPE_PMA,
2631			SERDES_IREG_RX_CALEQ_5_REG_NUM,
2632			&temp_val);
2633	rx_params->precal_code_sel = (temp_val &
2634			SERDES_IREG_RX_CALEQ_5_PRECAL_CODE_SEL_MASK) >>
2635			SERDES_IREG_RX_CALEQ_5_PRECAL_CODE_SEL_SHIFT;
2636	rx_params->high_freq_agc_boost = (temp_val &
2637			SERDES_IREG_RX_CALEQ_5_HIFREQAGCCAP_MASK) >>
2638			SERDES_IREG_RX_CALEQ_5_HIFREQAGCCAP_SHIFT;
2639
2640	al_serdes_lane_read(obj, grp, lane, AL_SRDS_REG_TYPE_PMA,
2641			SERDES_IREG_FLD_RX_DRV_OVERRIDE_EN_REG_NUM,
2642			&temp_val);
2643	rx_params->override = ((temp_val & SERDES_IREG_FLD_RX_DRV_OVERRIDE_EN) == 0);
2644}
2645
2646#if (	SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_LOCWREN_REG_NUM != \
2647		SERDES_IREG_FLD_RXCALROAMEYEMEASIN_LOCWREN_REG_NUM || \
2648	SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_LOCWREN_REG_NUM != \
2649		SERDES_IREG_FLD_RXCALROAMXADJUST_LOCWREN_REG_NUM)
2650#error Wrong assumption
2651#endif
2652int al_serdes_rx_equalization(
2653		struct al_serdes_obj *obj,
2654		enum al_serdes_group grp,
2655		enum al_serdes_lane  lane)
2656{
2657	uint8_t serdes_ireg_fld_rxcalroamyadjust_locwren_val;
2658	uint8_t serdes_ireg_fld_rxroam_xorbitsel_val;
2659	uint8_t serdes_ireg_fld_pcsrxeq_locwren_val;
2660	uint8_t serdes_ireg_fld_rxcal_locwren_val;
2661	uint8_t temp_val;
2662	uint8_t done;
2663
2664	int test_score;
2665	int i;
2666
2667	/*
2668	 * Make sure Roam Eye mechanism is not overridden
2669	 * Lane SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_LOCWREN = 1,
2670	 * 	so Rx 4-Point Eye process is not overridden
2671	 * Lane SERDES_IREG_FLD_RXCALROAMEYEMEASIN_LOCWREN = 1,
2672	 * 	so Eye Roam latch is not overridden
2673	 * Lane SERDES_IREG_FLD_RXCALROAMXADJUST_LOCWREN = 1,
2674	 * 	so Eye Roam latch 'X adjust' is not overridden
2675	 * Lane SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN = 1,
2676	 * 	so Eye Roam latch 'Y adjust' is not overridden
2677	 * Lane SERDES_IREG_FLD_RXROAM_XORBITSEL = 0/1,
2678	 * 	so Eye Roamlatch works on the right Eye position (XORBITSEL)
2679	 * 	For most cases 0 is needed, but sometimes 1 is needed.
2680	 * 	I couldn't sort out why is this so the code uses a global
2681	 *      XORBITSELmode variable, set by the user (GUI). Default is 0.
2682	 * control must be internal. At the end we restore original setting
2683	 */
2684
2685	/* save current values for restoring them later in the end */
2686	al_serdes_lane_read(
2687			obj, grp, lane, AL_SRDS_REG_TYPE_PMA,
2688			SERDES_IREG_FLD_RXCAL_LOCWREN_REG_NUM,
2689			&serdes_ireg_fld_rxcal_locwren_val);
2690
2691	al_serdes_lane_read(
2692			obj, grp, lane, AL_SRDS_REG_TYPE_PMA,
2693			SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN_REG_NUM,
2694			&serdes_ireg_fld_rxcalroamyadjust_locwren_val );
2695	al_serdes_lane_read(
2696			obj, grp, lane, AL_SRDS_REG_TYPE_PMA,
2697			SERDES_IREG_FLD_RXROAM_XORBITSEL_REG_NUM,
2698			&serdes_ireg_fld_rxroam_xorbitsel_val );
2699	al_serdes_lane_read(
2700			obj, grp, lane, AL_SRDS_REG_TYPE_PMA,
2701			SERDES_IREG_FLD_PCSRXEQ_LOCWREN_REG_NUM,
2702			&serdes_ireg_fld_pcsrxeq_locwren_val );
2703
2704	/*
2705	 * Set Bits:
2706	 * SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_LOCWREN
2707	 * SERDES_IREG_FLD_RXCALROAMEYEMEASIN_LOCWREN
2708	 * SERDES_IREG_FLD_RXCALROAMXADJUST_LOCWREN
2709	 * to return 4pt-RxEye and EyeRoam Latch to internal logic
2710	 *
2711	 * clear bit SERDES_IREG_FLD_RX_DRV_OVERRIDE_EN
2712	 * AGC/DFE controlled via PMA registers
2713	 */
2714	temp_val  = serdes_ireg_fld_rxcal_locwren_val;
2715	temp_val |= SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_LOCWREN;
2716	temp_val |= SERDES_IREG_FLD_RXCALROAMEYEMEASIN_LOCWREN;
2717	temp_val |= SERDES_IREG_FLD_RXCALROAMXADJUST_LOCWREN;
2718	temp_val |= SERDES_IREG_FLD_RX_DRV_OVERRIDE_EN;
2719
2720	al_serdes_lane_write(
2721			obj, grp, lane, AL_SRDS_REG_TYPE_PMA,
2722			SERDES_IREG_FLD_RXCAL_LOCWREN_REG_NUM,
2723			temp_val );
2724
2725	/*
2726	 * Set bit SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN
2727	 * to return EyeRoam Latch Y to internal logic
2728	 */
2729	temp_val = serdes_ireg_fld_rxcalroamyadjust_locwren_val |
2730			SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN;
2731	al_serdes_lane_write(
2732			obj, grp, lane, AL_SRDS_REG_TYPE_PMA,
2733			SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN_REG_NUM,
2734			temp_val );
2735
2736	/*
2737	 * Clear Bit: SERDES_IREG_FLD_RXROAM_XORBITSEL
2738	 * so XORBITSEL=0, needed for the Eye mapping.
2739	 */
2740	temp_val = serdes_ireg_fld_rxroam_xorbitsel_val &
2741			~SERDES_IREG_FLD_RXROAM_XORBITSEL;
2742	al_serdes_lane_write(
2743			obj, grp, lane, AL_SRDS_REG_TYPE_PMA,
2744			SERDES_IREG_FLD_RXROAM_XORBITSEL_REG_NUM,
2745			temp_val );
2746
2747	/*
2748	 * Take Control from int.pin over RxEQ process.
2749	 * Clear Bit SERDES_IREG_FLD_PCSRXEQ_LOCWREN
2750	 * to override RxEQ via PMA
2751	 */
2752	temp_val = serdes_ireg_fld_pcsrxeq_locwren_val &
2753			~SERDES_IREG_FLD_PCSRXEQ_LOCWREN;
2754	al_serdes_lane_write(
2755			obj, grp, lane, AL_SRDS_REG_TYPE_PMA,
2756			SERDES_IREG_FLD_PCSRXEQ_LOCWREN_REG_NUM,
2757			temp_val );
2758
2759
2760	/*
2761	 * Start/Stop RxEQ Cal is via PCSRXEQ_START: 1=START. 0=STOP.
2762	 * Clear Bit SERDES_IREG_FLD_PCSRXEQ_START
2763	 * to start fresh from Stop
2764	 */
2765	al_serdes_lane_read(
2766			obj, grp, lane, AL_SRDS_REG_TYPE_PMA,
2767			SERDES_IREG_FLD_PCSRXEQ_START_REG_NUM,
2768			&temp_val );
2769	temp_val &= ~SERDES_IREG_FLD_PCSRXEQ_START;
2770	al_serdes_lane_write(
2771			obj, grp, lane, AL_SRDS_REG_TYPE_PMA,
2772			SERDES_IREG_FLD_PCSRXEQ_START_REG_NUM,
2773			temp_val );
2774
2775	/* Set Bit SERDES_IREG_FLD_PCSRXEQ_START
2776	 * to begin Rx Eq Cal */
2777	temp_val |= SERDES_IREG_FLD_PCSRXEQ_START;
2778	al_serdes_lane_write(
2779			obj, grp, lane, AL_SRDS_REG_TYPE_PMA,
2780			SERDES_IREG_FLD_PCSRXEQ_START_REG_NUM,
2781			temp_val );
2782
2783	/* Poll on RxEq Cal completion. SERDES_IREG_FLD_RXEQ_DONE. 1=Done. */
2784	for( i = 0; i < AL_SERDES_RX_EQUAL_TRIES; ++i ) {
2785		al_serdes_lane_read(
2786				obj, grp, lane, AL_SRDS_REG_TYPE_PMA,
2787				SERDES_IREG_FLD_RXCALROAMEYEMEASDONE_REG_NUM,
2788				&done );
2789		done &= SERDES_IREG_FLD_RXEQ_DONE;
2790
2791		/* Check if RxEQ Cal is done */
2792		if (done)
2793			break;
2794		al_msleep(AL_SERDES_RX_EQUAL_MDELAY);
2795	}
2796
2797	if (!done) {
2798		al_err("%s: Timeout!\n", __func__);
2799		return -1;
2800	}
2801
2802	/* Stop the RxEQ process. */
2803	temp_val &= ~SERDES_IREG_FLD_PCSRXEQ_START;
2804	al_serdes_lane_write(
2805			obj, grp, lane, AL_SRDS_REG_TYPE_PMA,
2806			SERDES_IREG_FLD_PCSRXEQ_START_REG_NUM,
2807			temp_val );
2808	/* Get score */
2809	al_serdes_lane_read(
2810			obj, grp, lane, AL_SRDS_REG_TYPE_PMA,
2811			SERDES_IREG_RXEQ_BEST_EYE_MSB_VAL_REG_NUM,
2812			&temp_val );
2813	test_score = (int)( (temp_val & 0xFF) << 6 );
2814	al_serdes_lane_read(
2815			obj, grp, lane, AL_SRDS_REG_TYPE_PMA,
2816			SERDES_IREG_RXEQ_BEST_EYE_LSB_VAL_REG_NUM,
2817			&temp_val );
2818	test_score += (int)(temp_val & SERDES_IREG_RXEQ_BEST_EYE_LSB_VAL_MASK);
2819
2820	/* Restore start values */
2821	al_serdes_lane_write(
2822			obj, grp, lane, AL_SRDS_REG_TYPE_PMA,
2823			SERDES_IREG_FLD_RXCAL_LOCWREN_REG_NUM,
2824			serdes_ireg_fld_rxcal_locwren_val);
2825	al_serdes_lane_write(
2826			obj, grp, lane, AL_SRDS_REG_TYPE_PMA,
2827			SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN_REG_NUM,
2828			serdes_ireg_fld_rxcalroamyadjust_locwren_val );
2829	al_serdes_lane_write(
2830			obj, grp, lane, AL_SRDS_REG_TYPE_PMA,
2831			SERDES_IREG_FLD_RXROAM_XORBITSEL_REG_NUM,
2832			serdes_ireg_fld_rxroam_xorbitsel_val );
2833	al_serdes_lane_write(
2834			obj, grp, lane, AL_SRDS_REG_TYPE_PMA,
2835			SERDES_IREG_FLD_PCSRXEQ_LOCWREN_REG_NUM,
2836			serdes_ireg_fld_pcsrxeq_locwren_val );
2837
2838	return test_score;
2839}
2840
2841#if (	SERDES_IREG_FLD_RXCAL_LOCWREN_REG_NUM != \
2842		SERDES_IREG_FLD_RXCALROAMEYEMEASIN_LOCWREN_REG_NUM || \
2843	SERDES_IREG_FLD_RXCAL_LOCWREN_REG_NUM != \
2844		SERDES_IREG_FLD_RXCALROAMXADJUST_LOCWREN_REG_NUM || \
2845	SERDES_IREG_FLD_RXCAL_LOCWREN_REG_NUM != \
2846		SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_LOCWREN_REG_NUM)
2847#error Wrong assumption
2848#endif
2849int al_serdes_calc_eye_size(
2850		struct al_serdes_obj *obj,
2851		enum al_serdes_group grp,
2852		enum al_serdes_lane  lane,
2853		int*                 width,
2854		int*                 height)
2855{
2856	uint8_t rxcaleyediagfsm_x_y_valweight_val;
2857	uint8_t rxcaleyediagfsm_xvalcoarse_val;
2858	uint8_t rxcaleyediagfsm_xvalfine_val;
2859	uint8_t rxcaleyediagfsm_yvalcoarse_val;
2860	uint8_t rxcaleyediagfsm_yvalfine_val;
2861	uint8_t rxlock2ref_locwren_val;
2862	uint8_t rxcal_locwren_val;
2863	uint8_t rxcalroamyadjust_locwren_val;
2864	uint8_t rxlock2ref_ovren_val;
2865
2866	int i;
2867	uint8_t status;
2868	uint8_t reg_value;
2869
2870	/* Save Registers */
2871	al_serdes_lane_read(obj, grp, lane, AL_SRDS_REG_TYPE_PMA,
2872			SERDES_IREG_FLD_RXLOCK2REF_LOCWREN_REG_NUM,
2873			&rxlock2ref_locwren_val);
2874	al_serdes_lane_read(obj, grp, lane, AL_SRDS_REG_TYPE_PMA,
2875			SERDES_IREG_FLD_RXCAL_LOCWREN_REG_NUM,
2876			&rxcal_locwren_val);
2877	al_serdes_lane_read(obj, grp, lane, AL_SRDS_REG_TYPE_PMA,
2878			SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN_REG_NUM,
2879			&rxcalroamyadjust_locwren_val);
2880	al_serdes_lane_read(obj, grp, lane, AL_SRDS_REG_TYPE_PMA,
2881			SERDES_IREG_FLD_RXLOCK2REF_OVREN_REG_NUM,
2882			&rxlock2ref_ovren_val);
2883
2884	al_serdes_reg_read(obj, grp, AL_SRDS_REG_PAGE_4_COMMON,
2885			AL_SRDS_REG_TYPE_PMA,
2886			SERDES_IREG_FLD_RXCALEYEDIAGFSM_X_Y_VALWEIGHT_REG_NUM,
2887			&rxcaleyediagfsm_x_y_valweight_val);
2888	al_serdes_reg_read(obj, grp, AL_SRDS_REG_PAGE_4_COMMON,
2889			AL_SRDS_REG_TYPE_PMA,
2890			SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALCOARSE_REG_NUM,
2891			&rxcaleyediagfsm_xvalcoarse_val);
2892	al_serdes_reg_read(obj, grp, AL_SRDS_REG_PAGE_4_COMMON,
2893			AL_SRDS_REG_TYPE_PMA,
2894			SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALFINE_REG_NUM,
2895			&rxcaleyediagfsm_xvalfine_val);
2896	al_serdes_reg_read(obj, grp, AL_SRDS_REG_PAGE_4_COMMON,
2897			AL_SRDS_REG_TYPE_PMA,
2898			SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALCOARSE_REG_NUM,
2899			&rxcaleyediagfsm_yvalcoarse_val);
2900	al_serdes_reg_read(obj, grp, AL_SRDS_REG_PAGE_4_COMMON,
2901			AL_SRDS_REG_TYPE_PMA,
2902			SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALFINE_REG_NUM,
2903			&rxcaleyediagfsm_yvalfine_val);
2904
2905	/*
2906	 * Clear Bit:
2907	 * 	SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_LOCWREN
2908	 * 	to override RxEQ via PMA
2909	 * Set Bits:
2910	 * 	SERDES_IREG_FLD_RXCALROAMEYEMEASIN_LOCWREN,
2911	 * 	SERDES_IREG_FLD_RXCALROAMXADJUST_LOCWREN
2912	 * 	to keep Eye Diag Roam controlled internally
2913	 */
2914	al_serdes_grp_lane_masked_write(&obj->grp_info[grp],
2915			lane,
2916			AL_SRDS_REG_TYPE_PMA,
2917			SERDES_IREG_FLD_RXCAL_LOCWREN_REG_NUM,
2918			SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_LOCWREN  |
2919			SERDES_IREG_FLD_RXCALROAMEYEMEASIN_LOCWREN |
2920			SERDES_IREG_FLD_RXCALROAMXADJUST_LOCWREN,
2921			SERDES_IREG_FLD_RXCALROAMEYEMEASIN_LOCWREN |
2922			SERDES_IREG_FLD_RXCALROAMXADJUST_LOCWREN);
2923	/*
2924	 * Set Bit:
2925	 * 	 SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN
2926	 * 	 to keep Eye Diag Roam controlled internally
2927	 */
2928	al_serdes_grp_lane_masked_write(&obj->grp_info[grp],
2929			lane,
2930			AL_SRDS_REG_TYPE_PMA,
2931			SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN_REG_NUM,
2932			SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN,
2933			SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN);
2934
2935	/*
2936	 * Clear Bit:
2937	 * 	SERDES_IREG_FLD_RXROAM_XORBITSEL,
2938	 * 	so XORBITSEL=0, needed for the Eye mapping
2939	 *  Set Bit:
2940	 *  SERDES_IREG_FLD_RXLOCK2REF_OVREN,
2941	 *  so RXLOCK2REF_OVREN=1, keeping lock to data, preventing data hit
2942	 */
2943	al_serdes_grp_lane_masked_write(&obj->grp_info[grp],
2944			lane,
2945			AL_SRDS_REG_TYPE_PMA,
2946			SERDES_IREG_FLD_RXROAM_XORBITSEL_REG_NUM,
2947			SERDES_IREG_FLD_RXLOCK2REF_OVREN |
2948			SERDES_IREG_FLD_RXROAM_XORBITSEL,
2949			SERDES_IREG_FLD_RXLOCK2REF_OVREN);
2950
2951
2952	/*
2953	 * Clear Bit:
2954	 * 	SERDES_IREG_FLD_RXLOCK2REF_LOCWREN,
2955	 * 	so RXLOCK2REF_LOCWREN=0, to override control
2956	 */
2957	al_serdes_grp_lane_masked_write(&obj->grp_info[grp],
2958				lane,
2959				AL_SRDS_REG_TYPE_PMA,
2960				SERDES_IREG_FLD_RXLOCK2REF_LOCWREN_REG_NUM,
2961				SERDES_IREG_FLD_RXLOCK2REF_LOCWREN,
2962				0);
2963
2964	/* Width Calculation */
2965
2966	/* Return Value = 0*Y + 1*X */
2967	al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON,
2968			AL_SRDS_REG_TYPE_PMA,
2969			SERDES_IREG_FLD_RXCALEYEDIAGFSM_X_Y_VALWEIGHT_REG_NUM,
2970			0x01);
2971	/* X coarse scan step = 3 */
2972	al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON,
2973			AL_SRDS_REG_TYPE_PMA,
2974			SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALCOARSE_REG_NUM,
2975			0x03);
2976	/* X fine scan step = 1   */
2977	al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON,
2978			AL_SRDS_REG_TYPE_PMA,
2979			SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALFINE_REG_NUM,
2980			0x01);
2981	/* Y coarse scan step = 0 */
2982	al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON,
2983			AL_SRDS_REG_TYPE_PMA,
2984			SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALCOARSE_REG_NUM,
2985			0x00);
2986	/* Y fine scan step = 0   */
2987	al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON,
2988			AL_SRDS_REG_TYPE_PMA,
2989			SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALFINE_REG_NUM,
2990			0x00);
2991
2992	/*
2993	 * Set Bit:
2994	 * 	SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START,
2995	 * 	to start Eye measurement
2996	 */
2997	al_serdes_grp_lane_masked_write(&obj->grp_info[grp],
2998				lane,
2999				AL_SRDS_REG_TYPE_PMA,
3000				SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START_REG_NUM,
3001				SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START,
3002				SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START);
3003
3004	for( i = 0; i < AL_SERDES_RX_EYE_CAL_TRIES; ++i ) {
3005		/* Check if RxEQ Cal is done */
3006		al_serdes_lane_read(
3007				obj, grp, lane, AL_SRDS_REG_TYPE_PMA,
3008				SERDES_IREG_FLD_RXCALEYEDIAGFSM_DONE_REG_NUM,
3009				&status );
3010		if (status & SERDES_IREG_FLD_RXCALEYEDIAGFSM_DONE)
3011			break;
3012		al_msleep(AL_SERDES_RX_EYE_CAL_MDELAY);
3013	}
3014
3015	if (status & SERDES_IREG_FLD_RXCALEYEDIAGFSM_ERR) {
3016		al_err("%s: eye measure error!\n", __func__);
3017		return -1;
3018	}
3019
3020	if (!(status & SERDES_IREG_FLD_RXCALEYEDIAGFSM_DONE)) {
3021		al_err("%s: eye measure timeout!\n", __func__);
3022		return -1;
3023	}
3024
3025	/*  Read Eye Opening Metrics, Bits:
3026	 * 	SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_LSB,
3027	 * 	SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_LSB
3028	 */
3029	al_serdes_lane_read(
3030			obj, grp, lane, AL_SRDS_REG_TYPE_PMA,
3031			SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_MSB_REG_NUM,
3032			&reg_value );
3033	*width = reg_value << 6;
3034	al_serdes_lane_read(
3035			obj, grp, lane, AL_SRDS_REG_TYPE_PMA,
3036			SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_LSB_REG_NUM,
3037			&reg_value );
3038	*width =+ reg_value & SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_LSB_MAKE;
3039
3040	/*
3041	 * Clear Bit:
3042	 * 	SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START,
3043	 * 	to stop Eye measurement
3044	 */
3045	al_serdes_grp_lane_masked_write(&obj->grp_info[grp],
3046				lane,
3047				AL_SRDS_REG_TYPE_PMA,
3048				SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START_REG_NUM,
3049				SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START,
3050				0);
3051
3052	/* Height Calculation */
3053
3054	/* Return Value = 1*Y + 0*X */
3055	al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON,
3056			AL_SRDS_REG_TYPE_PMA,
3057			SERDES_IREG_FLD_RXCALEYEDIAGFSM_X_Y_VALWEIGHT_REG_NUM,
3058			0x10);
3059	/* X coarse scan step = 0 */
3060	al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON,
3061			AL_SRDS_REG_TYPE_PMA,
3062			SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALCOARSE_REG_NUM,
3063			0x00);
3064	/* X fine scan step = 0   */
3065	al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON,
3066			AL_SRDS_REG_TYPE_PMA,
3067			SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALFINE_REG_NUM,
3068			0x00);
3069	/* Y coarse scan step = 3 */
3070	al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON,
3071			AL_SRDS_REG_TYPE_PMA,
3072			SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALCOARSE_REG_NUM,
3073			0x03);
3074	/* Y fine scan step = 1   */
3075	al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON,
3076			AL_SRDS_REG_TYPE_PMA,
3077			SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALFINE_REG_NUM,
3078			0x01);
3079
3080	/*
3081	 * Set Bit:
3082	 * 	SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START,
3083	 * 	to start Eye measurement
3084	 */
3085	al_serdes_grp_lane_masked_write(&obj->grp_info[grp],
3086				lane,
3087				AL_SRDS_REG_TYPE_PMA,
3088				SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START_REG_NUM,
3089				SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START,
3090				SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START);
3091
3092	for( i = 0; i < AL_SERDES_RX_EYE_CAL_TRIES; ++i ) {
3093		/* Check if RxEQ Cal is done */
3094		al_serdes_lane_read(
3095				obj, grp, lane, AL_SRDS_REG_TYPE_PMA,
3096				SERDES_IREG_FLD_RXCALEYEDIAGFSM_DONE_REG_NUM,
3097				&status );
3098		if (status & SERDES_IREG_FLD_RXCALEYEDIAGFSM_DONE)
3099			break;
3100		al_msleep(AL_SERDES_RX_EYE_CAL_MDELAY);
3101	}
3102
3103	if (status & SERDES_IREG_FLD_RXCALEYEDIAGFSM_ERR) {
3104		al_err("%s: eye measure error!\n", __func__);
3105		return -1;
3106	}
3107
3108	if (!(status & SERDES_IREG_FLD_RXCALEYEDIAGFSM_DONE)) {
3109		al_err("%s: eye measure timeout!\n", __func__);
3110		return -1;
3111	}
3112
3113	/*  Read Eye Opening Metrics, Bits:
3114	 * 	SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_LSB,
3115	 * 	SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_LSB
3116	 */
3117	al_serdes_lane_read(
3118			obj, grp, lane, AL_SRDS_REG_TYPE_PMA,
3119			SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_MSB_REG_NUM,
3120			&reg_value );
3121	*height = reg_value << 6;
3122	al_serdes_lane_read(
3123			obj, grp, lane, AL_SRDS_REG_TYPE_PMA,
3124			SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_LSB_REG_NUM,
3125			&reg_value );
3126	*height =+ reg_value & SERDES_IREG_FLD_RXCALEYEDIAGFSM_EYESUM_LSB_MAKE;
3127
3128	/*
3129	 * Clear Bit:
3130	 * 	SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START,
3131	 * 	to stop Eye measurement
3132	 */
3133	al_serdes_grp_lane_masked_write(&obj->grp_info[grp],
3134				lane,
3135				AL_SRDS_REG_TYPE_PMA,
3136				SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START_REG_NUM,
3137				SERDES_IREG_FLD_RXCALEYEDIAGFSMIN_START,
3138				0);
3139
3140	/* Restore Registers */
3141	al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON,
3142			AL_SRDS_REG_TYPE_PMA,
3143			SERDES_IREG_FLD_RXCALEYEDIAGFSM_X_Y_VALWEIGHT_REG_NUM,
3144			rxcaleyediagfsm_x_y_valweight_val);
3145	al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON,
3146			AL_SRDS_REG_TYPE_PMA,
3147			SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALCOARSE_REG_NUM,
3148			rxcaleyediagfsm_xvalcoarse_val);
3149	al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON,
3150			AL_SRDS_REG_TYPE_PMA,
3151			SERDES_IREG_FLD_RXCALEYEDIAGFSM_XVALFINE_REG_NUM,
3152			rxcaleyediagfsm_xvalfine_val);
3153	al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON,
3154			AL_SRDS_REG_TYPE_PMA,
3155			SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALCOARSE_REG_NUM,
3156			rxcaleyediagfsm_yvalcoarse_val);
3157	al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON,
3158			AL_SRDS_REG_TYPE_PMA,
3159			SERDES_IREG_FLD_RXCALEYEDIAGFSM_YVALFINE_REG_NUM,
3160			rxcaleyediagfsm_yvalfine_val);
3161
3162	al_serdes_lane_write(obj, grp, lane, AL_SRDS_REG_TYPE_PMA,
3163			SERDES_IREG_FLD_RXLOCK2REF_LOCWREN_REG_NUM,
3164			rxlock2ref_locwren_val);
3165	al_serdes_lane_write(obj, grp, lane, AL_SRDS_REG_TYPE_PMA,
3166			SERDES_IREG_FLD_RXCAL_LOCWREN_REG_NUM,
3167			rxcal_locwren_val);
3168	al_serdes_lane_write(obj, grp, lane, AL_SRDS_REG_TYPE_PMA,
3169			SERDES_IREG_FLD_RXCALROAMYADJUST_LOCWREN_REG_NUM,
3170			rxcalroamyadjust_locwren_val);
3171	al_serdes_lane_write(obj, grp, lane, AL_SRDS_REG_TYPE_PMA,
3172			SERDES_IREG_FLD_RXLOCK2REF_OVREN_REG_NUM,
3173			rxlock2ref_ovren_val);
3174	return 0;
3175}
3176
3177void al_serdes_sris_config(
3178	struct al_serdes_obj		*obj,
3179	enum al_serdes_group		grp,
3180	struct al_serdes_sris_params	*params)
3181{
3182	struct al_serdes_group_info *grp_info = &obj->grp_info[grp];
3183
3184	al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA,
3185		SERDES_IREG_FLD_PPMDRIFTCOUNT1_REG_NUM,
3186		(params->ppm_drift_count & AL_FIELD_MASK(7, 0)) >> 0);
3187	al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA,
3188		SERDES_IREG_FLD_PPMDRIFTCOUNT2_REG_NUM,
3189		(params->ppm_drift_count & AL_FIELD_MASK(15, 8)) >> 8);
3190
3191	al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA,
3192		SERDES_IREG_FLD_PPMDRIFTMAX1_REG_NUM,
3193		(params->ppm_drift_max & AL_FIELD_MASK(7, 0)) >> 0);
3194	al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA,
3195		SERDES_IREG_FLD_PPMDRIFTMAX2_REG_NUM,
3196		(params->ppm_drift_max & AL_FIELD_MASK(15, 8)) >> 8);
3197
3198	al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA,
3199		SERDES_IREG_FLD_SYNTHPPMDRIFTMAX1_REG_NUM,
3200		(params->synth_ppm_drift_max & AL_FIELD_MASK(7, 0)) >> 0);
3201	al_serdes_reg_write(obj, grp, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PMA,
3202		SERDES_IREG_FLD_SYNTHPPMDRIFTMAX2_REG_NUM,
3203		(params->synth_ppm_drift_max & AL_FIELD_MASK(15, 8)) >> 8);
3204
3205	al_serdes_grp_reg_masked_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PCS,
3206		SERDES_IREG_FLD_PCS_EBUF_FULL_D2R1_REG_NUM,
3207		SERDES_IREG_FLD_PCS_EBUF_FULL_D2R1_REG_MASK,
3208		(params->full_d2r1)
3209			<< SERDES_IREG_FLD_PCS_EBUF_FULL_D2R1_REG_SHIFT);
3210
3211	al_serdes_grp_reg_masked_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PCS,
3212		SERDES_IREG_FLD_PCS_EBUF_FULL_PCIE_G3_REG_NUM,
3213		SERDES_IREG_FLD_PCS_EBUF_FULL_PCIE_G3_REG_MASK,
3214		(params->full_pcie_g3)
3215			<< SERDES_IREG_FLD_PCS_EBUF_FULL_PCIE_G3_REG_SHIFT);
3216
3217	al_serdes_grp_reg_masked_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PCS,
3218		SERDES_IREG_FLD_PCS_EBUF_RD_THRESHOLD_D2R1_REG_NUM,
3219		SERDES_IREG_FLD_PCS_EBUF_RD_THRESHOLD_D2R1_REG_MASK,
3220		(params->rd_threshold_d2r1)
3221			<< SERDES_IREG_FLD_PCS_EBUF_RD_THRESHOLD_D2R1_REG_SHIFT);
3222
3223	al_serdes_grp_reg_masked_write(grp_info, AL_SRDS_REG_PAGE_4_COMMON, AL_SRDS_REG_TYPE_PCS,
3224		SERDES_IREG_FLD_PCS_EBUF_RD_THRESHOLD_PCIE_G3_REG_NUM,
3225		SERDES_IREG_FLD_PCS_EBUF_RD_THRESHOLD_PCIE_G3_REG_MASK,
3226		(params->rd_threshold_pcie_g3)
3227			<< SERDES_IREG_FLD_PCS_EBUF_RD_THRESHOLD_PCIE_G3_REG_SHIFT);
3228}
3229