xilinx PL测 DP 点屏 /接收(二)--RX

环境:

a)硬件:官方ZCU106开发板 , tb-fmch-vfmc-dp子卡。

b)软件:vivado2021.1,vitis2021.1,裸机程序。

1、官方例程:

 

2、DP RX IP :

 

 

 

3、DP RX寄存器:

 

 

 

 

 

4、时钟:

 

5、像素:

Stream模式:

native模式:

 

6、timming:注意de非连续,每帧hsync个数和h_active一致。

 

 

7、vitis代码分析:

a)、iic使用ps测,和官方例程不一样,所以在MCDP6000这个文件夹定义iic:

PS侧iic初始化代码:iIc速率:100K

void ps_iic_init()

{

int Status;

XIicPs_Config *Config;

/*     * Initialize the IIC driver so that it's ready to use

 * Look up the configuration in the config table,

 * then initialize it.     */

Config = XIicPs_LookupConfig(XPAR_XIICPS_1_DEVICE_ID);

if (NULL == Config) {

printf("XIicPs_LookupConfig Failed\r\n");

return XST_FAILURE;

}

Status = XIicPs_CfgInitialize(&Iic, Config, Config->BaseAddress);

if (Status != XST_SUCCESS) {

printf("XIicPs_CfgInitialize Failed\r\n");

return XST_FAILURE;

}

/*     * Perform a self-test to ensure that the hardware was built correctly.     */

Status = XIicPs_SelfTest(&Iic);

if (Status != XST_SUCCESS) {

printf("XIicPs_SelfTest Failed\r\n");

return XST_FAILURE;

}

/*     * Set the IIC serial clock rate.     */

XIicPs_SetSClk(&Iic, 100000);

}

 

DP RX的初始化:

u32 Dprx_init(void)

{

u32 Status;

XDpRxSs_Config *ConfigPtr_rx;

xil_printf("config dp rx \n\r");

ConfigPtr_rx = XDpRxSs_LookupConfig(XDPRXSS_DEVICE_ID);

if (!ConfigPtr_rx) {

xil_printf("DPRXSS Lookup Config failed.\n\r");

return XST_FAILURE;

}

Status = XDpRxSs_CfgInitialize(&DpRxSsInst, ConfigPtr_rx,ConfigPtr_rx->BaseAddress);

if (Status != XST_SUCCESS) {

xil_printf("DPRXSS config initialization failed.\n\r");

return XST_FAILURE;

}

/* Check for SST/MST support */

if (DpRxSsInst.UsrOpt.MstSupport) {

xil_printf("INFO:DPRXSS is MST enabled. DPRXSS can be "    "switched to SST/MST\n\r");

} else {

xil_printf("INFO:DPRXSS is SST enabled. DPRXSS works "    "only in SST mode.\n\r");

}

xil_printf("Dprx_init   end .\n\r");

return XST_SUCCESS;

}

 

中断初始化:这里RX,TX都有包含

u32 DpSs_SetupIntrSystem(void)

{

u32 Status;

XINTC *IntcInstPtr = &IntcInst;

// Tx side

DpTxSs_SetupIntrSystem();

// Rx side

#ifdef DP_RX_EN

DpRxSs_SetupIntrSystem();

#endif

/* The configuration parameters of the interrupt controller */

XScuGic_Config *IntcConfig;

/* Initialize the interrupt controller

 * driver so that it is ready to use. */

IntcConfig = XScuGic_LookupConfig(XINTC_DEVICE_ID);

if (NULL == IntcConfig) {

xil_printf("XINTC_DEVICE_ID XScuGic_LookupConfig failed!\n\r");

return XST_FAILURE;

}

Status = XScuGic_CfgInitialize(IntcInstPtr, IntcConfig,    IntcConfig->CpuBaseAddress);

if (Status != XST_SUCCESS) {

xil_printf("XINTC_DEVICE_ID XScuGic_CfgInitialize failed!\n\r");

return XST_FAILURE;

}

/* Connect the device driver handler that will be called when an

 * interrupt for the device occurs, the handler defined

 * above performs the specific interrupt processing for the device.

 * */

#ifdef DP_RX_EN

Status = XScuGic_Connect(IntcInstPtr, XINTC_DPRXSS_DP_INTERRUPT_ID,    (Xil_InterruptHandler)XDpRxSs_DpIntrHandler,&DpRxSsInst);

if (Status != XST_SUCCESS) {

xil_printf("ERR: DP RX SS DP interrupt connect failed!\n\r");

return XST_FAILURE;

}

/* Enable the interrupt for the DP device */

XScuGic_Enable(IntcInstPtr, XINTC_DPRXSS_DP_INTERRUPT_ID);

#endif

/* Connect the device driver handler that will be called when an

 * interrupt for the device occurs, the handler defined above performs

 * the specific interrupt processing for the device

 */

Status = XScuGic_Connect(IntcInstPtr, XINTC_DPTXSS_DP_INTERRUPT_ID,    (Xil_InterruptHandler)XDpTxSs_DpIntrHandler,&DpTxSsInst);

if (Status != XST_SUCCESS) {

xil_printf("ERR: DP TX SS DP interrupt connect failed!\r\n");

return XST_FAILURE;

}

/* Enable the interrupt */

XScuGic_Enable(IntcInstPtr, XINTC_DPTXSS_DP_INTERRUPT_ID);

/* Initialize the exception table. */

Xil_ExceptionInit();

/* Register the interrupt controller handler with the exception

 * table.*/

Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,(Xil_ExceptionHandler)XINTC_HANDLER,IntcInstPtr);

/* Enable exceptions. */

Xil_ExceptionEnable();

return (XST_SUCCESS);

}

 

 

DP RX的中断申请:

u32 DpRxSs_SetupIntrSystem(void)

{

//    u32 Status;

//    XINTC *IntcInstPtr = &IntcInst;

/* Set callbacks for all the interrupts */

XDpRxSs_SetCallBack(&DpRxSsInst, XDPRXSS_HANDLER_DP_PWR_CHG_EVENT,            &DpRxSs_PowerChangeHandler, &DpRxSsInst);//2

XDpRxSs_SetCallBack(&DpRxSsInst, XDPRXSS_HANDLER_DP_NO_VID_EVENT,            &DpRxSs_NoVideoHandler, &DpRxSsInst);    //3

// XDpRxSs_SetCallBack(&DpRxSsInst, XDPRXSS_HANDLER_DP_VM_CHG_EVENT,            &DpRxSs_VmChangeHandler, &DpRxSsInst);

XDpRxSs_SetCallBack(&DpRxSsInst, XDPRXSS_HANDLER_DP_VBLANK_EVENT,                &DpRxSs_VerticalBlankHandler, &DpRxSsInst);//4

XDpRxSs_SetCallBack(&DpRxSsInst, XDPRXSS_HANDLER_DP_TLOST_EVENT,            &DpRxSs_TrainingLostHandler, &DpRxSsInst);//5

XDpRxSs_SetCallBack(&DpRxSsInst, XDPRXSS_HANDLER_DP_VID_EVENT,                &DpRxSs_VideoHandler, &DpRxSsInst);        //6

XDpRxSs_SetCallBack(&DpRxSsInst, XDPRXSS_HANDLER_DP_TDONE_EVENT,            &DpRxSs_TrainingDoneHandler, &DpRxSsInst);//9

XDpRxSs_SetCallBack(&DpRxSsInst, XDPRXSS_HANDLER_UNPLUG_EVENT,                &DpRxSs_UnplugHandler, &DpRxSsInst);    //17

XDpRxSs_SetCallBack(&DpRxSsInst, XDPRXSS_HANDLER_LINKBW_EVENT,                &DpRxSs_LinkBandwidthHandler, &DpRxSsInst);//18

XDpRxSs_SetCallBack(&DpRxSsInst, XDPRXSS_HANDLER_PLL_RESET_EVENT,            &DpRxSs_PllResetHandler, &DpRxSsInst);    //19

XDpRxSs_SetCallBack(&DpRxSsInst, XDPRXSS_HANDLER_DP_BW_CHG_EVENT,            &DpRxSs_BWChangeHandler, &DpRxSsInst);    //10

// XDpRxSs_SetCallBack(&DpRxSsInst, XDPRXSS_HANDLER_ACCESS_LINK_QUAL_EVENT,    &DpRxSs_AccessLinkQualHandler, &DpRxSsInst);

// XDpRxSs_SetCallBack(&DpRxSsInst, XDPRXSS_HANDLER_ACCESS_ERROR_COUNTER_EVENT,&DpRxSs_AccessErrorCounterHandler, &DpRxSsInst);

// XDpRxSs_SetCallBack(&DpRxSsInst, XDPRXSS_HANDLER_DP_CRC_TEST_EVENT,            &DpRxSs_CRCTestEventHandler, &DpRxSsInst);

// XDpRxSs_SetCallBack(&DpRxSsInst, XDPRXSS_HANDLER_DP_INFO_PKT_EVENT,            &DpRxSs_InfoPacketHandler, &DpRxSsInst);

// XDpRxSs_SetCallBack(&DpRxSsInst, XDPRXSS_HANDLER_DP_EXT_PKT_EVENT,            &DpRxSs_ExtPacketHandler, &DpRxSsInst);

/* Set custom timer wait */

XDpRxSs_SetUserTimerHandler(&DpRxSsInst, &CustomWaitUs, &TmrCtr);

return (XST_SUCCESS);

}

 

 

 

PHY的初始化:

u32 DpSs_PhyInit(u16 DeviceId)

{

XVphy_Config *ConfigPtr;

u32 Status;

/* Obtain the device configuration for the DisplayPort RX Subsystem */

ConfigPtr = XVphy_LookupConfig(DeviceId);

if (!ConfigPtr) {

return XST_FAILURE;

}

XVphy_DpInitialize(&VPhyInst, ConfigPtr, 0,

ONBOARD_REF_CLK,

ONBOARD_REF_CLK,

XVPHY_PLL_TYPE_QPLL1,

XVPHY_PLL_TYPE_CPLL,

DP_LINK_RATE);

//set the default vswing and pe for v0po

PLLRefClkSel (&VPhyInst, DP_LINK_RATE);

#if 1

    //setting vswing

    XVphy_SetTxVoltageSwing(&VPhyInst, 0, XVPHY_CHANNEL_ID_CH1,    XVPHY_GTHE4_DIFF_SWING_DP_V0P0);

    XVphy_SetTxVoltageSwing(&VPhyInst, 0, XVPHY_CHANNEL_ID_CH2,    XVPHY_GTHE4_DIFF_SWING_DP_V0P0);

    XVphy_SetTxVoltageSwing(&VPhyInst, 0, XVPHY_CHANNEL_ID_CH3,    XVPHY_GTHE4_DIFF_SWING_DP_V0P0);

    XVphy_SetTxVoltageSwing(&VPhyInst, 0, XVPHY_CHANNEL_ID_CH4,    XVPHY_GTHE4_DIFF_SWING_DP_V0P0);

    //setting postcursor

    XVphy_SetTxPostCursor(&VPhyInst, 0, XVPHY_CHANNEL_ID_CH1,    XVPHY_GTHE4_PREEMP_DP_L0);

    XVphy_SetTxPostCursor(&VPhyInst, 0, XVPHY_CHANNEL_ID_CH2,    XVPHY_GTHE4_PREEMP_DP_L0);

    XVphy_SetTxPostCursor(&VPhyInst, 0, XVPHY_CHANNEL_ID_CH3,    XVPHY_GTHE4_PREEMP_DP_L0);

    XVphy_SetTxPostCursor(&VPhyInst, 0, XVPHY_CHANNEL_ID_CH4,    XVPHY_GTHE4_PREEMP_DP_L0);

#endif

PHY_Two_byte_set (&VPhyInst, SET_RX_TO_2BYTE, SET_TX_TO_2BYTE);//SET_TX_TO_2BYTE

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

XVphy_BufgGtReset(&VPhyInst, XVPHY_DIR_TX,(TRUE));

XVphy_ResetGtPll(&VPhyInst, 0, XVPHY_CHANNEL_ID_CHA, XVPHY_DIR_TX,(FALSE));

XVphy_BufgGtReset(&VPhyInst, XVPHY_DIR_TX,(FALSE));

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

XVphy_BufgGtReset(&VPhyInst, XVPHY_DIR_RX,(TRUE));

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

XVphy_BufgGtReset(&VPhyInst, XVPHY_DIR_RX,(FALSE));

xil_printf("DpSs_PhyInit   end .\n\r");

Status = XVphy_ReadReg(XVPHY_BASEADDR, XVPHY_RX_INIT_STATUS_REG);

xil_printf("\n   DpSs_PhyInit  rx initialization Status 0x28 data = %x \n\r",Status);

    Status = XVphy_ReadReg(XVPHY_BASEADDR, XVPHY_PLL_LOCK_STATUS_REG);

    xil_printf("\n   DpSs_PhyInit  rx initialization Status 0x18 data = %x \n\r",Status);

return XST_SUCCESS;       

}

 

 

PHY的速率设置:

u32 config_phy(int LineRate_init_tx){

u32 Status=0;

//    u8 linerate;

//    u32 dptx_sts = 0;

switch(LineRate_init_tx){

case XDP_LINK_BW_SET_162GBPS:

Status = PHY_Configuration(&VPhyInst,PHY_User_Config_Table[(is_TX_CPLL) ? 0 : 3]);

break;

case XDP_LINK_BW_SET_270GBPS:

Status = PHY_Configuration(&VPhyInst,PHY_User_Config_Table[(is_TX_CPLL) ? 1 : 4]);

break;

case XDP_LINK_BW_SET_540GBPS:

Status = PHY_Configuration(&VPhyInst,PHY_User_Config_Table[(is_TX_CPLL) ? 2 : 5]);

break;

case XDP_LINK_BW_SET_810GBPS:

Status = PHY_Configuration(&VPhyInst,PHY_User_Config_Table[(is_TX_CPLL) ? 9 : 10]);

break;

}

xil_printf ("config_phy LineRate_init_tx = %x \r\n",LineRate_init_tx);

if (Status != XST_SUCCESS) {

xil_printf ("++++++++++ TX GT configuration encountered a failure +++++++\r\n");

}

return Status;

}

u32 PHY_Configuration(XVphy *InstancePtr,XVphy_User_Config PHY_User_Config_Table)

{

XVphy_PllRefClkSelType QpllRefClkSel;

XVphy_PllRefClkSelType CpllRefClkSel;

XVphy_PllType TxPllSelect;

XVphy_PllType RxPllSelect;

XVphy_ChannelId TxChId;

XVphy_ChannelId RxChId;

u8 QuadId = 0;

u32 Status = XST_FAILURE;

u32 retries = 0;

QpllRefClkSel   = PHY_User_Config_Table.QPLLRefClkSrc;

CpllRefClkSel   = PHY_User_Config_Table.CPLLRefClkSrc;

TxPllSelect     = PHY_User_Config_Table.TxPLL;

RxPllSelect     = PHY_User_Config_Table.RxPLL;

TxChId          = PHY_User_Config_Table.TxChId;

RxChId          = PHY_User_Config_Table.RxChId;

//Set the Ref Clock Frequency

XVphy_CfgQuadRefClkFreq(InstancePtr, QuadId, QpllRefClkSel,    PHY_User_Config_Table.QPLLRefClkFreqHz);

XVphy_CfgQuadRefClkFreq(InstancePtr, QuadId, CpllRefClkSel,    PHY_User_Config_Table.CPLLRefClkFreqHz);

XVphy_CfgLineRate(InstancePtr, QuadId, TxChId,    PHY_User_Config_Table.LineRateHz);

//    XVphy_CfgLineRate(InstancePtr, QuadId, RxChId,    PHY_User_Config_Table.LineRateHz);

// Initialize GT with ref clock and PLL selects

XVphy_PllInitialize(InstancePtr, QuadId, TxChId,QpllRefClkSel, CpllRefClkSel,TxPllSelect, RxPllSelect);

while (Status != XST_SUCCESS) {

Status = XVphy_ClkInitialize(InstancePtr, QuadId,   TxChId, XVPHY_DIR_TX);

if (retries > 100) {

retries = 0;

xil_printf ("exhausted\r\n");

break;

}

retries++;

}

// Initialize GT with ref clock and PLL selects

Status = XVphy_ClkInitialize(InstancePtr, QuadId, RxChId, XVPHY_DIR_RX);

XVphy_WriteReg(InstancePtr->Config.BaseAddr,XVPHY_PLL_RESET_REG,(XVPHY_PLL_RESET_CPLL_MASK | XVPHY_PLL_RESET_QPLL1_MASK)); // 0x06

XVphy_WriteReg(InstancePtr->Config.BaseAddr,XVPHY_PLL_RESET_REG, 0x0);

//    XVphy_ResetGtPll(InstancePtr, QuadId, RxChId, XVPHY_DIR_RX,(TRUE));

//    XVphy_ResetGtPll(InstancePtr, QuadId, RxChId, XVPHY_DIR_RX,(FALSE));

XVphy_ResetGtPll(InstancePtr, QuadId,XVPHY_CHANNEL_ID_CHA, XVPHY_DIR_TX,(FALSE));

//    Status =  XVphy_WaitForResetDone(&VPhyInst, 0, XVPHY_CHANNEL_ID_CHA, XVPHY_DIR_RX);

//    xil_printf("\n   step_phy  XVphy_WaitForResetDone Status = %x \n\r",Status);

//    Status = XVphy_WaitForPllLock(&VPhyInst, 0, XVPHY_CHANNEL_ID_CHA);

//    xil_printf("\n   step_phy  XVphy_WaitForPllLock Status = %x \n\r",Status);

Status = XVphy_WaitForPmaResetDone(InstancePtr, QuadId,    TxChId, XVPHY_DIR_TX);

Status += XVphy_WaitForPllLock(InstancePtr, QuadId, TxChId);

Status += XVphy_WaitForResetDone(InstancePtr, QuadId,TxChId, XVPHY_DIR_TX);

if (Status  != XST_SUCCESS) {

xil_printf ("++++TX GT config encountered error++++\r\n");

}

return Status;

}

 

 

DP RX速率,lane的数目设置:

u32 DPRx_step(void)

{

u32 Status;

u32 tmp_rd;

    /* Set Link rate and lane count to maximum */

    XDpRxSs_SetLinkRate(&DpRxSsInst, DP_LINK_RATE);

    XDpRxSs_SetLaneCount(&DpRxSsInst, DP_LANE_COUNT);

    /* Start DPRX Subsystem set */

    Status = XDpRxSs_Start(&DpRxSsInst);

    if (Status != XST_SUCCESS) {

        xil_printf("ERR:DPRX SS start failed\n\r");

        return XST_FAILURE;

    }

    xil_printf("\r\n  DPRx_step  done.\n\r");

    tmp_rd = XDp_ReadReg(DpRxSsInst.DpPtr->Config.BaseAddr, 0x4);

    tmp_rd |= tmp_rd | 0x06000000;

    XDp_WriteReg(DpRxSsInst.DpPtr->Config.BaseAddr, 0x4, tmp_rd);

    return (XST_SUCCESS);

}

 

DP RX 的开始training函数:

u32 DpRxSs_Setup(void)

{

    u32 ReadVal;

    u32 Status;

    /*Disable Rx*/

    XDp_WriteReg(DpRxSsInst.DpPtr->Config.BaseAddr, XDP_RX_LINK_ENABLE, 0x0);//hpd 拉低

    /*Setting BS Idle timeout value to long value*/

    XDp_WriteReg(DpRxSsInst.DpPtr->Config.BaseAddr,   XDP_RX_BS_IDLE_TIME, 0x047868C0);//这个参数,在某些应用上要适当的更改。

    /* Load Custom EDID */

    LoadEDID();

//    XDp_WriteReg(DpRxSsInst.DpPtr->Config.BaseAddr,    XDP_RX_INTERRUPT_MASK, 0xFFF87FFD);

    /*Disable All Interrupts*/

 //   XDp_RxInterruptDisable(DpRxSsInst.DpPtr, 0xFFFFFFFF);

    xil_printf("RX Link & Lane Capability is set to %x, %x\r\n",

                (XDp_ReadReg(DpRxSsInst.DpPtr->Config.BaseAddr ,XDP_RX_DPCD_LINK_BW_SET)),

                (XDp_ReadReg(DpRxSsInst.DpPtr->Config.BaseAddr,    XDP_RX_DPCD_LANE_COUNT_SET)));

    /*Enable Training related interrupts*/

   XDp_RxInterruptEnable(DpRxSsInst.DpPtr,

            XDP_RX_INTERRUPT_MASK_TP1_MASK|XDP_RX_INTERRUPT_MASK_TP2_MASK|

            XDP_RX_INTERRUPT_MASK_TP3_MASK|

            XDP_RX_INTERRUPT_MASK_POWER_STATE_MASK|

            XDP_RX_INTERRUPT_MASK_BW_CHANGE_MASK);

    /* Setting AUX Defer Count of Link Status Reads to 8 during Link Training

     * 8 Defer counts is chosen to handle worst case time interrupt service

     * load (PL system working at 100 MHz) when working with R5

     * */

    ReadVal = XDp_ReadReg(DpRxSsInst.DpPtr->Config.BaseAddr,XDP_RX_AUX_CLK_DIVIDER);

    ReadVal |= ReadVal | (AUX_DEFER_COUNT<<24);

    XDp_WriteReg(DpRxSsInst.DpPtr->Config.BaseAddr,    XDP_RX_AUX_CLK_DIVIDER, ReadVal);

//-------------------------------------------------------------------------------------------------------------------

    Status =  XVphy_WaitForResetDone(&VPhyInst, 0, XVPHY_CHANNEL_ID_CHA, XVPHY_DIR_RX);

    Status = XVphy_WaitForPllLock(&VPhyInst, 0, XVPHY_CHANNEL_ID_CHA);

    xil_printf("\n   step_dp_rx  XVphy_WaitForPllLock Status = %x \n\r",Status);

    xil_printf("\r\n addr =%x XDP_RX_PHY_STATUS = %x \r\n",XDP_RX_PHY_STATUS,XDp_ReadReg(XDPRXSS_BASEADDR, XDP_RX_PHY_STATUS));

    XScuGic_Enable(&IntcInst, XINTC_DPRXSS_DP_INTERRUPT_ID);

//resetting AUX logic. Needed for some Type C based connectors

XDp_WriteReg(DpRxSsInst.DpPtr->Config.BaseAddr, 0x1C, 0x80);

XDp_WriteReg(DpRxSsInst.DpPtr->Config.BaseAddr, 0x1C, 0x0);

  //********************************************

    if(LINK_TRAINING_DEBUG)

    {

        /*Updating Vswing Iteration Count*/

        RxTrainConfig.ChEqOption = 1;

        RxTrainConfig.ClockRecoveryOption = 2;

        RxTrainConfig.Itr1Premp = 0;

        RxTrainConfig.Itr2Premp = 0;

        RxTrainConfig.Itr3Premp = 0;

        RxTrainConfig.Itr4Premp = 0;

        RxTrainConfig.Itr5Premp = 0;

        RxTrainConfig.MinVoltageSwing = 1;

        RxTrainConfig.SetPreemp = 1;

        RxTrainConfig.SetVswing = 0;

        RxTrainConfig.VswingLoopCount = 3;

        XDp_WriteReg(DpRxSsInst.DpPtr->Config.BaseAddr,    XDP_RX_MIN_VOLTAGE_SWING,

                RxTrainConfig.MinVoltageSwing |

                (RxTrainConfig.ClockRecoveryOption << 2) |

                (RxTrainConfig.VswingLoopCount << 4) |

                (RxTrainConfig.SetVswing << 8) |

                (RxTrainConfig.ChEqOption << 10) |

                (RxTrainConfig.SetPreemp << 12) |

                (RxTrainConfig.Itr1Premp << 14) |

                (RxTrainConfig.Itr2Premp << 16) |

                (RxTrainConfig.Itr3Premp << 18) |

                (RxTrainConfig.Itr4Premp << 20) |

                (RxTrainConfig.Itr5Premp << 22)

                );

    }

    XDp_WriteReg(DpRxSsInst.DpPtr->Config.BaseAddr, XDP_RX_LINK_ENABLE, 0x1);//此时HPD会拉高,开始training

    xil_printf("\r\n  DpRxSs_Setup  done.\n\r");

    return XST_SUCCESS;

}

DP RX中断说明:

void DpRxSs_VerticalBlankHandler(void *InstancePtr)    //检测到v_blank,当检测到200个就表示接收到视频

{

//    xil_printf("\r\n   4     \r\n");

DpRxSsInst.VBlankCount++;

dp_rx_ok =0;

video_cnt =0;

if(DpRxSsInst.VBlankCount==200){

XDp_RxInterruptDisable(DpRxSsInst.DpPtr,        XDP_RX_INTERRUPT_MASK_VBLANK_MASK);

DpRxSsInst.VBlankCount=0;

XDp_RxDtgDis(DpRxSsInst.DpPtr);

XDp_RxDtgEn(DpRxSsInst.DpPtr);

XDp_RxSetLineReset(DpRxSsInst.DpPtr,1);

XDp_RxSetUserPixelWidth(DpRxSsInst.DpPtr,0x04);

xil_printf("\r\n   4   VBlankCount=200  \r\n");

video_flag = 1;

}

else if(DpRxSsInst.VBlankCount==80)

{

video_flag =0;

xil_printf("\r\n   4  VBlankCount= 80    \r\n");

}

else if(DpRxSsInst.VBlankCount==20)

{

video_flag =0;

xil_printf("\r\n   4  VBlankCount= 20    \r\n");

XDp_RxInterruptEnable(DpRxSsInst.DpPtr,0x80000000);

}

}

 

void DpRxSs_TrainingLostHandler(void *InstancePtr)

{

xil_printf("\r\n   5     \r\n");

XDp_RxGenerateHpdInterrupt(DpRxSsInst.DpPtr, 750);

XDpRxSs_AudioDisable(&DpRxSsInst);

sink_power_down(); // close dp tx

vdma_stop(); // close vdma write

video_flag =0;

dp_rx_ok=0;

dp_rx_lost=1;

}

void DpRxSs_VideoHandler(void *InstancePtr)   //此中断,在检测到不同的msa会进入此中断,如果一直在进入此中断,表示training ok,但是msa的数据异常,且在变化

{

xil_printf("\r\n   6     \r\n");

video_cnt++;

if((video_cnt==1)|(video_cnt==2))

dp_rx_ok = 1;

else

dp_rx_ok =0;

if(video_cnt==8)

{

//    XDp_RxGenerateHpdInterrupt(DpRxSsInst.DpPtr, 750);

XDp_WriteReg(DpRxSsInst.DpPtr->Config.BaseAddr, XDP_RX_LINK_ENABLE, 0x0);

usleep(250000);

XDp_WriteReg(DpRxSsInst.DpPtr->Config.BaseAddr, XDP_RX_LINK_ENABLE, 0x1);

}

if(0)//video_flag

{

xil_printf("\r\n   6     \r\n");

dp_rx_ok =1;

}

}

void DpRxSs_UnplugHandler(void *InstancePtr)

{

xil_printf("\r\n   17     \r\n");

video_flag =0;

/*Enable Training related interrupts*/

XDp_RxInterruptDisable(DpRxSsInst.DpPtr,  XDP_RX_INTERRUPT_MASK_ALL_MASK);

//    XDp_WriteReg(DpRxSsInst.DpPtr->Config.BaseAddr, XDP_RX_LINK_ENABLE, 0x0);

XDp_RxInterruptEnable(DpRxSsInst.DpPtr,

      XDP_RX_INTERRUPT_MASK_TP1_MASK |

      XDP_RX_INTERRUPT_MASK_TP2_MASK |

XDP_RX_INTERRUPT_MASK_TP3_MASK|

XDP_RX_INTERRUPT_MASK_POWER_STATE_MASK|

XDP_RX_INTERRUPT_MASK_CRC_TEST_MASK|

XDP_RX_INTERRUPT_MASK_BW_CHANGE_MASK);

XDp_RxGenerateHpdInterrupt(DpRxSsInst.DpPtr, 5000);

}

void DpRxSs_LinkBandwidthHandler(void *InstancePtr)    // 根据 tx发送的 速率,进行更改phy的速率

{

u32 Status;

//    xil_printf("\r\n   18     \r\n");

/*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");

}

 

void DpRxSs_PllResetHandler(void *InstancePtr)    //phy的速率更改后,重新复位。

{

//    xil_printf("\r\n   19     \r\n");

//    u32 ReadVal;

/* Issue resets to Video PHY - This API

 * called after line rate is programmed */

XVphy_BufgGtReset(&VPhyInst, XVPHY_DIR_RX,(TRUE));

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

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

XVphy_BufgGtReset(&VPhyInst, XVPHY_DIR_RX,(FALSE));

XVphy_WaitForResetDone(&VPhyInst, 0, XVPHY_CHANNEL_ID_CHA,      XVPHY_DIR_RX);

XVphy_WaitForPllLock(&VPhyInst, 0, XVPHY_CHANNEL_ID_CHA);

/*Enable all interrupts */

XDp_RxInterruptEnable(DpRxSsInst.DpPtr,   XDP_RX_INTERRUPT_MASK_ALL_MASK);

}

 

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值