XilinxProcessorIPLib/drivers/dp14txss/examples/src/pt_only/rx.c
void DpRxSs_LinkBandwidthHandler(void *InstancePtr)
{
	u32 Status;
#ifndef versal
	/*Program Video PHY to requested line rate*/
	PLLRefClkSel (&VPhyInst, DpRxSsInst.UsrOpt.LinkRate);

	XVphy_ResetGtPll(&VPhyInst, 0, XVPHY_CHANNEL_ID_CHA,
			 XVPHY_DIR_RX,(TRUE));

	XVphy_PllInitialize(&VPhyInst, 0, XVPHY_CHANNEL_ID_CHA,
				ONBOARD_REF_CLK, ONBOARD_REF_CLK,
				XVPHY_PLL_TYPE_QPLL1, XVPHY_PLL_TYPE_CPLL);
	Status = XVphy_ClkInitialize(&VPhyInst, 0,
									XVPHY_CHANNEL_ID_CHA, XVPHY_DIR_RX);
	if(Status != XST_SUCCESS)
		xil_printf("XVphy_ClkInitialize failed\r\n");
#else

	u8 bridge;
	u32 retry = 0;
	u32 dprx_sts=0;
	u32 rate=0;
	u32 HighTime;
	u32 DivEdge;
	u32 Reg;
	u32 P5Enable;
	u32 P5fEdge;
	u16 Oval;
	u16 Dval;
	u16 Mval;

	/* For each line rate, the M, D, Div values for MMCM are chosen such that
	 * MMCM gives a /20 clock output for /16 clk input.
	 *
	 * GT ch0outclk (/16) --> MMCM --> /20 clock
	 *
	 * Thus:
	 * 8.1G  : Input MMCM clock is 506.25, output is 405
	 * 5.4G  : Input MMCM clock is 337.5, output is 270
	 * 2.7G  : Input MMCM clock is 168.75, output is 135
	 * 1.62G : Input MMCM clock is 101.25, output is 81
	 */

    if (DpRxSsInst.UsrOpt.LinkRate == XDP_TX_LINK_BW_SET_810GBPS) {
		bridge = VERSAL_810G;
		Mval = 28;
		Dval = 5;
		Oval = 7;
    } else if (DpRxSsInst.UsrOpt.LinkRate == XDP_TX_LINK_BW_SET_540GBPS) {
		bridge = VERSAL_540G;
		Mval = 44;
		Dval = 5;
		Oval = 11;
    } else if (DpRxSsInst.UsrOpt.LinkRate == XDP_TX_LINK_BW_SET_270GBPS) {
		bridge = VERSAL_270G;
		Mval = 88;
		Dval = 5;
		Oval = 22;
    } else {
		bridge = VERSAL_162G;
		Mval = 148;
		Dval = 5;
		Oval = 37;
    }

#if (VERSAL_FABRIC_8B10B == 1)
    /* MMCM is dynamically programmed for the respective rate
     * using the M, D, Div values
     */
	HighTime = (Oval / 4);
	Reg =  XCLK_WIZ_REG3_PREDIV2 | XCLK_WIZ_REG3_USED | XCLK_WIZ_REG3_MX;
	if (Oval % 4 <= 1) {
		DivEdge = 0;
	} else {
		DivEdge = 1;
	}
	Reg |= (DivEdge << 8);
	P5fEdge = Oval % 2;
	P5Enable = Oval % 2;
	Reg = Reg | P5Enable << XCLK_WIZ_CLKOUT0_P5EN_SHIFT | P5fEdge << XCLK_WIZ_CLKOUT0_P5FEDGE_SHIFT;
	XClk_Wiz_WriteReg(CfgPtr_Dynamic_rx->BaseAddr, XCLK_WIZ_REG3_OFFSET, Reg);
	Reg = HighTime | HighTime << 8;
	XClk_Wiz_WriteReg(CfgPtr_Dynamic_rx->BaseAddr, XCLK_WIZ_REG4_OFFSET, Reg);

	/* Implement D */
	HighTime = (Dval / 2);
	Reg  = 0;
	Reg = Reg & ~(1 << XCLK_WIZ_REG12_EDGE_SHIFT);
	DivEdge = Dval % 2;
	Reg = Reg | DivEdge << XCLK_WIZ_REG12_EDGE_SHIFT;
	XClk_Wiz_WriteReg(CfgPtr_Dynamic_rx->BaseAddr, XCLK_WIZ_REG12_OFFSET, Reg);
	Reg = HighTime | HighTime << 8;
	XClk_Wiz_WriteReg(CfgPtr_Dynamic_rx->BaseAddr, XCLK_WIZ_REG13_OFFSET, Reg);

	/* Implement M*/
	XClk_Wiz_WriteReg(CfgPtr_Dynamic_rx->BaseAddr, XCLK_WIZ_REG25_OFFSET, 0);

	DivEdge = Mval % 2;
	HighTime = Mval / 2;
	Reg = HighTime | HighTime << 8;
	XClk_Wiz_WriteReg(CfgPtr_Dynamic_rx->BaseAddr, XCLK_WIZ_REG2_OFFSET, Reg);
	Reg = XCLK_WIZ_REG1_PREDIV2 | XCLK_WIZ_REG1_EN | XCLK_WIZ_REG1_MX;

	if (DivEdge) {
		Reg = Reg | (1 << XCLK_WIZ_REG1_EDGE_SHIFT);
	} else {
		Reg = Reg & ~(1 << XCLK_WIZ_REG1_EDGE_SHIFT);
	}
	XClk_Wiz_WriteReg(CfgPtr_Dynamic_rx->BaseAddr, XCLK_WIZ_REG1_OFFSET, Reg);
	XClk_Wiz_WriteReg(CfgPtr_Dynamic_rx->BaseAddr, XCLK_WIZ_REG11_OFFSET, 0x2e);
	XClk_Wiz_WriteReg(CfgPtr_Dynamic_rx->BaseAddr, XCLK_WIZ_REG14_OFFSET, 0xe80);
	XClk_Wiz_WriteReg(CfgPtr_Dynamic_rx->BaseAddr, XCLK_WIZ_REG15_OFFSET, 0x4271);
	XClk_Wiz_WriteReg(CfgPtr_Dynamic_rx->BaseAddr, XCLK_WIZ_REG16_OFFSET, 0x43e9);
	XClk_Wiz_WriteReg(CfgPtr_Dynamic_rx->BaseAddr, XCLK_WIZ_REG17_OFFSET, 0x001C);
	XClk_Wiz_WriteReg(CfgPtr_Dynamic_rx->BaseAddr, XCLK_WIZ_REG26_OFFSET, 0x0001);
	XClk_Wiz_WriteReg(CfgPtr_Dynamic_rx->BaseAddr, XCLK_WIZ_RECONFIG_OFFSET, 0x3);
#endif

    rate = bridge << 1;
    GtCtrl (GT_RATE_MASK, rate, 0);
    dprx_sts = 0;
	while (dprx_sts != ALL_LANE && retry < 10000) {
		 dprx_sts = XDp_ReadReg(DpRxSsInst.DpPtr->Config.BaseAddr, 0x208);
		 dprx_sts &= ALL_LANE;
		 retry++;
	}
	if (retry == 10000) {
		xil_printf ("+++ RX GT Configuration failure ++++\r\n");
	}
#if (VERSAL_FABRIC_8B10B == 1)
	retry = 0;
	/* MMCM issued a reset */
	XClk_Wiz_WriteReg(CfgPtr_Dynamic_rx->BaseAddr, 0x0, 0xA);
	while(!(XClk_Wiz_ReadReg(CfgPtr_Dynamic_rx->BaseAddr, XCLK_WIZ_STATUS_OFFSET) & 1)) {
		if(retry == 10000) {
				break;
		}
//					usleep(100);
		retry++;
	}
	if (retry == 10000) {
		xil_printf ("Rx Clk_wizard failed to lock\r\n");
	}
#endif
#endif

	DpRxSsInst.link_up_trigger = 0;
	DpRxSsInst.VBlankCount = 0;
	DpRxSsInst.no_video_trigger = 1;
}
/*****************************************************************************/
/**
*
* This function is the callback function for when the link bandwidth change
* occurs.
*
* @param    InstancePtr is a pointer to the XDpRxSs instance.
*
* @return    None.
*
* @note        None.
*
******************************************************************************/
This function is the callback function for when the link bandwidth change
occurs.
This function is the callback function for when the link bandwidth change occurs .
void DpRxSs_LinkBandwidthHandler(void *InstancePtr)
{
	u32 Status;
#ifndef versal
	PLLRefClkSel (&VPhyInst, DpRxSsInst.UsrOpt.LinkRate);
	XVphy_ResetGtPll(&VPhyInst, 0, XVPHY_CHANNEL_ID_CHA,
			 XVPHY_DIR_RX,(TRUE));
	XVphy_PllInitialize(&VPhyInst, 0, XVPHY_CHANNEL_ID_CHA,
				ONBOARD_REF_CLK, ONBOARD_REF_CLK,
				XVPHY_PLL_TYPE_QPLL1, XVPHY_PLL_TYPE_CPLL);
	Status = XVphy_ClkInitialize(&VPhyInst, 0,
									XVPHY_CHANNEL_ID_CHA, XVPHY_DIR_RX);
	if(Status != XST_SUCCESS)
		xil_printf("XVphy_ClkInitialize failed\r\n");
#else
	u8 bridge;
	u32 retry = 0;
	u32 dprx_sts=0;
	u32 rate=0;
	u32 HighTime;
	u32 DivEdge;
	u32 Reg;
	u32 P5Enable;
	u32 P5fEdge;
	u16 Oval;
	u16 Dval;
	u16 Mval;
    if (DpRxSsInst.UsrOpt.LinkRate == XDP_TX_LINK_BW_SET_810GBPS) {
		bridge = VERSAL_810G;
		Mval = 28;
		Dval = 5;
		Oval = 7;
    } else if (DpRxSsInst.UsrOpt.LinkRate == XDP_TX_LINK_BW_SET_540GBPS) {
		bridge = VERSAL_540G;
		Mval = 44;
		Dval = 5;
		Oval = 11;
    } else if (DpRxSsInst.UsrOpt.LinkRate == XDP_TX_LINK_BW_SET_270GBPS) {
		bridge = VERSAL_270G;
		Mval = 88;
		Dval = 5;
		Oval = 22;
    } else {
		bridge = VERSAL_162G;
		Mval = 148;
		Dval = 5;
		Oval = 37;
    }
#if (VERSAL_FABRIC_8B10B == 1)
	HighTime = (Oval / 4);
	Reg =  XCLK_WIZ_REG3_PREDIV2 | XCLK_WIZ_REG3_USED | XCLK_WIZ_REG3_MX;
	if (Oval % 4 <= 1) {
		DivEdge = 0;
	} else {
		DivEdge = 1;
	}
	Reg |= (DivEdge << 8);
	P5fEdge = Oval % 2;
	P5Enable = Oval % 2;
	Reg = Reg | P5Enable << XCLK_WIZ_CLKOUT0_P5EN_SHIFT | P5fEdge << XCLK_WIZ_CLKOUT0_P5FEDGE_SHIFT;
	XClk_Wiz_WriteReg(CfgPtr_Dynamic_rx->BaseAddr, XCLK_WIZ_REG3_OFFSET, Reg);
	Reg = HighTime | HighTime << 8;
	XClk_Wiz_WriteReg(CfgPtr_Dynamic_rx->BaseAddr, XCLK_WIZ_REG4_OFFSET, Reg);
	HighTime = (Dval / 2);
	Reg  = 0;
	Reg = Reg & ~(1 << XCLK_WIZ_REG12_EDGE_SHIFT);
	DivEdge = Dval % 2;
	Reg = Reg | DivEdge << XCLK_WIZ_REG12_EDGE_SHIFT;
	XClk_Wiz_WriteReg(CfgPtr_Dynamic_rx->BaseAddr, XCLK_WIZ_REG12_OFFSET, Reg);
	Reg = HighTime | HighTime << 8;
	XClk_Wiz_WriteReg(CfgPtr_Dynamic_rx->BaseAddr, XCLK_WIZ_REG13_OFFSET, Reg);
	XClk_Wiz_WriteReg(CfgPtr_Dynamic_rx->BaseAddr, XCLK_WIZ_REG25_OFFSET, 0);
	DivEdge = Mval % 2;
	HighTime = Mval / 2;
	Reg = HighTime | HighTime << 8;
	XClk_Wiz_WriteReg(CfgPtr_Dynamic_rx->BaseAddr, XCLK_WIZ_REG2_OFFSET, Reg);
	Reg = XCLK_WIZ_REG1_PREDIV2 | XCLK_WIZ_REG1_EN | XCLK_WIZ_REG1_MX;
	if (DivEdge) {
		Reg = Reg | (1 << XCLK_WIZ_REG1_EDGE_SHIFT);
	} else {
		Reg = Reg & ~(1 << XCLK_WIZ_REG1_EDGE_SHIFT);
	}
	XClk_Wiz_WriteReg(CfgPtr_Dynamic_rx->BaseAddr, XCLK_WIZ_REG1_OFFSET, Reg);
	XClk_Wiz_WriteReg(CfgPtr_Dynamic_rx->BaseAddr, XCLK_WIZ_REG11_OFFSET, 0x2e);
	XClk_Wiz_WriteReg(CfgPtr_Dynamic_rx->BaseAddr, XCLK_WIZ_REG14_OFFSET, 0xe80);
	XClk_Wiz_WriteReg(CfgPtr_Dynamic_rx->BaseAddr, XCLK_WIZ_REG15_OFFSET, 0x4271);
	XClk_Wiz_WriteReg(CfgPtr_Dynamic_rx->BaseAddr, XCLK_WIZ_REG16_OFFSET, 0x43e9);
	XClk_Wiz_WriteReg(CfgPtr_Dynamic_rx->BaseAddr, XCLK_WIZ_REG17_OFFSET, 0x001C);
	XClk_Wiz_WriteReg(CfgPtr_Dynamic_rx->BaseAddr, XCLK_WIZ_REG26_OFFSET, 0x0001);
	XClk_Wiz_WriteReg(CfgPtr_Dynamic_rx->BaseAddr, XCLK_WIZ_RECONFIG_OFFSET, 0x3);
#endif
    rate = bridge << 1;
    GtCtrl (GT_RATE_MASK, rate, 0);
    dprx_sts = 0;
	while (dprx_sts != ALL_LANE && retry < 10000) {
		 dprx_sts = XDp_ReadReg(DpRxSsInst.DpPtr->Config.BaseAddr, 0x208);
		 dprx_sts &= ALL_LANE;
		 retry++;
	}
	if (retry == 10000) {
		xil_printf ("+++ RX GT Configuration failure ++++\r\n");
	}
#if (VERSAL_FABRIC_8B10B == 1)
	retry = 0;
	XClk_Wiz_WriteReg(CfgPtr_Dynamic_rx->BaseAddr, 0x0, 0xA);
	while(!(XClk_Wiz_ReadReg(CfgPtr_Dynamic_rx->BaseAddr, XCLK_WIZ_STATUS_OFFSET) & 1)) {
		if(retry == 10000) {
				break;
		}
		retry++;
	}
	if (retry == 10000) {
		xil_printf ("Rx Clk_wizard failed to lock\r\n");
	}
#endif
#endif
	DpRxSsInst.link_up_trigger = 0;
	DpRxSsInst.VBlankCount = 0;
	DpRxSsInst.no_video_trigger = 1;
}
void DpRxSs_LinkBandwidthHandler ( void * InstancePtr ) { u32 Status ; #ifndef versal PLLRefClkSel ( & VPhyInst , DpRxSsInst . UsrOpt . LinkRate ) ; XVphy_ResetGtPll ( & VPhyInst , 0 , XVPHY_CHANNEL_ID_CHA , XVPHY_DIR_RX , ( TRUE ) ) ; XVphy_PllInitialize ( & VPhyInst , 0 , XVPHY_CHANNEL_ID_CHA , ONBOARD_REF_CLK , ONBOARD_REF_CLK , XVPHY_PLL_TYPE_QPLL1 , XVPHY_PLL_TYPE_CPLL ) ; Status = XVphy_ClkInitialize ( & VPhyInst , 0 , XVPHY_CHANNEL_ID_CHA , XVPHY_DIR_RX ) ; if ( Status != XST_SUCCESS ) xil_printf ( " \r \n " ) ; #else u8 bridge ; u32 retry = 0 ; u32 dprx_sts = 0 ; u32 rate = 0 ; u32 HighTime ; u32 DivEdge ; u32 Reg ; u32 P5Enable ; u32 P5fEdge ; u16 Oval ; u16 Dval ; u16 Mval ; if ( DpRxSsInst . UsrOpt . LinkRate == XDP_TX_LINK_BW_SET_810GBPS ) { bridge = VERSAL_810G ; Mval = 28 ; Dval = 5 ; Oval = 7 ; } else if ( DpRxSsInst . UsrOpt . LinkRate == XDP_TX_LINK_BW_SET_540GBPS ) { bridge = VERSAL_540G ; Mval = 44 ; Dval = 5 ; Oval = 11 ; } else if ( DpRxSsInst . UsrOpt . LinkRate == XDP_TX_LINK_BW_SET_270GBPS ) { bridge = VERSAL_270G ; Mval = 88 ; Dval = 5 ; Oval = 22 ; } else { bridge = VERSAL_162G ; Mval = 148 ; Dval = 5 ; Oval = 37 ; } #if ( VERSAL_FABRIC_8B10B == 1 ) HighTime = ( Oval / 4 ) ; Reg = XCLK_WIZ_REG3_PREDIV2 | XCLK_WIZ_REG3_USED | XCLK_WIZ_REG3_MX ; if ( Oval % 4 <= 1 ) { DivEdge = 0 ; } else { DivEdge = 1 ; } Reg |= ( DivEdge << 8 ) ; P5fEdge = Oval % 2 ; P5Enable = Oval % 2 ; Reg = Reg | P5Enable << XCLK_WIZ_CLKOUT0_P5EN_SHIFT | P5fEdge << XCLK_WIZ_CLKOUT0_P5FEDGE_SHIFT ; XClk_Wiz_WriteReg ( CfgPtr_Dynamic_rx -> BaseAddr , XCLK_WIZ_REG3_OFFSET , Reg ) ; Reg = HighTime | HighTime << 8 ; XClk_Wiz_WriteReg ( CfgPtr_Dynamic_rx -> BaseAddr , XCLK_WIZ_REG4_OFFSET , Reg ) ; HighTime = ( Dval / 2 ) ; Reg = 0 ; Reg = Reg & ~ ( 1 << XCLK_WIZ_REG12_EDGE_SHIFT ) ; DivEdge = Dval % 2 ; Reg = Reg | DivEdge << XCLK_WIZ_REG12_EDGE_SHIFT ; XClk_Wiz_WriteReg ( CfgPtr_Dynamic_rx -> BaseAddr , XCLK_WIZ_REG12_OFFSET , Reg ) ; Reg = HighTime | HighTime << 8 ; XClk_Wiz_WriteReg ( CfgPtr_Dynamic_rx -> BaseAddr , XCLK_WIZ_REG13_OFFSET , Reg ) ; XClk_Wiz_WriteReg ( CfgPtr_Dynamic_rx -> BaseAddr , XCLK_WIZ_REG25_OFFSET , 0 ) ; DivEdge = Mval % 2 ; HighTime = Mval / 2 ; Reg = HighTime | HighTime << 8 ; XClk_Wiz_WriteReg ( CfgPtr_Dynamic_rx -> BaseAddr , XCLK_WIZ_REG2_OFFSET , Reg ) ; Reg = XCLK_WIZ_REG1_PREDIV2 | XCLK_WIZ_REG1_EN | XCLK_WIZ_REG1_MX ; if ( DivEdge ) { Reg = Reg | ( 1 << XCLK_WIZ_REG1_EDGE_SHIFT ) ; } else { Reg = Reg & ~ ( 1 << XCLK_WIZ_REG1_EDGE_SHIFT ) ; } XClk_Wiz_WriteReg ( CfgPtr_Dynamic_rx -> BaseAddr , XCLK_WIZ_REG1_OFFSET , Reg ) ; XClk_Wiz_WriteReg ( CfgPtr_Dynamic_rx -> BaseAddr , XCLK_WIZ_REG11_OFFSET , 0x2e ) ; XClk_Wiz_WriteReg ( CfgPtr_Dynamic_rx -> BaseAddr , XCLK_WIZ_REG14_OFFSET , 0xe80 ) ; XClk_Wiz_WriteReg ( CfgPtr_Dynamic_rx -> BaseAddr , XCLK_WIZ_REG15_OFFSET , 0x4271 ) ; XClk_Wiz_WriteReg ( CfgPtr_Dynamic_rx -> BaseAddr , XCLK_WIZ_REG16_OFFSET , 0x43e9 ) ; XClk_Wiz_WriteReg ( CfgPtr_Dynamic_rx -> BaseAddr , XCLK_WIZ_REG17_OFFSET , 0x001C ) ; XClk_Wiz_WriteReg ( CfgPtr_Dynamic_rx -> BaseAddr , XCLK_WIZ_REG26_OFFSET , 0x0001 ) ; XClk_Wiz_WriteReg ( CfgPtr_Dynamic_rx -> BaseAddr , XCLK_WIZ_RECONFIG_OFFSET , 0x3 ) ; #endif rate = bridge << 1 ; GtCtrl ( GT_RATE_MASK , rate , 0 ) ; dprx_sts = 0 ; while ( dprx_sts != ALL_LANE && retry < 10000 ) { dprx_sts = XDp_ReadReg ( DpRxSsInst . DpPtr -> Config . BaseAddr , 0x208 ) ; dprx_sts &= ALL_LANE ; retry ++ ; } if ( retry == 10000 ) { xil_printf ( " \r \n " ) ; } #if ( VERSAL_FABRIC_8B10B == 1 ) retry = 0 ; XClk_Wiz_WriteReg ( CfgPtr_Dynamic_rx -> BaseAddr , 0x0 , 0xA ) ; while ( ! ( XClk_Wiz_ReadReg ( CfgPtr_Dynamic_rx -> BaseAddr , XCLK_WIZ_STATUS_OFFSET ) & 1 ) ) { if ( retry == 10000 ) { break ; } retry ++ ; } if ( retry == 10000 ) { xil_printf ( " \r \n " ) ; } #endif #endif DpRxSsInst . link_up_trigger = 0 ; DpRxSsInst . VBlankCount = 0 ; DpRxSsInst . no_video_trigger = 1 ; }
This function is the callback function for when the link bandwidth change
occurs.
This function is the callback function for when the link bandwidth change occurs .
/*Program Video PHY to requested line rate*/ /* For each line rate, the M, D, Div values for MMCM are chosen such that
	 * MMCM gives a /20 clock output for /16 clk input.
	 *
	 * GT ch0outclk (/16) --> MMCM --> /20 clock
	 *
	 * Thus:
	 * 8.1G  : Input MMCM clock is 506.25, output is 405
	 * 5.4G  : Input MMCM clock is 337.5, output is 270
	 * 2.7G  : Input MMCM clock is 168.75, output is 135
	 * 1.62G : Input MMCM clock is 101.25, output is 81
	 */ /* MMCM is dynamically programmed for the respective rate
     * using the M, D, Div values
     */ /* Implement D */ /* Implement M*/ /* MMCM issued a reset */ //					usleep(100);