Exemple #1
0
/**
*
* This function checks if there is a connected RX device to DisplayPort TX
* Subsystem.
*
* @param	InstancePtr is a pointer to the XDpTxSs core instance.
*
* @return
*		- TRUE if there is a connection.
*		- FALSE if there is no connection.
*
* @note		None.
*
******************************************************************************/
u32 XDpTxSs_IsConnected(XDpTxSs *InstancePtr)
{
	u32 Status;

	/* Verify argument.*/
	Xil_AssertNonvoid(InstancePtr != NULL);

	/* Check for TX connected */
	Status = XDp_TxIsConnected(InstancePtr->DpPtr);

	return Status;
}
Exemple #2
0
/**
 * This function is the interrupt handler for the XDp driver operating in TX
 * mode.
 *
 * When an interrupt happens, it first detects what kind of interrupt happened,
 * then decides which callback function to invoke.
 *
 * @param	InstancePtr is a pointer to the XDp instance.
 *
 * @return	None.
 *
 * @note	None.
 *
*******************************************************************************/
static void XDp_TxInterruptHandler(XDp *InstancePtr)
{
	u32 IntrStatus;
	u8 HpdEventDetected;
	u8 HpdPulseDetected;
	u32 HpdDuration;
	u32 IntrMask;

	/* Determine what kind of interrupt occurred.
	 * Note: XDP_TX_INTERRUPT_STATUS is an RC (read-clear) register. */
	IntrStatus = XDp_ReadReg(InstancePtr->Config.BaseAddr,
						XDP_TX_INTERRUPT_STATUS);
	IntrStatus &= ~XDp_ReadReg(InstancePtr->Config.BaseAddr,
						XDP_TX_INTERRUPT_MASK);
	IntrMask = XDp_ReadReg(InstancePtr->Config.BaseAddr,
						XDP_TX_INTERRUPT_MASK);

	HpdEventDetected = IntrStatus & XDP_TX_INTERRUPT_STATUS_HPD_EVENT_MASK;
	HpdPulseDetected = IntrStatus &
				XDP_TX_INTERRUPT_STATUS_HPD_PULSE_DETECTED_MASK;

	if (HpdEventDetected) {
		/* Mask interrupts while event handling is taking place. API
		 * will error out in case of a disconnection event anyway. */
		XDp_WriteReg(InstancePtr->Config.BaseAddr,
			XDP_TX_INTERRUPT_MASK, IntrMask |
			XDP_TX_INTERRUPT_MASK_HPD_EVENT_MASK);

		InstancePtr->TxInstance.HpdEventHandler(
				InstancePtr->TxInstance.HpdEventCallbackRef);
	}
	else if (HpdPulseDetected && XDp_TxIsConnected(InstancePtr)) {
		/* Mask interrupts while event handling is taking place. */
		XDp_WriteReg(InstancePtr->Config.BaseAddr,
			XDP_TX_INTERRUPT_MASK, IntrMask |
			XDP_TX_INTERRUPT_MASK_HPD_PULSE_DETECTED_MASK);

		/* The source device must debounce the incoming HPD signal by
		 * sampling the value at an interval greater than 0.500 ms. An
		 * HPD pulse should be of width 0.5 ms - 1.0 ms. */
		HpdDuration = XDp_ReadReg(InstancePtr->Config.BaseAddr,
							XDP_TX_HPD_DURATION);
		if (HpdDuration >= 500) {
			InstancePtr->TxInstance.HpdPulseHandler(
				InstancePtr->TxInstance.HpdPulseCallbackRef);
		}
	}

	/* Unmask previously masked interrupts once handling is done. */
	XDp_WriteReg(InstancePtr->Config.BaseAddr, XDP_TX_INTERRUPT_MASK,
								IntrMask);
}
/**
 * This function is called when a Hot-Plug-Detect (HPD) event is received by the
 * DisplayPort TX core. The XDP_TX_INTERRUPT_STATUS_HPD_EVENT_MASK bit of the
 * core's XDP_TX_INTERRUPT_STATUS register indicates that an HPD event has
 * occurred.
 *
 * @param	InstancePtr is a pointer to the XDp instance.
 *
 * @return	None.
 *
 * @note	Use the XDp_TxSetHpdEventHandler driver function to set this
 *		function as the handler for HPD pulses.
 *
*******************************************************************************/
static void Dptx_HpdEventHandler(void *InstancePtr)
{
	XDp *XDp_InstancePtr = (XDp *)InstancePtr;

	if (XDp_TxIsConnected(XDp_InstancePtr)) {
		xil_printf("+===> HPD connection event detected.\n");

		Dptx_Run(XDp_InstancePtr);
	}
	else {
		xil_printf("+===> HPD disconnection event detected.\n\n");
	}
}
Exemple #4
0
/**
*
* This function starts the DisplayPort Transmitter Subsystem including all
* sub-cores.
*
* @param	InstancePtr is a pointer to the XDpTxSs core instance.
*
* @return
*		- XST_SUCCESS, if DP TX Subsystem and its included sub-cores
*		configured successfully.
*		- XST_FAILURE, otherwise.
*
* @note		None.
*
******************************************************************************/
u32 XDpTxSs_Start(XDpTxSs *InstancePtr)
{
	u32 Status;
	u32 Index;
	u8 SinkTotal;
#if (XPAR_XDUALSPLITTER_NUM_INSTANCES > 0)
	u8 VertSplit;
#endif

	/* Verify arguments. */
	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid((InstancePtr->UsrOpt.MstSupport == 0) ||
				(InstancePtr->UsrOpt.MstSupport == 1));

	/* Check for downstream device connected */
	if (!XDp_TxIsConnected(InstancePtr->DpPtr)) {
		xdbg_printf(XDBG_DEBUG_GENERAL,"SS ERR: RX device "
				"is not connected!\n\r");
		return XST_FAILURE;
	}

	/* Check RX device is MST capable */
	Status = XDp_TxMstCapable(InstancePtr->DpPtr);
	if ((Status == XST_SUCCESS) && (InstancePtr->Config.MstSupport)) {
		if (InstancePtr->UsrOpt.MstSupport <
					InstancePtr->Config.MstSupport) {
			/* Enable SST mode when RX is MST */
			InstancePtr->UsrOpt.MstSupport = 0;

			/* set maximum number of streams to one */
			InstancePtr->UsrOpt.NumOfStreams = 1;
			xdbg_printf(XDBG_DEBUG_GENERAL,"SS INFO: Setting "
				"to SST even though RX device is with MST "
					"capable!\n\r");
		}
		else {
			/* Enable MST mode */
			InstancePtr->UsrOpt.MstSupport =
					InstancePtr->Config.MstSupport;

			/* Restore maximum number of supported streams */
			InstancePtr->UsrOpt.NumOfStreams =
					InstancePtr->Config.NumMstStreams;
			xdbg_printf(XDBG_DEBUG_GENERAL,"SS INFO: RX device "
					"is with MST capable!\n\r");
		}
	}
	else {
		/* Enable SST mode */
		InstancePtr->UsrOpt.MstSupport = 0;

		/* set maximum number of streams to one */
		InstancePtr->UsrOpt.NumOfStreams = 1;
		xdbg_printf(XDBG_DEBUG_GENERAL,"SS INFO: RX device "
			"is with SST capable. OR Design supports only SST "
				"mode.\n\r");
	}

	/* Start DisplayPort sub-core configuration */
	Status = XDpTxSs_DpTxStart(InstancePtr->DpPtr,
			InstancePtr->UsrOpt.MstSupport,
				InstancePtr->UsrOpt.Bpc,
					InstancePtr->UsrOpt.VmId);
	if (Status != XST_SUCCESS) {
		xdbg_printf(XDBG_DEBUG_GENERAL,"SS ERR: DP Start failed "
			"in %s!\n\r",
				InstancePtr->UsrOpt.MstSupport?"MST":"SST");
		return Status;
	}

	/* Align video mode being set in DisplayPort */
	InstancePtr->UsrOpt.VmId =
			InstancePtr->DpPtr->TxInstance.MsaConfig[0].Vtm.VmId;

	/* Set number of stream to number of sinks found. Make sure that sink
	 * total does not exceed total number supported streams in by Subsystem
	 * configuration.
	 */
	if (InstancePtr->UsrOpt.MstSupport) {
		SinkTotal = InstancePtr->DpPtr->TxInstance.Topology.SinkTotal;
		InstancePtr->UsrOpt.NumOfStreams =
		(SinkTotal > InstancePtr->UsrOpt.NumOfStreams)?
			InstancePtr->UsrOpt.NumOfStreams:SinkTotal;
	}

#if (XPAR_XDUALSPLITTER_NUM_INSTANCES > 0)
	if (InstancePtr->DsPtr) {
		/* Check video mode and MST support */
		if ((InstancePtr->UsrOpt.VmId == XVIDC_VM_UHD2_60_P)
				&& (InstancePtr->UsrOpt.MstSupport)) {

			/* Vertical split mode */
			VertSplit = (TRUE);
		}
		else {
			/* Bypass mode */
			VertSplit = (FALSE);
		}

		/* Setup Dual Splitter in either bypass/vertical split mode */
		Status = XDpTxSs_DsSetup(InstancePtr->DsPtr, VertSplit,
				&InstancePtr->DpPtr->TxInstance.MsaConfig[0]);
		if (Status != XST_SUCCESS) {
			xdbg_printf(XDBG_DEBUG_GENERAL,"SS ERR: DS start "
				"failed!\n\r");
			return Status;
		}
	}
#endif

	/* Setup VTC */
	for (Index = 0; Index < InstancePtr->UsrOpt.NumOfStreams; Index++) {
		if (InstancePtr->VtcPtr[Index]) {
			Status = XDpTxSs_VtcSetup(InstancePtr->VtcPtr[Index],
			&InstancePtr->DpPtr->TxInstance.MsaConfig[Index]);
			if (Status != XST_SUCCESS) {
				xdbg_printf(XDBG_DEBUG_GENERAL,"SS ERR: "
					"VTC%d setup failed!\n\r", Index);
				return Status;
			}
		}
	}

	return XST_SUCCESS;
}