cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
dimiter
Contributor
Contributor
374 Views
Registered: ‎06-10-2018

Ultrazed EV Displayport SDK single lane

I'm trying to implement a bare metal (SDK) configuration of the Displayport with a TPG on an Ultrazed EV.  The problem is the Ultrazed uses a single lane for the DP and the SDK drivers seem to have bugs.

I followed the mods shown here but I don't get any image on the screen.

https://www.xilinx.com/support/answers/71416.html

 

It fails when the DP driver is configured which implies issues with the underlying SDK.

 

The BSP was also modified as shown here:

https://forums.xilinx.com/t5/Video-and-Audio/Standalone-DisplayPort-on-ZCU102/m-p/892936

 

 

It fails with this message:


Starting...
XDpPsu_InitializeTx() failed
Displayport hot-plug event detected
Displayport monitor connected

! 1st power wake-up - AUX write failed.
! 2nd power wake-up - AUX write failed.

! Error getting RX caps.
! Error getting RX caps.

 

 

The default driver was also tested and that also fails with:


RunCfgPntr done.

XDpPsu_InitializeTx
Failed at InitDpDmaSubsystem

DPDMA Video Example Test Failed

 

The board is connected with a DP to HDMI converter to a monitor configured with 1280x720 resolution.

The board was tested with the same cable and monitor with a OS and I can see image on screen so I know the hardware is OK.

The Displayport is configured with a TPG. The design was tested on a U96 board so I know it works. 

1.png

 

2.png

 

#include "xdpdma.h"			
#include "xscugic.h"		
#include "xdppsu.h"			
#include "xavbuf.h"    		
#include "xavbuf_clk.h"		
#include "xscugic.h"		
#include "displayport.h"

XDpPsu dppsu;
XDpDma dpdma;

#define ARMA53_32 1

static int dummy_user_data = 0;

int displayport_init() {
	XDpPsu_Config *dppsu_config;
	XAVBuf avbuf;
	XDpDma_Config *dpdma_config;

	if ( (dppsu_config = XDpPsu_LookupConfig(XPAR_PSU_DP_DEVICE_ID)) == NULL) {
		xil_printf("XDpPsu_LookupConfig() failed\r\n");
		return XST_FAILURE;
	}
	XDpPsu_CfgInitialize(&dppsu, dppsu_config, dppsu_config->BaseAddr);
	XAVBuf_CfgInitialize(&avbuf, dppsu_config->BaseAddr, XPAR_PSU_DP_DEVICE_ID);
	if ( (dpdma_config = XDpDma_LookupConfig(XPAR_PSU_DPDMA_DEVICE_ID)) == NULL) {
		xil_printf("XDpDma_LookupConfig() failed\r\n");
		return XST_FAILURE;
	}
	XDpDma_CfgInitialize(&dpdma, dpdma_config);

	if (XDpPsu_InitializeTx(&dppsu) != XST_SUCCESS) {
		xil_printf("XDpPsu_InitializeTx() failed\r\n");
		return XST_FAILURE;
	}

	XDpDma_SetQOS(&dpdma, 11);
	if (XAVBuf_SetInputLiveVideoFormat(&avbuf, INPUT_VIDEO_FORMAT) != XST_SUCCESS) {
		xil_printf("XAVBuf_SetInputLiveVideoFormat() failed\r\n");
		return XST_FAILURE;
	}
	XAVBuf_EnableVideoBuffers(&avbuf, 1);
	if (XAVBuf_SetOutputVideoFormat(&avbuf, INPUT_VIDEO_FORMAT) != XST_SUCCESS) {
		xil_printf("XAVBuf_SetOutputVideoFormat() failed\r\n");
		return XST_FAILURE;
	}
	XAVBuf_InputVideoSelect(&avbuf, XAVBUF_VIDSTREAM1_LIVE, XAVBUF_VIDSTREAM2_NONE);
	XAVBuf_ConfigureOutputVideo(&avbuf);
	XAVBuf_SetBlenderAlpha(&avbuf, 0, 0); 	// Disable the global alpha
	XDpPsu_CfgMsaEnSynchClkMode(&dppsu, 0);
	XAVBuf_SetAudioVideoClkSrc(&avbuf, XAVBUF_PL_CLK, XAVBUF_PS_CLK);
	XAVBuf_SoftReset(&avbuf);

	xil_printf("Displayport initialized\r\n");

	return XST_SUCCESS;
}

int displayport_setup_interrupts() {
	XScuGic	ic;
	XScuGic_Config *ic_config;

	u32 interrupt_mask = XDPPSU_INTR_HPD_IRQ_MASK | XDPPSU_INTR_HPD_EVENT_MASK;

	XDpPsu_WriteReg(dppsu.Config.BaseAddr, XDPPSU_INTR_DIS, 0xFFFFFFFF);
	XDpPsu_WriteReg(dppsu.Config.BaseAddr, XDPPSU_INTR_MASK, 0xFFFFFFFF);

	XDpPsu_SetHpdEventHandler(&dppsu, displayport_hpd_event_isr, &dummy_user_data);
	XDpPsu_SetHpdPulseHandler(&dppsu, displayport_hpd_pulse_isr, &dummy_user_data);

	if ( (ic_config = XScuGic_LookupConfig(XPAR_SCUGIC_0_DEVICE_ID)) == NULL) {
		xil_printf("XScuGic_LookupConfig() failed\r\n");
		return XST_FAILURE;
	}
	if (XScuGic_CfgInitialize(&ic, ic_config, ic_config->CpuBaseAddress) != XST_SUCCESS) {
		xil_printf("XScuGic_CfgInitialize() failed\r\n");
		return XST_FAILURE;
	}

	/* Register ISRs. */
	if (XScuGic_Connect(&ic, DPPSU_INTR_ID,
			(Xil_InterruptHandler) XDpPsu_HpdInterruptHandler, &dppsu) != XST_SUCCESS) {
		xil_printf("XScuGic_Connect() failed\r\n");
		return XST_FAILURE;
	}

	/* Trigger DP interrupts on rising edge. */
	XScuGic_SetPriorityTriggerType(&ic, DPPSU_INTR_ID, 0x0, 0x03);

	/* Connect DPDMA Interrupt */
	if (XScuGic_Connect(&ic, DPDMA_INTR_ID,
			(Xil_ExceptionHandler) XDpDma_InterruptHandler, &dppsu) != XST_SUCCESS) {
		xil_printf("XScuGic_Connect() failed\r\n");
		return XST_FAILURE;
	}

	/* Initialize exceptions. */
	Xil_ExceptionInit();
	Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT,
			(Xil_ExceptionHandler) XScuGic_DeviceInterruptHandler,
			XPAR_SCUGIC_0_DEVICE_ID);

	/* Enable exceptions for interrupts. */
	Xil_ExceptionEnableMask(XIL_EXCEPTION_IRQ);
	Xil_ExceptionEnable();

	/* Enable DP interrupts. */
	XScuGic_Enable(&ic, DPPSU_INTR_ID);
	XDpPsu_WriteReg(dppsu.Config.BaseAddr, XDPPSU_INTR_EN, interrupt_mask);

	/* Enable DPDMA Interrupts */
	XScuGic_Enable(&ic, DPDMA_INTR_ID);
	XDpDma_InterruptEnable(&dpdma, XDPDMA_IEN_VSYNC_INT_MASK);

	return XST_SUCCESS;
}

void displayport_hpd_event_isr() {
	u8 aux_data = 0x1;
	u8 count = 0;
	u32 status;

	xil_printf("Displayport hot-plug event detected\r\n");

	XDpPsu_EnableMainLink(&dppsu, 0);

	if (!XDpPsu_IsConnected(&dppsu)) {
		xil_printf("Displayport monitor disconnected.\n\r");
		return;
	}
	else {
		xil_printf("Displayport monitor connected\n\r");
	}

	if (XDpPsu_AuxWrite(&dppsu, XDPPSU_DPCD_SET_POWER_DP_PWR_VOLTAGE, 1, &aux_data) != XST_SUCCESS) {
		xil_printf("\t! 1st power wake-up - AUX write failed.\n\r");
	}
	if (XDpPsu_AuxWrite(&dppsu, XDPPSU_DPCD_SET_POWER_DP_PWR_VOLTAGE, 1, &aux_data) != XST_SUCCESS) {
		xil_printf("\t! 2nd power wake-up - AUX write failed.\n\r");
	}

	do {
		usleep(100000);
		count++;

		status = display_port_hpd_train();
		if (status == XST_DEVICE_NOT_FOUND) {
			xil_printf("Lost connection\n\r");
			return;
		}
		else if (status != XST_SUCCESS)
			continue;

		displayport_setup_video_stream();
		XDpPsu_EnableMainLink(&dppsu, 1);

		status = XDpPsu_CheckLinkStatus(&dppsu, dppsu.LinkConfig.LaneCount);
		if (status == XST_DEVICE_NOT_FOUND)
			return;
	} while ((status != XST_SUCCESS) && (count < 2));
}

u32 display_port_hpd_train() {
	XDpPsu_LinkConfig *link_config = &dppsu.LinkConfig;

	if (XDpPsu_GetRxCapabilities(&dppsu) != XST_SUCCESS) {
		xil_printf("\t! Error getting RX caps.\n\r");
		return XST_FAILURE;
	}

	if (XDpPsu_SetEnhancedFrameMode(&dppsu,	link_config->SupportEnhancedFramingMode ? 1 : 0) != XST_SUCCESS) {
		xil_printf("\t! EFM set failed.\n\r");
		return XST_FAILURE;
	}

	if (XDpPsu_SetLaneCount(&dppsu, link_config->MaxLaneCount) != XST_SUCCESS) {
		xil_printf("\t! Lane count set failed.\n\r");
		return XST_FAILURE;
	}

	if (XDpPsu_SetLinkRate(&dppsu, link_config->MaxLinkRate) != XST_SUCCESS) {
		xil_printf("\t! Link rate set failed.\n\r");
		return XST_FAILURE;
	}

	if (XDpPsu_SetDownspread(&dppsu, link_config->SupportDownspreadControl)
			!= XST_SUCCESS) {
		xil_printf("\t! Setting downspread failed.\n\r");
		return XST_FAILURE;
	}

	xil_printf("Lane count = %d\n\r", dppsu.LinkConfig.LaneCount);
	xil_printf("Link rate = ");
	switch (dppsu.LinkConfig.LinkRate) {
	case 0x06:
		xil_printf("162Gbps\r\n");
		break;
	case 0x0A:
		xil_printf("270Gbps\r\n");
		break;
	case 0x14:
		xil_printf("540Gbps\r\n");
		break;
	default:
		xil_printf("Unknown\r\n");
	}

	// Link training sequence is done
	xil_printf("Starting Training...\n\r");
	if (XDpPsu_EstablishLink(&dppsu) == XST_SUCCESS)
		xil_printf("Training succeeded.\n\r");
	else
		xil_printf("\t! Training failed.\n\r");

	return XST_SUCCESS;
}

void displayport_setup_video_stream() {
	XDpPsu_MainStreamAttributes *msa_config = &dppsu.MsaConfig;

	XDpPsu_SetColorEncode(&dppsu, COLOR_ENCODING);
	XDpPsu_CfgMsaSetBpc(&dppsu, BPC);
	XDpPsu_CfgMsaUseStandardVideoMode(&dppsu, VIDEO_MODE);

	XAVBuf_SetPixelClock(msa_config->PixelClockHz);

	/* Reset the transmitter. */
	XDpPsu_WriteReg(dppsu.Config.BaseAddr, XDPPSU_SOFT_RESET, 0x1);
	usleep(10);
	XDpPsu_WriteReg(dppsu.Config.BaseAddr, XDPPSU_SOFT_RESET, 0x0);

	XDpPsu_SetMsaValues(&dppsu);
	/* Issuing a soft-reset (AV_BUF_SRST_REG). */
	XDpPsu_WriteReg(dppsu.Config.BaseAddr, 0xB124, 0x3); // Assert reset.
	usleep(10);
	XDpPsu_WriteReg(dppsu.Config.BaseAddr, 0xB124, 0x0); // De-ssert reset.

	XDpPsu_EnableMainLink(&dppsu, 1);
}

void displayport_hpd_pulse_isr() {
	u32 status;
	u8 count = 0;

	xil_printf("Displayport hot-plug pulse detected\r\n");

	if (XDpPsu_CheckLinkStatus(&dppsu, dppsu.LinkConfig.LaneCount) == XST_DEVICE_NOT_FOUND) {
		xil_printf("Lost connection .......... HPD pulse\n\r");
		return;
	}

	xil_printf("Re-training required.\n\r");

	XDpPsu_EnableMainLink(&dppsu, 0);

	do {
		count++;

		status = display_port_hpd_train();
		if (status == XST_DEVICE_NOT_FOUND) {
			xil_printf("Lost connection .......... HPD pulse\n\r");
			return;
		}
		else if (status != XST_SUCCESS) {
			continue;
		}

		displayport_setup_video_stream();
		XDpPsu_EnableMainLink(&dppsu, 1);

		status = XDpPsu_CheckLinkStatus(&dppsu, dppsu.LinkConfig.LaneCount);
		if (status == XST_DEVICE_NOT_FOUND) {
			xil_printf("Lost connection .......... HPD pulse\n\r");
			return;
		}
	} while ((status != XST_SUCCESS) && (count < 2));
}
Tags (2)
0 Kudos
Reply
2 Replies
samk
Moderator
Moderator
332 Views
Registered: ‎10-04-2017

Hi @dimiter,

A few things.


Have you tested the default example design with 1 lane that just sends a 1/2 green screen to verify your BSP setup?

What version of the tools was used to produce your BSP? Is this the same version of SDK being used to produce your application?

 

 

Based on the examples I would say that it is likely you are not getting proper clock/reset to the DP/TX as the processor is having issues communicating with the DP hardblock.

 

The 2 errors you are getting XDpPsu_InitializeTx() failed and ! Error getting RX caps. seem to point to the TX not being active.

Did you build your OS project from the same BSP or a different BSP?

 

https://github.com/Xilinx/embeddedsw/blob/f975a0ea90930587ab55e4d920a31950bd373fa8/XilinxProcessorIPLib/drivers/dppsu/src/xdppsu.c

samk_1-1600175269142.png

Alternatively, you could be having issues as your phy is still programmed for too many lanes.
My suggestion to get closer to your issue is to add print statments to debug the errors.
Example: xil_printf("Lane Mask #%x \n\r",XDPPSU_PHY_STATUS_ALL_LANES_READY_MASK);

It is a known issue as shown in the AR71416 that the lane#s need to be manually changed. This is scheduled to be fixed, but at this point I don't know which version of the tools will include the fix.

 

Thanks,

Sam

 

 

 

 

Don't forget to reply, kudo, and accept as solution.

Xilinx Video Design Hub
2020-09-15 07_15_02-embeddedsw_xdppsu.c at f975a0ea90930587ab55e4d920a31950bd373fa8 · Xilinx_embedde.png
0 Kudos
Reply
dimiter
Contributor
Contributor
299 Views
Registered: ‎06-10-2018

Hi @samk 

Yes, that was the first SDK app that I tried to run.

I am using Vivado 2019.1 and the SDK.

I tested the hardware with a ready made Linux image from Avnet for the Ultrazed EV to verify the hardware and cable work with the HDMI TV.

 

The issue seems to be with the SDK driver. I have not managed to get it working.

It fails with a timeout at :

 

if (XDpPsu_InitializeTx(&dppsu) != XST_SUCCESS) {
xil_printf("XDpPsu_InitializeTx() failed\r\n");
return XST_FAILURE;
}

 

Digging further shows that it fails on the WaitforPHY loop on the BSP fuction.

This is before and after implementing the modifications suggested by Xilinx for a single lane operation.

 

The only issue that I managed to check so far is that the SDK configures by default for MaxLinkRate (540Gbps).

I don't think Ultrazed supports this link rate with a single lane.

I changed it to 162Gbps.

However the PHY initialization still fails.

 

So as it stands the SDK app :

a) Implements the changes suggested by Xilinx for 1 lane operation.

b) Configures the main driver to use 1 lane

c) Configures the main driver to use 162Gbps link rate

d) confirms the lane and link rate via debug calls.

e) fails at PHY init??? but training proceeds successfully and HPD events are also detected

0 Kudos
Reply