This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TMDSEVM6670: Port OK problem on DPS - FPGA connection

Part Number: TMDSEVM6670

Hello team,

We're trying to connect a TMDSEVM6670 with a Kintex-7 FPGA Connecitivity Kit (KC705 with IP Core Gen4).

Unfortunatelly we're stuck at Port OK when program jumps into a loop waiting for proper bit value.

What we have already tested succesfully:
DSP loopback DIO example with ISR (this example I have modified for our needs)
DSP - DSP connection with DIO packets sending in both sides.
FPGA loopback DIO example

Our goal is to make a 1x mode connection using one lane with a data rate of 3.125Gbps.

Q1: I think that the refclk is 312.5MHz by default on this kit but I'm not sure - any hint how to check it?

Q2: I have checked a lot of device settings on DPS side but well, maybe I have forgotten about something important to set... I will be grateful for any tip or what might be important from the Port OK point of view. Any hints or ideas?

Q3: In sprugw1b.pdf Table 3-182 I have read that:

PRESCALAR_SRV_CLK - The default value of 31 is for an ip_clk frequency of 312.5 MHz.
For different frequencies of ip_clk, use the formula:
ip_clk_frequency (in MHz) /10 rounded to the nearest integer.

In the DIO with ISR loopback example it is set to 0x21 which is 33 in dec.
The question is: why?
I have read in e2e that it is CPU/3 but not sure if it's true.

Q4: Moreover, does it have any realtion with RefClk used in Table 3-7?

Here are my device settings from the DSP side (if you need more settings or any info I could provide, let me know):

#ifndef __LINUX_USER_SPACE
    void
#else
    CSL_SrioHandle hSrio,
    uint32_t       srioSerdesVAddr
#endif
)
{
	portsNum = 1;
	/* Get the CSL SRIO Handle. */
	hSrio = CSL_SRIO_Open (0);

	if (hSrio == NULL)
        return -1;

    /* Code to disable SRIO reset isolation */
    if (CSL_PSC_isModuleResetIsolationEnabled(CSL_PSC_LPSC_SRIO))
    {
    	CSL_PSC_disableModuleResetIsolation(CSL_PSC_LPSC_SRIO);
    }

    /* Disable the SRIO Global block */
   	CSL_SRIO_GlobalDisable (hSrio);

   	/* Disable each of the individual SRIO blocks. */
   	for(unsigned int i = 0; i <= 9; i++)
   	{
   		CSL_SRIO_DisableBlock(hSrio, i);
   	}

    /* Set boot complete to be 0; we are not done with the initialization. */
	CSL_SRIO_SetBootComplete(hSrio, 0);

    /* Now enable the SRIO block and all the individual blocks also. */
    CSL_SRIO_GlobalEnable (hSrio);
    for(unsigned int i = 0; i <= 9; i++)
    {
    	CSL_SRIO_EnableBlock(hSrio,i);
    }

    /* Configure SRIO ports to operate in normal mode. :) */
    CSL_SRIO_SetNormalMode(hSrio, 0);
    //CSL_SRIO_SetNormalMode(hSrio, 1);
    //CSL_SRIO_SetNormalMode(hSrio, 2);
    //CSL_SRIO_SetNormalMode(hSrio, 3);

	/* Enable Automatic Priority Promotion of response packets. */
	CSL_SRIO_EnableAutomaticPriorityPromotion(hSrio);

	/* Set the SRIO Prescalar select to operate in the range of 44.7 to 89.5 */
	CSL_SRIO_SetPrescalarSelect (hSrio, 0);

#ifndef __LINUX_USER_SPACE
    /* Unlock the Boot Configuration Kicker */
    CSL_BootCfgUnlockKicker();

    /* Assuming the link rate is 3125; program the PLL accordingly. */
    CSL_BootCfgSetSRIOSERDESConfigPLL (0x229); //MPY (PLL Multiplier) = 5x

    /* Configure the SRIO SERDES Receive Configuration. */
    CSL_BootCfgSetSRIOSERDESRxConfig (0, 0x00440495); //RATESCALE = 0.5
    //CSL_BootCfgSetSRIOSERDESRxConfig (1, 0x00440495);
    //CSL_BootCfgSetSRIOSERDESRxConfig (2, 0x00440495);
    //CSL_BootCfgSetSRIOSERDESRxConfig (3, 0x00440495);

    /* Configure the SRIO SERDES Transmit Configuration. */
    CSL_BootCfgSetSRIOSERDESTxConfig (0, 0x00180795); //RATESCALE = 0.5
    //CSL_BootCfgSetSRIOSERDESTxConfig (1, 0x00180795);
    //CSL_BootCfgSetSRIOSERDESTxConfig (2, 0x00180795);
    //CSL_BootCfgSetSRIOSERDESTxConfig (3, 0x00180795);
#endif

    /* Loop around till the SERDES PLL is not locked. */
    while (1)
    {
    	uint32_t    status;
    	/* Get the SRIO SERDES Status */
    	CSL_BootCfgGetSRIOSERDESStatus(&status);
    	if (status & 0x1)
    	{
    		break;
    	}
    }

    /* Clear the LSU pending interrupts. */
	CSL_SRIO_ClearLSUPendingInterrupt (hSrio, 0xFFFFFFFF, 0xFFFFFFFF);

	/* Set the Device Information */
	CSL_SRIO_SetDeviceInfo (hSrio, DEVICE_ID1_16BIT, DEVICE_VENDOR_ID, DEVICE_REVISION);

	/* Set the Assembly Information */
	CSL_SRIO_SetAssemblyInfo(hSrio, DEVICE_ASSEMBLY_ID, DEVICE_ASSEMBLY_VENDOR_ID, DEVICE_ASSEMBLY_REVISION, DEVICE_ASSEMBLY_INFO);

	/*  The SRIO RL file is missing the Re-transmit Suppression Support (Bit6) field definition */
	peFeatures.isBridge                          = 0;
	peFeatures.isEndpoint                        = 0;
	peFeatures.isProcessor                       = 1;
	peFeatures.isSwitch                          = 0;
	peFeatures.isMultiport                       = 0;
	peFeatures.isFlowArbiterationSupported       = 0;
	peFeatures.isMulticastSupported              = 0;
	peFeatures.isExtendedRouteConfigSupported    = 0;
	peFeatures.isStandardRouteConfigSupported    = 1;
	peFeatures.isFlowControlSupported            = 1;
	peFeatures.isCRFSupported                    = 0;
	peFeatures.isCTLSSupported                   = 1;
	peFeatures.isExtendedFeaturePtrValid         = 1;
	peFeatures.numAddressBitSupported            = 1;
	CSL_SRIO_SetProcessingElementFeatures (hSrio, &peFeatures);

	/* Configure the source operation CAR */
	memset ((void *) &opCar, 0, sizeof (opCar));
	opCar.portWriteOperationSupport = 1;
	opCar.atomicClearSupport        = 1;
	opCar.atomicSetSupport          = 1;
	opCar.atomicDecSupport          = 1;
	opCar.atomicIncSupport          = 1;
	opCar.atomicTestSwapSupport     = 1;
	opCar.doorbellSupport           = 1;
	opCar.dataMessageSupport        = 1;
	opCar.writeResponseSupport      = 1;
	opCar.streamWriteSupport        = 1;
	opCar.writeSupport              = 1;
	opCar.readSupport               = 1;
	opCar.dataStreamingSupport      = 1;
	CSL_SRIO_SetSourceOperationCAR (hSrio, &opCar);

	/* Configure the destination operation CAR */
	memset ((void *) &opCar, 0, sizeof (opCar));
	opCar.portWriteOperationSupport  = 1;
	opCar.doorbellSupport            = 1;
	opCar.dataMessageSupport         = 1;
	opCar.writeResponseSupport       = 1;
	opCar.streamWriteSupport         = 1;
	opCar.writeSupport               = 1;
	opCar.readSupport                = 1;
	CSL_SRIO_SetDestOperationCAR (hSrio, &opCar);

    /* Set the 16 bit and 8 bit identifier for the SRIO Device. */
    CSL_SRIO_SetDeviceIDCSR (hSrio, DEVICE_ID1_8BIT, DEVICE_ID1_16BIT);

    /* Enable TLM Base Routing Information for Maintainance Requests & ensure that
     * the BRR's can be used by all the ports. */
    CSL_SRIO_SetTLMPortBaseRoutingInfo(hSrio, 0, 1, 1, 1, 0);
    CSL_SRIO_SetTLMPortBaseRoutingInfo(hSrio, 0, 2, 1, 1, 0);
    CSL_SRIO_SetTLMPortBaseRoutingInfo(hSrio, 0, 3, 1, 1, 0);
    //CSL_SRIO_SetTLMPortBaseRoutingInfo(hSrio, 1, 0, 1, 1, 0);

    SRIO_PLM_IMPL_CONTROL   implControl;
    CSL_SRIO_GetPortPLMImplSpecificControl (hSrio, 0, &implControl);

    //##############################################################
    implControl.useIdle1 = 1;
    CSL_SRIO_SetPLMPortImplSpecificControl (hSrio, 0, &implControl);
	//##############################################################

    /* Configure the Base Routing Register to ensure that all packets matching the
     * Device Identifier & the Secondary Device Id are admitted. */
    CSL_SRIO_SetTLMPortBaseRoutingPatternMatch(hSrio, 0, 1, DEVICE_ID2_16BIT, 0xFFFF);
    //CSL_SRIO_SetTLMPortBaseRoutingPatternMatch(hSrio, 0, 2, DEVICE_ID3_16BIT, 0xFFFF);
    //CSL_SRIO_SetTLMPortBaseRoutingPatternMatch(hSrio, 0, 3, DEVICE_ID4_16BIT, 0xFFFF);
    //CSL_SRIO_SetTLMPortBaseRoutingPatternMatch(hSrio, 1, 0, DEVICE_ID2_8BIT,  0xFF);

    /* We need to open the Garbage collection queues in the QMSS. This is done to ensure that
     * these queues are not opened by another system entity. */
    for (unsigned int i = 0; i < 6; i++)
    {
        /* Open the Garabage queues */
        garbageQueueHnd[i] = queueHnd = Qmss_queueOpen (Qmss_QueueType_GENERAL_PURPOSE_QUEUE, QMSS_PARAM_NOT_SPECIFIED, &isAllocated);
        if (queueHnd < 0)
            return -1;

        /* Make sure the queue has not been opened already; we dont the queues to be shared by some other
         * entity in the system. */
        if (isAllocated > 1)
            return -1;
    }

    /* Set the Transmit Garbage Collection Information. */
    CSL_SRIO_SetTxGarbageCollectionInfo (
    		hSrio,
			Qmss_getQIDFromHandle(garbageQueueHnd[0]),
			Qmss_getQIDFromHandle(garbageQueueHnd[1]),
			Qmss_getQIDFromHandle(garbageQueueHnd[2]),
			Qmss_getQIDFromHandle(garbageQueueHnd[3]),
			Qmss_getQIDFromHandle(garbageQueueHnd[4]),
			Qmss_getQIDFromHandle(garbageQueueHnd[5])
			);

    /* Set the Host Device Identifier. */
    CSL_SRIO_SetHostDeviceID (hSrio, DEVICE_ID1_16BIT);

    /* Configure the component tag CSR */
    CSL_SRIO_SetCompTagCSR (hSrio, 0x00000000);

    /* Configure the PLM for all the ports. */
	for (unsigned int i = 0; i < portsNum; i++)
	{
	    /* Set the PLM Port Silence Timer. */
        CSL_SRIO_SetPLMPortSilenceTimer (hSrio, i, 0x2);

        /* TODO: We need to ensure that the Port 0 is configured to support both
         * the 2x and 4x modes. The Port Width field is read only. So here we simply
         * ensure that the Input and Output ports are enabled. */
        CSL_SRIO_EnableInputPort (hSrio, i);
        CSL_SRIO_EnableOutputPort (hSrio, i);

        /* Set the PLM Port Discovery Timer. */
        CSL_SRIO_SetPLMPortDiscoveryTimer (hSrio, i, 0x2);

        /* Reset the Port Write Reception capture. */
        CSL_SRIO_SetPortWriteReceptionCapture(hSrio, i, 0x0);
    }

    /* Set the Port link timeout CSR */
    CSL_SRIO_SetPortLinkTimeoutCSR (hSrio, 0x000FFF);

    /* Set the Port General CSR: Only executing as Master Enable */
    CSL_SRIO_SetPortGeneralCSR (hSrio, 0, 1, 0);

    /* Clear the sticky register bits. */
    CSL_SRIO_SetLLMResetControl (hSrio, 1);

    /* Set the device id to be 0 for the Maintenance Port-Write operation
     * to report errors to a system host. */
    CSL_SRIO_SetPortWriteDeviceId (hSrio, 0x0, 0x0, 0x0);

    /* Set the Data Streaming MTU */
    CSL_SRIO_SetDataStreamingMTU (hSrio, 64);

    /* Configure the path mode for the ports. */
    for(unsigned int i = 0; i < portsNum; i++)
    {
    	CSL_SRIO_SetPLMPortPathControlMode (hSrio, i, 0);
    }

    /* Set the LLM Port IP Prescalar. */
    CSL_SRIO_SetLLMPortIPPrescalar (hSrio, 0x21); //0x21: 333MHZ - default: 0x31 which is 312.5MHz

    /* Enable the peripheral. */
    CSL_SRIO_EnablePeripheral(hSrio);

    /* Configuration has been completed. */
    CSL_SRIO_SetBootComplete(hSrio, 1);

#ifndef SIMULATOR_SUPPORT
    /* This code checks if the ports are operational or not. The functionality is not supported
     * on the simulator. */
	for(unsigned int i = 0; i < portsNum; i++)
	{
		while (CSL_SRIO_IsPortOk (hSrio, i) != TRUE)
		{
		}
	}
#endif

    /* Set all the queues 0 to operate at the same priority level and to send packets onto Port 0 */
    for (unsigned int i = 0 ; i < 16; i++)
    {
    	CSL_SRIO_SetTxQueueSchedInfo(hSrio, i, 0, 0);
    }

    /* Set the Doorbell route to determine which routing table is to be used
     * This configuration implies that the Interrupt Routing Table is configured as
     * follows:-
     *  Interrupt Destination 0 - INTDST 16
     *  Interrupt Destination 1 - INTDST 17
     *  Interrupt Destination 2 - INTDST 18
     *  Interrupt Destination 3 - INTDST 19
     */
    CSL_SRIO_SetDoorbellRoute(hSrio, 0);

    /* Route the Doorbell interrupts.
     *  Doorbell Register 0 - All 16 Doorbits are routed to Interrupt Destination 0.
     *  Doorbell Register 1 - All 16 Doorbits are routed to Interrupt Destination 1.
     *  Doorbell Register 2 - All 16 Doorbits are routed to Interrupt Destination 2.
     *  Doorbell Register 3 - All 16 Doorbits are routed to Interrupt Destination 3. */
//    for (i = 0; i < 16; i++)
//    {
//        CSL_SRIO_RouteDoorbellInterrupts(hSrio, 0, i, 0);
//        CSL_SRIO_RouteDoorbellInterrupts(hSrio, 1, i, 1);
//        CSL_SRIO_RouteDoorbellInterrupts(hSrio, 2, i, 2);
//        CSL_SRIO_RouteDoorbellInterrupts(hSrio, 3, i, 3);
//    }

    /* Initialization has been completed. */
    return 0;

Thanks,,

Maciej