1 /*******************************************************************************
2 * Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions.
3 *
4 * SPDX-License-Identifier: MIT
5 *
6 * MPFS HAL Embedded Software
7 *
8 */
9
10 /*******************************************************************************
11 * @file mss_sgmii.c
12 * @author Microchip-FPGA Embedded Systems Solutions
13 * @brief sgmii related functions
14 *
15 */
16
17 #include <string.h>
18 #include <stdio.h>
19 #include "mpfs_hal/mss_hal.h"
20 #include "simulation.h"
21
22 #ifdef MPFS_HAL_HW_CONFIG
23
24 static PART_TYPE silicon_variant = PART_NOT_DETERMINED;
25
26 /*
27 * local functions
28 */
29 static void setup_sgmii_rpc_per_config(void);
30 #ifdef SGMII_SUPPORT
31 static uint32_t sgmii_channel_setup(void);
32 #endif
33
34 /*
35 * local variable
36 */
37 static uint32_t sro_dll_90_code;
38
39 /*
40 * local functions
41 */
42 static void set_early_late_thresholds(uint8_t n_late_threshold, uint8_t p_early_threshold);
43
44 /*
45 * extern functions
46 */
47 extern void sgmii_mux_config(uint8_t option);
48
49
sgmii_setup(void)50 uint32_t sgmii_setup(void)
51 {
52 #ifdef SGMII_SUPPORT
53 /*
54 * Check if any tx/Rx channels enabled
55 */
56 if((LIBERO_SETTING_SGMII_MODE & (TX_RX_CH_EN_MASK<<TX_RX_CH_EN_OFFSET)) != 0U)
57 {
58 while (sgmii_channel_setup() != 0)
59 {
60
61 }
62 }
63 else
64 {
65 sgmii_off_mode();
66 sgmii_mux_config(RPC_REG_UPDATE);
67 }
68 #else
69 {
70 sgmii_off_mode();
71 sgmii_mux_config(RPC_REG_UPDATE);
72 }
73 #endif
74 return(0UL);
75 }
76
77
78 /**
79 *
80 * @param sgmii_instruction
81 * @return
82 */
83 #ifdef SGMII_SUPPORT
sgmii_channel_setup(void)84 static uint32_t sgmii_channel_setup(void)
85 {
86 static SGMII_TRAINING_SM sgmii_training_state = SGMII_SETUP_INIT;
87 static uint32_t status = SGMII_IN_SETUP;
88 static uint32_t timer_out;
89
90 /*
91 * Initialise NWC
92 * Clocks
93 * SGMII
94 * DDR
95 * IOMUX
96 */
97
98 switch(sgmii_training_state)
99 {
100 case SGMII_SETUP_INIT:
101 status = SGMII_IN_SETUP;
102 CFG_DDR_SGMII_PHY->SOFT_RESET_SGMII.SOFT_RESET_SGMII = \
103 (0x01 << 8U) | 1U; /* PERIPH soft reset */
104 CFG_DDR_SGMII_PHY->SOFT_RESET_SGMII.SOFT_RESET_SGMII = 1U;
105 setup_sgmii_rpc_per_config(); /* load RPC SGMII_MODE register ext */
106
107 /* Enable the Bank controller */
108 /*
109 * Set soft reset on IP to load RPC to SCB regs (dynamic mode)
110 * Bring the sgmii bank controller out of reset =- ioscb_bank_ctrl_sgmii
111 */
112 IOSCB_BANK_CNTL_SGMII->soft_reset = 1U; /* DPC_BITS NV_MAP reset */
113 sgmii_training_state = SGMII_IO_EN;
114 break;
115
116 case SGMII_IO_EN:
117 /*
118 * Check the IO_EN signal here.
119 * This is an output from the bank controller power detector, which are
120 * turned on using MSS_IO_EN
121 */
122 /* aro_ioen_bnk - PVT calibrator IOEN */
123 timer_out++;
124 if((CFG_DDR_SGMII_PHY->PVT_STAT.PVT_STAT & (0x01U<<6U)) != 0U)
125 {
126 timer_out=0U;
127 sgmii_training_state = SGMII_RAMP_TIMER;
128 }
129 break;
130
131 case SGMII_RAMP_TIMER:
132 /*
133 * IO power ramp wait time
134 * After IOEN is received from power detectors DDR and SGMii, extra time
135 * required for voltage to ramp.
136 * This time will come from the user- Dependent on ramp time of power
137 * supply
138 * Approximately - Bank power timer (from ioen_in to ioen_out = 10uS)?
139 *
140 */
141 timer_out++;
142 if(timer_out >= 0xFU)
143 {
144 timer_out=0U;
145 sgmii_training_state = SGMII_IO_SETUP;
146 }
147 break;
148
149 case SGMII_IO_SETUP:
150 /*
151 * fixme- not sure if we should be setting this register
152 * From regmap detail:
153 * bit 8 of MSS_RESET_CR
154 * Asserts a reset the SGMII block containing the MSS reference clock
155 * input.
156 * Warning that setting this bit causes the external reference clock
157 * input to the
158 * MSS PLL to disappear.
159 * It is advisable to use the SGMII channel soft resets in the PHY
160 * instead of this bit.
161 * However if E51 software wants to set this bit, the MSS clock source
162 * should be switched over to the standby source in advance.
163 */
164 SCB_REGS->MSS_RESET_CR.MSS_RESET_CR = 0;
165
166 /*
167 * I ran the sim past the place where we set the nvmap_reset in the
168 * SOFT_RESET_SGMII register and it did not result in any
169 * change from the DLL default bits.
170 * But I traced the 'flashing' signal on one of these regs back to
171 * 'dll0_soft_reset_nv_map' (not 'pll0_soft_reset_periph').
172 * Now the only place I can find 'dll0_soft_reset_nv_map' is in SCB
173 * space...ie 0x3e10_0000 SOFT_RESET register.
174 *
175 */
176 /*
177 * so we have to use scb register to reset as no APB register available
178 * to soft reset the IP
179 * ioscb_dll_sgmii
180 * */
181 IOSCB_DLL_SGMII->soft_reset = (0x01U << 0x00U); /* reset sgmii DLL */
182
183 /*
184 * I have discovered the problem with the tx channels (soft reset issue)
185 * So we require the:
186 *
187 * sgmiiphy_lane 01 soft-reset register (0x3650_0000) to be written to
188 * with 0x1 (to set the nv_map bit[0] =1 (self clears))
189 * same for sgmiiphy_lane 23 soft-reset register (0x3651_0000).
190 *
191 * This will result in the rpc bits for the Lane controls to get loaded.
192 * Not happening currently.
193 *
194 * The soft_reset_sgmii occurs in the mss_ddr.c line 436, so I suppose
195 * we put the 2 new soft reset writes after that.
196 *
197 */
198 {
199 /* sgmiiphy_lane 01 soft-reset register (0x3650_0000) */
200 SGMIIPHY_LANE01->soft_reset = 0x000000001U;
201 /* sgmiiphy_lane 23 soft-reset register (0x3650_0000) */
202 SGMIIPHY_LANE23->soft_reset = 0x000000001U;
203 }
204
205 /*
206 * Kick-off calibration, by taking calibration IP out of reset
207 */
208 /*
209 * Soft reset
210 */
211 {
212 /* PVT soft reset - APB*/
213 /* reg_pvt_soft_reset_periph */
214 CFG_DDR_SGMII_PHY->DYN_CNTL.DYN_CNTL = (0x01U<< 10U) | (0x7FU<<0U);
215 /* reg_pvt_soft_reset_periph */
216 CFG_DDR_SGMII_PHY->DYN_CNTL.DYN_CNTL = (0x7FU<<0U);
217 /* PVT soft reset - SCB */
218 /* make sure out of reset */
219 IOSCB_IO_CALIB_SGMII->SOFT_RESET_IOCALIB = 0x1U;
220 /* make sure out of reset */
221 IOSCB_IO_CALIB_SGMII->SOFT_RESET_IOCALIB = 0x0U;
222 }
223 sgmii_training_state = SGMII_WAIT_FOR_CALIB_COMPLETE;
224 break;
225
226 case SGMII_WAIT_FOR_CALIB_COMPLETE:
227 /*
228 * Verify calibration
229 * Bank 5 PVT calibrator can be controlled by MSS firmware through APB
230 * registers to do initial calibration and re-calibration. During startup,
231 * the initial calibration can be started by default when MSS releases SGMII
232 * reset. Re-calibration is enabled by default with reg_pvt_calib_start/lock
233 * bits being set to 1 before startup, and MSS firmware can start
234 * re-calibration after startup by toggling pvt_calib_start/lock bits per
235 * PVT calibrator spec.
236 *
237 */
238 if((CFG_DDR_SGMII_PHY->PVT_STAT.PVT_STAT & (1U << 14U)) == (1U << 14U))
239 {
240 sgmii_training_state = SGMII_ASSERT_CALIB_LOCK;
241 }
242 break;
243
244 case SGMII_ASSERT_CALIB_LOCK:
245 /*
246 * now assert calib lock
247 * calibrated pcode and ncode will be written.
248 * */
249
250 CFG_DDR_SGMII_PHY->PVT_STAT.PVT_STAT |= 0x40000000UL;
251 IOSCB_IO_CALIB_SGMII->IOC_REG0 |= (0x01U<<14U);
252 sgmii_training_state = SGMII_SET_UP_PLL;
253 break;
254
255 case SGMII_SET_UP_PLL:
256 /*
257 * SGMii Step 3) Wait for PLL and DLL lock
258 * Delay codes generated
259 */
260
261 /* 0U => configure using scb, 1U => NVMAP reset */
262 sgmii_mux_config(RPC_REG_UPDATE);
263 /* 0U => configure using scb, 1U => NVMAP reset */
264 sgmii_pll_config_scb(RPC_REG_UPDATE);
265
266 timer_out=0U;
267 sgmii_training_state = SGMII_WAIT_FOR_MSS_LOCK;
268 break;
269
270 case SGMII_WAIT_FOR_MSS_LOCK:
271 if (CFG_DDR_SGMII_PHY->PLL_CNTL.PLL_CNTL & (1U<<7U))
272 {
273 sgmii_training_state = SGMII_WAIT_FOR_DLL_LOCK;
274 }
275 break;
276
277 case SGMII_WAIT_FOR_DLL_LOCK:
278 if (CFG_DDR_SGMII_PHY->RECAL_CNTL.RECAL_CNTL & (1U<<23U))
279 {
280 sgmii_training_state = SGMII_TURN_ON_MACS;
281 }
282 break;
283
284 case SGMII_TURN_ON_MACS:
285 /*
286 * Provide mac clocks
287 * The nw_config register for mac0 (0x2011_0004): I am forcing 'gigabit' and
288 * 'tbi' bits = 11.
289 * The same for Mac1.
290 * This starts up the tx_mac_clocks for the 2 macs.
291 *
292 */
293 /* the mac clocks need to be turned on when setting up the sgmii */
294 (void)mss_config_clk_rst(MSS_PERIPH_MAC0, (uint8_t) MPFS_HAL_FIRST_HART, PERIPHERAL_ON);
295 (void)mss_config_clk_rst(MSS_PERIPH_MAC0, (uint8_t) MPFS_HAL_FIRST_HART, PERIPHERAL_ON);
296 GEM_A_LO->network_config |= (0x01U << 10U) | (0x01U << 11U); /* GEM0 */
297 GEM_B_LO->network_config |= (0x01U << 10U) | (0x01U << 11U); /* GEM1 */
298 sgmii_training_state = SGMII_DETERMINE_SILICON_VARIANT;
299 break;
300
301 case SGMII_DETERMINE_SILICON_VARIANT:
302 /*
303 * Determine Silicon variant from generated dll generated sro_dll_90_code
304 */
305 sro_dll_90_code = ((CFG_DDR_SGMII_PHY->RECAL_CNTL.RECAL_CNTL >> 16U) & 0x7FU);
306
307 if(CFG_DDR_SGMII_PHY->SPARE_STAT.SPARE_STAT & (01U<<31U)) /* bit31 == 1 => post rev B silicon */
308 {
309 silicon_variant = PART_REVC_OR_LATER;
310 set_early_late_thresholds(LATE_EYE_WIDTH_PART_REVC_OR_LATER_PRE_TEST, EARLY_EYE_WIDTH_PART_REVC_OR_LATER_PRE_TEST);
311 }
312 else
313 {
314 /*
315 * SS part expect < 13
316 * typical-typical or FF expect > 13
317 */
318 if(sro_dll_90_code < MIN_DLL_90_CODE_VALUE_INDICATING_TT_PART_REVB) /* SS part */
319 {
320 silicon_variant = SS_PART_REVB;
321 set_early_late_thresholds(LATE_EYE_WIDTH_SS_PART_REVB, EARLY_EYE_WIDTH_SS_PART_REVB);
322 }
323 else
324 {
325 silicon_variant = TT_PART_REVB;
326 set_early_late_thresholds(LATE_TT_PART_REVB, EARLY_TT_PART_REVB);
327 }
328 }
329 sgmii_training_state = SGMII_RESET_CHANNELS;
330 break;
331
332 case SGMII_RESET_CHANNELS:
333 /*
334 * DLL soft reset - Already configured
335 * PVT soft reset - Already configured
336 * Bank controller soft reset - Already configured
337 * CLKMUX soft reset - Already configured
338 * Lane0 soft reset - must be soft reset here
339 * Lane1 soft reset - must be soft reset here
340 *
341 * __IO uint32_t reg_lane0_soft_reset_periph :1; bit 13
342 * __IO uint32_t reg_lane1_soft_reset_periph :1; bit 14
343 */
344 CFG_DDR_SGMII_PHY->DYN_CNTL.DYN_CNTL = (1U << 14U)|(1U << 13U)|(0x7FU<<0U);
345 CFG_DDR_SGMII_PHY->DYN_CNTL.DYN_CNTL = (0U << 14U)|(0U << 13U)|(0x7FU<<0U);
346 if(silicon_variant == PART_REVC_OR_LATER)
347 {
348 timer_out=0U;
349 sgmii_training_state = SGMII_WAIT_10MS;
350 }
351 else
352 {
353 sgmii_training_state = SGMII_CHANNELS_UP;
354 }
355 break;
356
357 case SGMII_WAIT_10MS:
358 timer_out++;
359 if(timer_out >= 0xFFFU)
360 {
361 timer_out=0U;
362 sgmii_training_state = SGMII_CHECK_REVC_RESULT;
363 }
364 break;
365
366 case SGMII_CHECK_REVC_RESULT:
367 if ( (CFG_DDR_SGMII_PHY->SPARE_STAT.SPARE_STAT & ARO_REF_PCODE_MASK) > ARO_REF_PCODE_REVC_THRESHOLD )
368 {
369 /* OK, we are good */
370 sgmii_training_state = SGMII_CHANNELS_UP;
371 }
372 else
373 {
374 /* need to adjust eye values */
375 set_early_late_thresholds(LATE_EYE_WIDTH_PART_REVC_OR_LATER, EARLY_EYE_WIDTH_PART_REVC_OR_LATER);
376 /*
377 * Now reset the channels
378 */
379 CFG_DDR_SGMII_PHY->DYN_CNTL.DYN_CNTL = (1U << 14U)|(1U << 13U)|(0x7FU<<0U);
380 CFG_DDR_SGMII_PHY->DYN_CNTL.DYN_CNTL = (0U << 14U)|(0U << 13U)|(0x7FU<<0U);
381 /* OK, we are good */
382 sgmii_training_state = SGMII_CHANNELS_UP;
383 }
384 break;
385
386 case SGMII_CHANNELS_UP:
387 /*
388 * SGMii Step 4) Monitor the DLL codes for Voltage and Temp variation
389 * MSS E51 software sets the magnitude value of variation to flag.
390 * MSS E51 software can poll this flag.
391 * Re-calibration, if needed, is controlled by E51 software if needed.
392 * ML step 4- This is a monitoring step- to be run constantly in the back
393 * ground
394 */
395 status = SGMII_FINISHED_SETUP;
396 break;
397 } /* end of switch statement */
398
399 return(status);
400 }
401 #endif
402
403 /**
404 * setup_sgmii_rpc_per_config
405 * Configures SGMII RPC TIP registers
406 */
setup_sgmii_rpc_per_config(void)407 static void setup_sgmii_rpc_per_config(void)
408 {
409 CFG_DDR_SGMII_PHY->SGMII_MODE.SGMII_MODE = (LIBERO_SETTING_SGMII_MODE & ~REG_CDR_MOVE_STEP);
410 CFG_DDR_SGMII_PHY->CH0_CNTL.CH0_CNTL = LIBERO_SETTING_CH0_CNTL;
411 CFG_DDR_SGMII_PHY->CH1_CNTL.CH1_CNTL = LIBERO_SETTING_CH1_CNTL;
412 CFG_DDR_SGMII_PHY->RECAL_CNTL.RECAL_CNTL = LIBERO_SETTING_RECAL_CNTL;
413 CFG_DDR_SGMII_PHY->CLK_CNTL.CLK_CNTL = LIBERO_SETTING_CLK_CNTL;
414 /* ibuffmx_p and _n rx1, bit 22 and 23 , rx0, bit 20 and 21 */
415 CFG_DDR_SGMII_PHY->SPARE_CNTL.SPARE_CNTL = LIBERO_SETTING_SPARE_CNTL;
416 CFG_DDR_SGMII_PHY->PLL_CNTL.PLL_CNTL = LIBERO_SETTING_PLL_CNTL;
417 }
418
419 /**
420 * SGMII Off mode
421 */
sgmii_off_mode(void)422 void sgmii_off_mode(void)
423 {
424 /*
425 * do soft reset of SGMII TIP
426 */
427 CFG_DDR_SGMII_PHY->SOFT_RESET_SGMII.SOFT_RESET_SGMII = (0x01 << 8U) | 1U;
428 CFG_DDR_SGMII_PHY->SOFT_RESET_SGMII.SOFT_RESET_SGMII = 1U;
429
430 /*
431 *
432 */
433 setup_sgmii_rpc_per_config();
434
435 /*
436 * Resetting the SCB register only required in already in dynamic mode. If
437 * not reset, IO will not be configured.
438 */
439 IOSCB_DLL_SGMII->soft_reset = (0x01U << 0x00U); /* reset sgmii */
440
441 }
442
443 /**
444 *
445 */
ddr_pvt_calibration(void)446 void ddr_pvt_calibration(void)
447 {
448 /*
449 * R3.1
450 * PVT calibration
451 * Wait for IOEN from power detectors DDR and SGMII - IO enable signal from
452 * System Control powers on
453 *
454 * From DDR phy SAC spec:
455 * MSS processor releases dce bus to send RPC bits to IO buffer,
456 * setting each to it's programmed mode and then asserts
457 * ioen high at end of this state.
458 *
459 *
460 * Following verification required for MSS IO Calibration (DDRPHY,
461 * SGMII and MSSIO)
462 * Auto-calibration supply ramp time settings
463 * Calibration in reset until ioen_bnk goes high, timer complete
464 * and setup of bits complete
465 * scbclk divider setting (/1)
466 * calibration clkdiv setting
467 * VS bit settings
468 * Initial non-calibrated codes to IOs (functional max codes)
469 * Calibration signal transitions
470 * pvt_calib_status , r in reg DYN_CNTL
471 * reg_calib_reset, w/r in reg IOC_REG6
472 * calib_clkdiv, w/r in reg IOC_REG6
473 * soft_reset_periph_b,
474 * calib_lock, w/r in reg IOC_REG0
475 * calib_start, w/r in reg IOC_REG0
476 * calib_intrpt r in reg
477 * Final calibration codes
478 * Lane latching of codes
479 * IO Glitching
480 */
481 volatile uint32_t timer_out=0U;
482
483 #ifndef RENODE_DEBUG
484 /* sro_ioen_out */
485 while((CFG_DDR_SGMII_PHY->IOC_REG1.IOC_REG1 & (1U<<4U)) == 0U)
486 {
487 timer_out++;
488 /*todo: add a fail break */
489 }
490 #endif
491
492 /*
493 * R3.2 Trigger timer and wait for completion
494 * PVT calibration
495 * After IOEN is received from power detectors DDR and SGMII, extra time
496 * required for voltage to ramp.
497 * This time will come from the user- Dependent on ramp time of power supply
498 * Approximately - Bank power timer (from ioen_in to ioen_out = 10uS)?
499 *
500 */
501 /*todo: implement proper timer- user will supply ramp time */
502 timer_out=0U;
503 while(timer_out < 0xFU)
504 {
505 timer_out++;
506 }
507
508 /*
509 * R3.2 Initiate calibration:
510 *
511 * IOC_REG6
512 * bit 2:1 reg_calib_clkdiv
513 * bit 0 reg_calib_reset
514 *
515 * DDRIO: calib_reset: 1 -> 0
516 * mss_write(0x20007000 + 0x21C,0x00000004);
517 * DDRIO: calib_rst_b: 0 -> 1
518 * mss_write(0x20007000 + 0x220,0x00000000);
519 * SGMII: calib_rst_b: 0 -> 1
520 * mss_write(0x20007000 + 0xC1C,0x00000000);
521 *
522 */
523 /*
524 * Soft reset
525 */
526 /* PVT soft reset - APB*/
527 /* DDRIO: calib_reset: 1 -> 0, clk divider changed - from 2 - to 3 */
528 CFG_DDR_SGMII_PHY->IOC_REG6.IOC_REG6 = 0x00000006U;
529
530 /* PVT soft nv reset - SCB, should load from RPC */
531 IOSCB_IO_CALIB_DDR->SOFT_RESET_IOCALIB = 0x1U; /* make sure reset */
532 IOSCB_IO_CALIB_DDR->SOFT_RESET_IOCALIB = 0x0U; /* make sure reset */
533
534 /*
535 * R3.4 Wait for PVT calibration to complete
536 * Check:
537 * bit 2 sro_calib_status
538 *
539 * The G5 Memory controller needs to see that the IO calibration has
540 * completed before kicking off DDR training.
541 * It uses the calib_status signal as a flag for this.
542 */
543 timer_out=0U;
544 #ifndef RENODE_DEBUG
545 {
546 /* PVT I/O - sro_calib_status - wait for calibration to complete */
547 while((IOSCB_IO_CALIB_DDR->IOC_REG1 & 0x00000004U) == 0U)
548 {
549 timer_out++;
550 }
551 /* PVT I/O - sro_calib_status - wait for calibration to complete */
552 while((CFG_DDR_SGMII_PHY->IOC_REG1.IOC_REG1 & 0x00000004U) == 0U)
553 {
554 timer_out++;
555 }
556 }
557 #endif
558 /*
559 * now assert calib lock
560 *
561 * */
562 {
563 CFG_DDR_SGMII_PHY->IOC_REG0.IOC_REG0 &= ~(0x01U<<14U);
564 IOSCB_IO_CALIB_DDR->IOC_REG0 &= ~(0x01U<<14U);
565 CFG_DDR_SGMII_PHY->IOC_REG0.IOC_REG0 |= (0x01U<<14U);
566 IOSCB_IO_CALIB_DDR->IOC_REG0 |= (0x01U<<14U);
567 }
568 }
569
570
571 /**
572 *
573 */
ddr_pvt_recalibration(void)574 void ddr_pvt_recalibration(void)
575 {
576 volatile uint32_t timer_out=0U;
577
578 /*
579 * now assert calib start
580 *
581 * */
582 {
583 CFG_DDR_SGMII_PHY->IOC_REG0.IOC_REG0 &= ~(0x01U<<13U);
584 IOSCB_IO_CALIB_DDR->IOC_REG0 &= ~(0x01U<<13U);
585 CFG_DDR_SGMII_PHY->IOC_REG0.IOC_REG0 |= (0x01U<<13U);
586 IOSCB_IO_CALIB_DDR->IOC_REG0 |= (0x01U<<13U);
587 }
588
589 /*
590 * R3.4 Wait for PVT calibration to complete
591 * Check:
592 * bit 2 sro_calib_status
593 *
594 * The G5 Memory controller needs to see that the IO calibration has
595 * completed before kicking off DDR training.
596 * It uses the calib_status signal as a flag for this.
597 */
598 timer_out=0U;
599 #ifndef RENODE_DEBUG
600 {
601 /* PVT I/O - sro_calib_status - wait for calibration to complete */
602 while((IOSCB_IO_CALIB_DDR->IOC_REG1 & 0x00000004U) == 0U)
603 {
604 timer_out++;
605 }
606 /* PVT I/O - sro_calib_status - wait for calibration to complete */
607 while((CFG_DDR_SGMII_PHY->IOC_REG1.IOC_REG1 & 0x00000004U) == 0U)
608 {
609 timer_out++;
610 }
611 }
612 #endif
613 /*
614 * now assert calib lock
615 *
616 * */
617 {
618 #if 0 /*
619 * fixme: this appears to cause wite calibration to fail, investigating
620 */
621 CFG_DDR_SGMII_PHY->IOC_REG0.IOC_REG0 &= ~(0x01U<<14U);
622 IOSCB_IO_CALIB_DDR->IOC_REG0 &= ~(0x01U<<14U);
623 CFG_DDR_SGMII_PHY->IOC_REG0.IOC_REG0 |= (0x01U<<14U);
624 IOSCB_IO_CALIB_DDR->IOC_REG0 |= (0x01U<<14U);
625 #endif
626 }
627 }
628
629 /**
630 * Set eye thresholds
631 * @param n_late_threshold
632 * @param p_early_threshold
633 */
set_early_late_thresholds(uint8_t n_late_threshold,uint8_t p_early_threshold)634 static void set_early_late_thresholds(uint8_t n_late_threshold, uint8_t p_early_threshold)
635 {
636 uint32_t n_eye_values;
637 uint32_t p_eye_value;
638
639 /*
640 * Set the N eye width value
641 * bits 31:29 for CH1, bits 28:26 for CH0 in spare control (N eye width value)
642 */
643 n_eye_values = (n_late_threshold << SHIFT_TO_CH0_N_EYE_VALUE);
644 n_eye_values |= (n_late_threshold << SHIFT_TO_CH1_N_EYE_VALUE);
645
646 CFG_DDR_SGMII_PHY->SPARE_CNTL.SPARE_CNTL = (LIBERO_SETTING_SPARE_CNTL & N_EYE_MASK) | n_eye_values;
647
648 /*
649 * Set P values
650 */
651 p_eye_value = (p_early_threshold << SHIFT_TO_REG_RX0_EYEWIDTH);
652 CFG_DDR_SGMII_PHY->CH0_CNTL.CH0_CNTL = ((LIBERO_SETTING_CH0_CNTL & REG_RX0_EYEWIDTH_P_MASK) | p_eye_value) | REG_RX0_EN_FLAG_N;
653 CFG_DDR_SGMII_PHY->CH1_CNTL.CH1_CNTL = ((LIBERO_SETTING_CH1_CNTL & REG_RX0_EYEWIDTH_P_MASK) | p_eye_value) | REG_RX1_EN_FLAG_N;
654
655 }
656
657 #endif
658