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