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.

PCIE_K2HC66BiosExampleProject - PCIe PHY Loopback in K2HEVM

Expert 1800 points

Hello,

Is that possible to verify PCIe PHY loopback using the PCIE_K2HC66BiosExampleProject in the K2HEVM?

Are there any hardware requirements?

Please clarify.

Regards

Rams

  • Rams,

    The PCIE_K2HC66BiosExampleProject is written for PCIE test between 2 K2H EVMs. If you want to do loopback, please check PCIE user guide (sprugs6d) section 2.12. For pipe loopback, you need 2 cards. For PHY loopback, you need one card. Also, you need to change the SW for that.

    Regards, Eric

     

  • Hi,

    Thanks for the response.  I have been referring PCIE user guide for PHY loopback.  I have modified the pcie_sample.c in the example project for PHY Loopback.

    I have modified ths pcie_sample.c to include the sequence as described in the user guide.

    When I run on the EVM, it is stuck in pcieWaitLinkUp.  Please see the output below.

    Could you please clarify if I am doing something wrong?

    I am attaching the modified pcie_sample.c which contains additional settings for PHY loopback as recommended.

    Thanks

    Rams

    /*  ============================================================================
     *   Copyright (c) Texas Instruments Incorporated 2010-2013
     * 
     *  Redistribution and use in source and binary forms, with or without 
     *  modification, are permitted provided that the following conditions 
     *  are met:
     *
     *    Redistributions of source code must retain the above copyright 
     *    notice, this list of conditions and the following disclaimer.
     *
     *    Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the 
     *    documentation and/or other materials provided with the   
     *    distribution.
     *
     *    Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
     *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
     *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
     *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
     *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
     *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
     *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
     *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     *
    */
    
    
    /**
     *   @file  pcie_sample.c
     *
     *   @brief   
     *      This is the PCIe example code.   
     *
     */
    
    /** 
     * In the PCIe sample example two Shannon EVMs are used to test the PCIe driver. 
     * As described in the following figure, Shannon 1 is configured as a Root Complex
     * and Shannon 2 is configured as End Point.
     *
     *       Shannon 1                                       Shannon 2
     *   ------------------                             -------------------
     *   |                |                             |                 |
     *   |   Root         |          PCIe Link          |  End Point      |
     *   |   Complex      | <-------------------------->|                 |
     *   |                |                             |                 |
     *   ------------------                             -------------------
     *  
     * Once the PCIe link is established, the following sequence of actions will happen:
     *  - Shannon 1 sends data to Shannon 2
     *  - Shannon 2 waits to receive all the data
     *  - Shannon 2 sends the data back to Shannon 1
     *  - Shannon 1 waits to receive all the data
     *  - Shannon 1 verifies if the received data matches the sent data and declares test pass or fail.
     *
     */
     
    #define ENABLE_PHYLOOPBACK
    #include "pcie_sample.h"
    #include <ti/drv/pcie/device/pcie_device.h>
    
    /* Use regular "printf" when not using BIOS */
    //#include <xdc/runtime/System.h>
    #define System_printf printf
    #include <stdio.h>
    
    #include <ti/csl/csl_bootcfgAux.h>
    #include <ti/csl/csl_cacheAux.h>
    #include <ti/csl/csl_chip.h>
    #include <ti/csl/csl_xmcAux.h>
    
    
    #pragma DATA_SECTION(dstBuf, ".dstBufSec")
    /* Cache coherence: Align must be a multiple of cache line size (L2=128 bytes, L1=64 bytes) to operate with cache enabled. */
    /* Aligning to 256 bytes because the PCIe inbound offset register masks the last 8bits of the buffer address  */
    #pragma DATA_ALIGN(dstBuf, 256)
    /* last element in the buffer is a marker that indicates the buffer status: full/empty */
    #define PCIE_EXAMPLE_MAX_CACHE_LINE_SIZE 128
    #define PCIE_EXAMPLE_UINT32_SIZE           4 /* preprocessor #if requires a real constant, not a sizeof() */
    
    #define PCIE_EXAMPLE_DSTBUF_BYTES ((PCIE_BUFSIZE_APP + 1) * PCIE_EXAMPLE_UINT32_SIZE)
    #define PCIE_EXAMPLE_DSTBUF_REM (PCIE_EXAMPLE_DSTBUF_BYTES % PCIE_EXAMPLE_MAX_CACHE_LINE_SIZE)
    #define PCIE_EXAMPLE_DSTBUF_PAD (PCIE_EXAMPLE_DSTBUF_REM ? (PCIE_EXAMPLE_MAX_CACHE_LINE_SIZE - PCIE_EXAMPLE_DSTBUF_REM) : 0)
    struct dstBuf_s {
      volatile uint32_t buf[PCIE_BUFSIZE_APP + 1];
      /* Cache coherence: Must pad to cache line size in order to enable cacheability */
    #if PCIE_EXAMPLE_DSTBUF_PAD
      uint8_t padding[PCIE_EXAMPLE_DSTBUF_PAD];
    #endif
    } dstBuf;
    
    #define PCIE_EXAMPLE_BUF_EMPTY 0
    #define PCIE_EXAMPLE_BUF_FULL  1
    
    /* Does not need to be aligned (even for cache) since it is only accessed locally */
    uint32_t srcBuf[PCIE_BUFSIZE_APP];
    
    extern volatile unsigned int cregister TSCL;
    
    /* Global config variable that controls
       the PCIe mode. It is global so it can be poked
       from CCS. It should be set either to EP or RC. */
    pcieMode_e PcieModeGbl = pcie_RC_MODE;
    
    #if defined(DEVICE_K2K) || defined(DEVICE_K2H)
    /**********************************************************************************
     * FUNCTION PURPOSE: Function for updating register value with mask
     **********************************************************************************
     * DESCRIPTION: Function for updating register value with mask
     **********************************************************************************/ 
    static void write_32_mask(volatile uint32_t  base_addr,
                                  uint32_t           offset,
                                  uint32_t           mask,
                                  uint32_t           write_data)
    {
        uint32_t read_data, data;
        read_data = (*(volatile uint32_t *)(base_addr + offset));
        data = (write_data & ~mask ) | (read_data & mask);
        (*(uint32_t *) ((base_addr + offset))) = data;
    }
    
    
    void reg_poll(volatile unsigned int addr, volatile unsigned int poll_val, volatile unsigned int masked_bits)
    {
      volatile unsigned int read_data;
    
      read_data = (*(unsigned int *) (addr));
      read_data = read_data & masked_bits;
      while (read_data != (poll_val & masked_bits))
        {
          read_data = (*(unsigned int *) (addr));
          read_data = read_data & masked_bits;
        }
    }
    
    void pcieSSDefSbSerdesSetup(volatile uint32_t  base_addr) 
    {
        write_32_mask(base_addr, 0x000,0xffff00ff,0x00000800);
        write_32_mask(base_addr, 0x0060,0xff000000,0x00041c5c);
        write_32_mask(base_addr, 0x0064,0x000000ff,0x0343c700);
        write_32_mask(base_addr, 0x006c,0xffffff00,0x00000012);
        write_32_mask(base_addr, 0x0068,0xff00ffff,0x00070000);
        write_32_mask(base_addr, 0x0078,0xffff00ff,0x0000c000);
    
        write_32_mask(base_addr, 0x0200,0xffffff00,0x00000000);
        write_32_mask(base_addr, 0x0204,0x00ffff00,0x5e000080);
        write_32_mask(base_addr, 0x0208,0xffffff00,0x00000006);
        write_32_mask(base_addr, 0x0210,0xffffff00,0x00000023);
        write_32_mask(base_addr, 0x0214,0x00ff0000,0x2e003060);
        write_32_mask(base_addr, 0x0218,0x00ffffff,0x76000000);
        write_32_mask(base_addr, 0x022c,0xff00ff00,0x00100002);
        write_32_mask(base_addr, 0x02a0,0x0000ffff,0xffee0000);
        write_32_mask(base_addr, 0x02a4,0xffffff00,0x0000000f);
        write_32_mask(base_addr, 0x0204,0x00ffffff,0x5e000000);
        write_32_mask(base_addr, 0x0208,0xffffff00,0x00000006);
        write_32_mask(base_addr, 0x0278,0xffff00ff,0x00002000);
        write_32_mask(base_addr, 0x0280,0xff00ff00,0x00280028);
        write_32_mask(base_addr, 0x0284,0x00000000,0x2d0f0385);
        write_32_mask(base_addr, 0x0250,0x00ffffff,0xd0000000);    
        write_32_mask(base_addr, 0x0284,0xffffff00,0x00000085);
        write_32_mask(base_addr, 0x0294,0x00ffffff,0x20000000);
        
        write_32_mask(base_addr, 0x0400,0xffffff00,0x00000000);
        write_32_mask(base_addr, 0x0404,0x00ffff00,0x5e000080);
        write_32_mask(base_addr, 0x0408,0xffffff00,0x00000006);
        write_32_mask(base_addr, 0x0410,0xffffff00,0x00000023);
        write_32_mask(base_addr, 0x0414,0x00ff0000,0x2e003060);
        write_32_mask(base_addr, 0x0418,0x00ffffff,0x76000000);
        write_32_mask(base_addr, 0x042c,0xff00ff00,0x00100002);
        write_32_mask(base_addr, 0x04a0,0x0000ffff,0xffee0000);
        write_32_mask(base_addr, 0x04a4,0xffffff00,0x0000000f);
        write_32_mask(base_addr, 0x0404,0x00ffffff,0x5e000000);
        write_32_mask(base_addr, 0x0408,0xffffff00,0x00000006);
        write_32_mask(base_addr, 0x0478,0xffff00ff,0x00002000);
        write_32_mask(base_addr, 0x0480,0xff00ff00,0x00280028);
        write_32_mask(base_addr, 0x0484,0x00000000,0x2d0f0385);
        write_32_mask(base_addr, 0x0450,0x00ffffff,0xd0000000);   
        write_32_mask(base_addr, 0x0494,0x00ffffff,0x20000000);
        
        write_32_mask(base_addr, 0x0604,0xffffff00,0x00000080);
        write_32_mask(base_addr, 0x0600,0xffffff00,0x00000000);
        write_32_mask(base_addr, 0x0604,0x00ffffff,0x5e000000);
        write_32_mask(base_addr, 0x0608,0xffffff00,0x00000006);
        write_32_mask(base_addr, 0x0610,0xffffff00,0x00000023);
        write_32_mask(base_addr, 0x0614,0x00ff0000,0x2e003060);
        write_32_mask(base_addr, 0x0618,0x00ffffff,0x76000000);
        write_32_mask(base_addr, 0x062c,0xff00ff00,0x00100002);
        write_32_mask(base_addr, 0x06a0,0x0000ffff,0xffee0000);
        write_32_mask(base_addr, 0x06a4,0xffffff00,0x0000000f);
        write_32_mask(base_addr, 0x0604,0x00ffffff,0x5e000000);
        write_32_mask(base_addr, 0x0608,0xffffff00,0x00000006);
        write_32_mask(base_addr, 0x0678,0xffff00ff,0x00002000);
        write_32_mask(base_addr, 0x0680,0xff00ff00,0x00280028);
        write_32_mask(base_addr, 0x0684,0x00000000,0x2d0f0385);
        write_32_mask(base_addr, 0x0650,0x00ffffff,0xd0000000);
        write_32_mask(base_addr, 0x0694,0x00ffffff,0x20000000);
        
        write_32_mask(base_addr, 0x0800,0xffffff00,0x00000000);
        write_32_mask(base_addr, 0x0804,0x00ffff00,0x5e000080);
        write_32_mask(base_addr, 0x0808,0xffffff00,0x00000006);
        write_32_mask(base_addr, 0x0810,0xffffff00,0x00000023);
        write_32_mask(base_addr, 0x0814,0x00ff0000,0x2e003060);
        write_32_mask(base_addr, 0x0818,0x00ffffff,0x76000000);
        write_32_mask(base_addr, 0x082c,0xff00ff00,0x00100002);
        write_32_mask(base_addr, 0x08a0,0x0000ffff,0xffee0000);
        write_32_mask(base_addr, 0x08a4,0xffffff00,0x0000000f);
        write_32_mask(base_addr, 0x0804,0x00ffffff,0x5e000000);
        write_32_mask(base_addr, 0x0808,0xffffff00,0x00000006);
        write_32_mask(base_addr, 0x0878,0xffff00ff,0x00002000);
        write_32_mask(base_addr, 0x0880,0xff00ff00,0x00280028);
        write_32_mask(base_addr, 0x0884,0x00000000,0x2d0f0385);
        write_32_mask(base_addr, 0x0850,0x00ffffff,0xd0000000); 
        write_32_mask(base_addr, 0x0894,0x00ffffff,0x20000000);
        
        write_32_mask(base_addr, 0x0a00,0xffff00ff,0x00000100);
        write_32_mask(base_addr, 0x0a08,0xff000000,0x00e12c08);
        write_32_mask(base_addr, 0x0a0c,0xffffff00,0x00000081);
        write_32_mask(base_addr, 0x0a18,0xff00ffff,0x00e80000);
        write_32_mask(base_addr, 0x0a30,0x00ffff00,0x002f2f00);
        write_32_mask(base_addr, 0x0a48,0xff0000ff,0x00e3ce00);
        write_32_mask(base_addr, 0x0a4c,0x0000ffff,0xac820000);
        write_32_mask(base_addr, 0x0a54,0x00ffffff,0xc0000000);
        write_32_mask(base_addr, 0x0a58,0xffff0000,0x00001441);
        write_32_mask(base_addr, 0x0a84,0xffff0000,0x00000301); 
        
        write_32_mask(base_addr, 0x0a8c,0x0000ffff,0x81030000);    
        write_32_mask(base_addr, 0x0a90,0xffff0000,0x00006001);    
        write_32_mask(base_addr, 0x0a94,0x00ffffff,0x01000000);    
        write_32_mask(base_addr, 0x0aa0,0x00ffffff,0x81000000);    
        write_32_mask(base_addr, 0x0abc,0x00ffffff,0xff000000);    
        write_32_mask(base_addr, 0x0ac0,0xffffff00,0x0000008b);    
        
        write_32_mask(base_addr, 0x0000,0xffffff00,0x00000003);    
        write_32_mask(base_addr, 0x0a00,0xffffff00,0x0000009f);
        
    }
    #endif
    /*****************************************************************************
     * Function: Power domain configuration
     ****************************************************************************/
    pcieRet_e pciePowerCfg(void)
    {
      /* Turn on the PCIe power domain */
      if (CSL_PSC_getPowerDomainState (CSL_PSC_PD_PCIE) != PSC_PDSTATE_ON) {
        /* Enable the domain */
        CSL_PSC_enablePowerDomain (CSL_PSC_PD_PCIE);
        /* Enable MDCTL */
        CSL_PSC_setModuleNextState (CSL_PSC_LPSC_PCIE, PSC_MODSTATE_ENABLE);
        /* Apply the domain */
        CSL_PSC_startStateTransition (CSL_PSC_PD_PCIE);
        /* Wait for it to finish */
        while (! CSL_PSC_isStateTransitionDone (CSL_PSC_PD_PCIE));
      } else {
        System_printf ("Power domain is already enabled.  You probably re-ran without device reset (which is OK)\n");
      }
    
      return pcie_RET_OK;
    }
    
    /*****************************************************************************
     * Function: Utility function to introduce delay 
     ****************************************************************************/
    void cycleDelay (uint32_t count)
    {
      uint32_t sat;
    
      if (count <= 0)
        return;
    
      sat = TSCL + count;
      while (TSCL < sat);
    }
    
    /*****************************************************************************
     * Function: Serdes configuration 
     ****************************************************************************/
    pcieRet_e pcieSerdesCfg(void)
    {
    #if !defined(DEVICE_K2K) && !defined(DEVICE_K2H)
      uint16_t cfg;
    #endif
      
    #if !defined(DEVICE_K2K) && !defined(DEVICE_K2H)
      /* Provide PLL reference clock to SERDES inside PCIESS
         Program PLL settings and enable PLL from PCIe SERDES.*/
      cfg = 0x01C9; /* value based on PCIe userguide */
    
      CSL_BootCfgSetPCIEConfigPLL(cfg);
    #else /* !DEVICE_K2K && !DEVICE_K2H */
    #ifndef  SIMULATOR_SUPPORT
       //CSL_PciessDefSbSerdesSetup();
       pcieSSDefSbSerdesSetup(CSL_PCIE_SERDES_CFG_REGS);
    #endif
    #endif
      /*Wait for PLL to lock (3000 CLKIN1 cycles) */
      cycleDelay(10000);
      
      return pcie_RET_OK;
    }
    
    /*****************************************************************************
     * Function: Enable/Disable LTSSM (Link Training)
     ****************************************************************************/
    pcieRet_e pcieLtssmCtrl(Pcie_Handle handle, uint8_t enable)
    {
      pcieCmdStatusReg_t    cmdStatus;
      pcieRegisters_t       setRegs;
      pcieRegisters_t       getRegs;
      pcieRet_e retVal;
    
      memset (&cmdStatus,    0, sizeof(cmdStatus));
      memset (&setRegs,      0, sizeof(setRegs));
      memset (&getRegs,      0, sizeof(getRegs));
    
      getRegs.cmdStatus = &cmdStatus;
      if ((retVal = Pcie_readRegs (handle, pcie_LOCATION_LOCAL, &getRegs)) != pcie_RET_OK) 
      {
        System_printf ("Read CMD STATUS register failed!\n");
        return retVal;
      }
      
      if(enable)
        cmdStatus.ltssmEn = 1;
      else  
        cmdStatus.ltssmEn = 0;
    
      setRegs.cmdStatus = &cmdStatus;   
      
      if ((retVal = Pcie_writeRegs (handle, pcie_LOCATION_LOCAL, &setRegs)) != pcie_RET_OK) 
      {
        System_printf ("SET CMD STATUS register failed!\n");
        return retVal;
      }
    
      return pcie_RET_OK;
    }
    
    
    /*****************************************************************************
     * Function: Configure PCIe in Root Complex Mode
     ****************************************************************************/
    pcieRet_e pcieCfgRC(Pcie_Handle handle)
    {
      pcieRet_e retVal;
    
      pcieCmdStatusReg_t     cmdStatus;
      pcieObSizeReg_t        obSize;
      pcieGen2Reg_t          gen2;
      pcieType1Bar32bitIdx_t type1Bar32bitIdx;
      pcieStatusCmdReg_t     statusCmd;
      pcieDevStatCtrlReg_t   devStatCtrl;
      pcieAccrReg_t          accr;
                     
      pcieRegisters_t        setRegs;
      pcieRegisters_t        getRegs;
    
      memset (&cmdStatus,        0, sizeof(cmdStatus));
      memset (&obSize,           0, sizeof(obSize));
      memset (&gen2,             0, sizeof(gen2));
      memset (&type1Bar32bitIdx, 0, sizeof(type1Bar32bitIdx));
      memset (&statusCmd,        0, sizeof(statusCmd));
      memset (&devStatCtrl,      0, sizeof(devStatCtrl));
      memset (&accr,             0, sizeof(accr));
    
      /*Disable link training*/
      if ((retVal = pcieLtssmCtrl(handle, FALSE)) != pcie_RET_OK) 
      {
        System_printf ("Failed to disable Link Training!\n");
        return retVal;
      }
      
      /* Configure the size of the translation regions */   
      memset (&setRegs, 0, sizeof(setRegs));
      memset (&getRegs, 0, sizeof(getRegs));
      
      obSize.size = pcie_OB_SIZE_8MB;
      setRegs.obSize = &obSize;
      
      if ((retVal = Pcie_writeRegs (handle, pcie_LOCATION_LOCAL, &setRegs)) != pcie_RET_OK) 
      {
        System_printf ("SET OB_SIZE register failed!\n");
        return retVal;
      }
         
      /* Setting PL_GEN2 */   
      memset (&setRegs, 0, sizeof(setRegs));
      gen2.numFts = 0xF;
      gen2.dirSpd = 0x0;
      gen2.lnEn   = 1;
      setRegs.gen2 = &gen2;
      
      if ((retVal = Pcie_writeRegs (handle, pcie_LOCATION_LOCAL, &setRegs)) != pcie_RET_OK) 
      {
        System_printf ("SET GEN2 register failed!\n");
        return retVal;
      }
      
      /* Configure BAR Masks */   
      /* First need to enable writing on BAR mask registers */
      memset (&setRegs, 0, sizeof(setRegs));
      memset (&getRegs, 0, sizeof(getRegs));
      memset (&cmdStatus,  0, sizeof(cmdStatus));
    
      getRegs.cmdStatus = &cmdStatus;
      if ((retVal = Pcie_readRegs (handle, pcie_LOCATION_LOCAL, &getRegs)) != pcie_RET_OK) 
      {
        System_printf ("Read CMD STATUS register failed!\n");
        return retVal;
      }
      cmdStatus.dbi = 1;
      setRegs.cmdStatus = &cmdStatus;   
      
      if ((retVal = Pcie_writeRegs (handle, pcie_LOCATION_LOCAL, &setRegs)) != pcie_RET_OK) 
      {
        System_printf ("SET CMD STATUS register failed!\n");
        return retVal;
      }
      
      /* Configure Masks*/
      memset (&setRegs, 0, sizeof(setRegs));
      type1Bar32bitIdx.reg.reg32 = PCIE_BAR_MASK;
      setRegs.type1Bar32bitIdx = &type1Bar32bitIdx;
    
      /* BAR 0 */
      type1Bar32bitIdx.idx = 0; /* configure BAR 0*/
      if ((retVal = Pcie_writeRegs (handle, pcie_LOCATION_LOCAL, &setRegs)) != pcie_RET_OK) 
      {
        System_printf ("SET BAR MASK register failed!\n");
        return retVal;
      }
      
      /* BAR 1 */
      type1Bar32bitIdx.idx = 1; /* configure BAR 1*/
      if ((retVal = Pcie_writeRegs (handle, pcie_LOCATION_LOCAL, &setRegs)) != pcie_RET_OK) 
      {
        System_printf ("SET BAR MASK register failed!\n");
        return retVal;
      }
      
      /* Disable writing on BAR Masks */
      memset (&setRegs, 0, sizeof(setRegs));
      memset (&getRegs, 0, sizeof(getRegs));
      memset (&cmdStatus,  0, sizeof(cmdStatus));
    
      getRegs.cmdStatus = &cmdStatus;
      if ((retVal = Pcie_readRegs (handle, pcie_LOCATION_LOCAL, &getRegs)) != pcie_RET_OK) 
      {
        System_printf ("Read CMD STATUS register failed!\n");
        return retVal;
      }
      cmdStatus.dbi = 0;
      setRegs.cmdStatus = &cmdStatus;   
      
      if ((retVal = Pcie_writeRegs (handle, pcie_LOCATION_LOCAL, &setRegs)) != pcie_RET_OK) 
      {
        System_printf ("SET CMD STATUS register failed!\n");
        return retVal;
      }
    
      /* Enable memory access and mastership of the bus */
      memset (&setRegs, 0, sizeof(setRegs));
      memset (&getRegs, 0, sizeof(getRegs));
    
      getRegs.statusCmd = &statusCmd;
      if ((retVal = Pcie_readRegs (handle, pcie_LOCATION_LOCAL, &getRegs)) != pcie_RET_OK) 
      {
        System_printf ("Read Status Comand register failed!\n");
        return retVal;
      }
      statusCmd.memSp  = 1;
      statusCmd.busMs  = 1;
      statusCmd.resp   = 1;
      statusCmd.serrEn = 1;
      setRegs.statusCmd = &statusCmd;   
      
      if ((retVal = Pcie_writeRegs (handle, pcie_LOCATION_LOCAL, &setRegs)) != pcie_RET_OK) 
      {
        System_printf ("SET Status Command register failed!\n");
        return retVal;
      }
    
      /* Enable Error Reporting */
      memset (&setRegs, 0, sizeof(setRegs));
      memset (&getRegs, 0, sizeof(getRegs));
    
      getRegs.devStatCtrl = &devStatCtrl;
      if ((retVal = Pcie_readRegs (handle, pcie_LOCATION_LOCAL, &getRegs)) != pcie_RET_OK) 
      {
        System_printf ("Regad Device Status Control register failed!\n");
        return retVal;
      }
     
      devStatCtrl.reqRp = 1;
      devStatCtrl.fatalErRp = 1;
      devStatCtrl.nFatalErRp = 1;
      devStatCtrl.corErRp = 1;
      setRegs.devStatCtrl = &devStatCtrl;   
      
      if ((retVal = Pcie_writeRegs (handle, pcie_LOCATION_LOCAL, &setRegs)) != pcie_RET_OK) 
      {
        System_printf ("SET Device Status Control register failed!\n");
        return retVal;
      }
    
      /* Enable ECRC */
      memset (&setRegs, 0, sizeof(setRegs));
      
      accr.chkEn=1;
      accr.chkCap=1;
      accr.genEn=1;
      accr.genCap=1;
      setRegs.accr = &accr;
    
      if ((retVal = Pcie_writeRegs (handle, pcie_LOCATION_LOCAL, &setRegs)) != pcie_RET_OK) 
      {
        System_printf ("SET ACCR register failed!\n");
        return retVal;
      }
    
      return pcie_RET_OK;
    }
    
    /*****************************************************************************
     * Function: Configure PCIe in End Point Mode
     ****************************************************************************/
    pcieRet_e pcieCfgEP(Pcie_Handle handle)
    {
      pcieRet_e retVal;
    
      pcieCmdStatusReg_t     cmdStatus;
      pcieObSizeReg_t        obSize;
      pcieGen2Reg_t          gen2;
      pcieType0Bar32bitIdx_t type0Bar32bitIdx;
      pcieStatusCmdReg_t     statusCmd;
      pcieDevStatCtrlReg_t   devStatCtrl;
      pcieAccrReg_t          accr;
                     
      pcieRegisters_t        setRegs;
      pcieRegisters_t        getRegs;
    
      memset (&cmdStatus,        0, sizeof(cmdStatus));
      memset (&obSize,           0, sizeof(obSize));
      memset (&gen2,             0, sizeof(gen2));
      memset (&type0Bar32bitIdx, 0, sizeof(type0Bar32bitIdx));
      memset (&statusCmd,        0, sizeof(statusCmd));
      memset (&devStatCtrl,      0, sizeof(devStatCtrl));
      memset (&accr,             0, sizeof(accr));
    
      /*Disable link training*/
      if ((retVal = pcieLtssmCtrl(handle, FALSE)) != pcie_RET_OK) 
      {
        System_printf ("Failed to disable Link Training!\n");
        return retVal;
      }
      
      /* Configure the size of the translation regions */   
      memset (&setRegs, 0, sizeof(setRegs));
      memset (&getRegs, 0, sizeof(getRegs));
      
      obSize.size = pcie_OB_SIZE_8MB;
      setRegs.obSize = &obSize;
      
      if ((retVal = Pcie_writeRegs (handle, pcie_LOCATION_LOCAL, &setRegs)) != pcie_RET_OK) 
      {
        System_printf ("SET OB_SIZE register failed!\n");
        return retVal;
      }
         
      /* Setting PL_GEN2 */   
      memset (&setRegs, 0, sizeof(setRegs));
      gen2.numFts = 0xF;
      gen2.dirSpd = 0x0;
      gen2.lnEn   = 1;
      setRegs.gen2 = &gen2;
      
      if ((retVal = Pcie_writeRegs (handle, pcie_LOCATION_LOCAL, &setRegs)) != pcie_RET_OK) 
      {
        System_printf ("SET GEN2 register failed!\n");
        return retVal;
      }
      
      /* Configure BAR Masks */   
      /* First need to enable writing on BAR mask registers */
      memset (&setRegs, 0, sizeof(setRegs));
      memset (&getRegs, 0, sizeof(getRegs));
      memset (&cmdStatus,  0, sizeof(cmdStatus));
    
      getRegs.cmdStatus = &cmdStatus;
      if ((retVal = Pcie_readRegs (handle, pcie_LOCATION_LOCAL, &getRegs)) != pcie_RET_OK) 
      {
        System_printf ("Read CMD STATUS register failed!\n");
        return retVal;
      }
      cmdStatus.dbi = 1;
      setRegs.cmdStatus = &cmdStatus;   
      
      if ((retVal = Pcie_writeRegs (handle, pcie_LOCATION_LOCAL, &setRegs)) != pcie_RET_OK) 
      {
        System_printf ("SET CMD STATUS register failed!\n");
        return retVal;
      }
      
      /* Configure Masks*/
      memset (&setRegs, 0, sizeof(setRegs));
      type0Bar32bitIdx.reg.reg32 = PCIE_BAR_MASK;
      setRegs.type0Bar32bitIdx = &type0Bar32bitIdx;
    
      /* BAR 0 */
      type0Bar32bitIdx.idx = 0; /* configure BAR 0*/
      if ((retVal = Pcie_writeRegs (handle, pcie_LOCATION_LOCAL, &setRegs)) != pcie_RET_OK) 
      {
        System_printf ("SET BAR MASK register failed!\n");
        return retVal;
      }
      
      /* BAR 1 */
      type0Bar32bitIdx.idx = 1; /* configure BAR 1*/
      if ((retVal = Pcie_writeRegs (handle, pcie_LOCATION_LOCAL, &setRegs)) != pcie_RET_OK) 
      {
        System_printf ("SET BAR MASK register failed!\n");
        return retVal;
      }
      
      /* Disable writing on BAR Masks */
      memset (&setRegs, 0, sizeof(setRegs));
      memset (&getRegs, 0, sizeof(getRegs));
      memset (&cmdStatus,  0, sizeof(cmdStatus));
    
      getRegs.cmdStatus = &cmdStatus;
      if ((retVal = Pcie_readRegs (handle, pcie_LOCATION_LOCAL, &getRegs)) != pcie_RET_OK) 
      {
        System_printf ("Read CMD STATUS register failed!\n");
        return retVal;
      }
      cmdStatus.dbi = 0;
      setRegs.cmdStatus = &cmdStatus;   
      
      if ((retVal = Pcie_writeRegs (handle, pcie_LOCATION_LOCAL, &setRegs)) != pcie_RET_OK) 
      {
        System_printf ("SET CMD STATUS register failed!\n");
        return retVal;
      }
    
      /* Enable memory access and mastership of the bus */
      memset (&setRegs, 0, sizeof(setRegs));
      memset (&getRegs, 0, sizeof(getRegs));
    
      getRegs.statusCmd = &statusCmd;
      if ((retVal = Pcie_readRegs (handle, pcie_LOCATION_LOCAL, &getRegs)) != pcie_RET_OK) 
      {
        System_printf ("Read Status Comand register failed!\n");
        return retVal;
      }
      statusCmd.memSp  = 1;
      statusCmd.busMs  = 1;
      statusCmd.resp   = 1;
      statusCmd.serrEn = 1;
      setRegs.statusCmd = &statusCmd;   
      
      if ((retVal = Pcie_writeRegs (handle, pcie_LOCATION_LOCAL, &setRegs)) != pcie_RET_OK) 
      {
        System_printf ("SET Status Command register failed!\n");
        return retVal;
      }
    
      /* Enable Error Reporting */
      memset (&setRegs, 0, sizeof(setRegs));
      memset (&getRegs, 0, sizeof(getRegs));
    
      getRegs.devStatCtrl = &devStatCtrl;
      if ((retVal = Pcie_readRegs (handle, pcie_LOCATION_LOCAL, &getRegs)) != pcie_RET_OK) 
      {
        System_printf ("Regad Device Status Control register failed!\n");
        return retVal;
      }
     
      devStatCtrl.reqRp = 1;
      devStatCtrl.fatalErRp = 1;
      devStatCtrl.nFatalErRp = 1;
      devStatCtrl.corErRp = 1;
      setRegs.devStatCtrl = &devStatCtrl;   
      
      if ((retVal = Pcie_writeRegs (handle, pcie_LOCATION_LOCAL, &setRegs)) != pcie_RET_OK) 
      {
        System_printf ("SET Device Status Control register failed!\n");
        return retVal;
      }
    
      /* Enable ECRC */
      memset (&setRegs, 0, sizeof(setRegs));
      
      accr.chkEn=1;
      accr.chkCap=1;
      accr.genEn=1;
      accr.genCap=1;
      setRegs.accr = &accr;
    
      if ((retVal = Pcie_writeRegs (handle, pcie_LOCATION_LOCAL, &setRegs)) != pcie_RET_OK) 
      {
        System_printf ("SET ACCR register failed!\n");
        return retVal;
      }
    
      return pcie_RET_OK;
    }
    
    /*****************************************************************************
     * Function: Configure and enable Outbound Address Translation 
     ****************************************************************************/
    pcieRet_e pcieObTransCfg(Pcie_Handle handle, uint32_t obAddrLo, uint32_t obAddrHi, uint8_t region)
    {
    
      pcieRet_e retVal;
    
      pcieRegisters_t      setRegs;
      pcieRegisters_t      getRegs;
    
      pcieCmdStatusReg_t   cmdStatus;
    
      memset (&setRegs,   0, sizeof(setRegs));
      memset (&getRegs,   0, sizeof(getRegs));
      memset (&cmdStatus, 0, sizeof(cmdStatus));
    
      /* Set outbound offset registers */
      if ((retVal = Pcie_cfgObOffset(handle, obAddrLo, obAddrHi, region)) != pcie_RET_OK) 
      {
        System_printf ("Failed to configure ObOffset registers!\n");
        return retVal;
      }
    
      /*enable Outbound address translation*/
      memset (&setRegs,    0, sizeof(setRegs));
      memset (&getRegs,    0, sizeof(getRegs));
    
      getRegs.cmdStatus = &cmdStatus;
      if ((retVal = Pcie_readRegs (handle, pcie_LOCATION_LOCAL, &getRegs)) != pcie_RET_OK) 
      {
        System_printf ("Read CMD STATUS register failed!\n");
        return retVal;
      }
      cmdStatus.obXltEn = 1;
      setRegs.cmdStatus = &cmdStatus;   
      
      if ((retVal = Pcie_writeRegs (handle, pcie_LOCATION_LOCAL, &setRegs)) != pcie_RET_OK) 
      {
        System_printf ("SET CMD STATUS register failed!\n");
        return retVal;
      }
    
      return pcie_RET_OK;
    }
    
    
    /*****************************************************************************
     * Function: Configure and enable Inbound Address Translation 
     ****************************************************************************/
    pcieRet_e pcieIbTransCfg(Pcie_Handle handle, pcieIbTransCfg_t *ibCfg)
    {
      pcieRet_e retVal;
    
      pcieRegisters_t      setRegs;
      pcieRegisters_t      getRegs;
    
      pcieCmdStatusReg_t   cmdStatus;
    
      memset (&setRegs,   0, sizeof(setRegs));
      memset (&getRegs,   0, sizeof(getRegs));
      memset (&cmdStatus, 0, sizeof(cmdStatus));
    
      /* Set outbound offset registers */
      if ((retVal = Pcie_cfgIbTrans(handle, ibCfg)) != pcie_RET_OK) 
      {
        System_printf ("Failed to configure Inbound Translation registers!\n");
        return retVal;
      }
    
      /*enable Inbound address translation*/
      memset (&setRegs,    0, sizeof(setRegs));
      memset (&getRegs,    0, sizeof(getRegs));
    
      getRegs.cmdStatus = &cmdStatus;
      if ((retVal = Pcie_readRegs (handle, pcie_LOCATION_LOCAL, &getRegs)) != pcie_RET_OK) 
      {
        System_printf ("Read CMD STATUS register failed!\n");
        return retVal;
      }
      cmdStatus.ibXltEn = 1;
      setRegs.cmdStatus = &cmdStatus;   
      
      if ((retVal = Pcie_writeRegs (handle, pcie_LOCATION_LOCAL, &setRegs)) != pcie_RET_OK) 
      {
        System_printf ("SET CMD STATUS register failed!\n");
        return retVal;
      }
    
      return pcie_RET_OK;
    }
    
    /*****************************************************************************
     * Function: Configure PHY Loopback
     ****************************************************************************/
    pcieRet_e pcieSerDesLoopback(Pcie_Handle handle)
    {
      pcieRet_e retVal;
    
      pcieRegisters_t      setRegs;
      pcieRegisters_t      getRegs;
    
      pcieSerdesCfg0Reg_t   serdesCfg0;
      pcieSerdesCfg1Reg_t   serdesCfg1;
    
      memset (&setRegs,   0, sizeof(setRegs));
      memset (&getRegs,   0, sizeof(getRegs));
      memset (&serdesCfg0, 0, sizeof(serdesCfg0));
      memset (&serdesCfg1, 0, sizeof(serdesCfg1));
    
    
      getRegs.serdesCfg0 = &serdesCfg0;
      getRegs.serdesCfg1 = &serdesCfg1;
      if ((retVal = Pcie_readRegs (handle, pcie_LOCATION_LOCAL, &getRegs)) != pcie_RET_OK)
      {
        System_printf ("Read SerdesCfg register failed!\n");
        return retVal;
      }
      serdesCfg0.txLoopback = 0x2;
      serdesCfg0.rxLoopback = 0x3;
      serdesCfg0.rxLos = 0;
      serdesCfg1.txLoopback = 0x2;
      serdesCfg1.rxLoopback = 0x3;
      serdesCfg1.rxLos = 0;
    
      setRegs.serdesCfg0 = &serdesCfg0;
      setRegs.serdesCfg1 = &serdesCfg1;
    
      if ((retVal = Pcie_writeRegs (handle, pcie_LOCATION_LOCAL, &setRegs)) != pcie_RET_OK)
      {
        System_printf ("SET SerdesCfg PHYLOOPBACK failed!\n");
        return retVal;
      }
    
      return pcie_RET_OK;
    }
    
    /*****************************************************************************
     * Function: Configure POLL ACTIVE STATE
     ****************************************************************************/
    pcieRet_e pcieForceLink(Pcie_Handle handle)
    {
      pcieRet_e retVal;
    
      pcieRegisters_t      setRegs;
      pcieRegisters_t      getRegs;
    
      pciePlForceLinkReg_t   plForceLink;
    
    
      memset (&setRegs,   0, sizeof(setRegs));
      memset (&getRegs,   0, sizeof(getRegs));
      memset (&plForceLink, 0, sizeof(plForceLink));
    
    
      getRegs.plForceLink = &plForceLink;
    
      if ((retVal = Pcie_readRegs (handle, pcie_LOCATION_LOCAL, &getRegs)) != pcie_RET_OK)
      {
        System_printf ("Read plForceLink register failed!\n");
        return retVal;
      }
      plForceLink.lnkState = 0x2;
      plForceLink.forceLink = 0x1;
    
      setRegs.plForceLink = &plForceLink;
    
      if ((retVal = Pcie_writeRegs (handle, pcie_LOCATION_LOCAL, &setRegs)) != pcie_RET_OK)
      {
        System_printf ("SET plForceLink failed!\n");
        return retVal;
      }
    
      return pcie_RET_OK;
    }
    
    /*****************************************************************************
     * Function: Initialize application buffers
     ****************************************************************************/
    void pcieInitAppBuf(void)
    {
      uint32_t i;
      
      for (i=0; i<PCIE_BUFSIZE_APP; i++)
      {
        dstBuf.buf[i] = 0;	
        srcBuf[i] = i;	
      }
      
      dstBuf.buf[PCIE_BUFSIZE_APP] = PCIE_EXAMPLE_BUF_EMPTY;
    }
    
    /*****************************************************************************
     * Function: Check LTSSM status and wait for the link to be up
     ****************************************************************************/
    void pcieWaitLinkUp(Pcie_Handle handle)
    {
      pcieRegisters_t  getRegs;
      pcieDebug0Reg_t  debug0;
      
      memset (&debug0,  0, sizeof(debug0));
      memset (&getRegs, 0, sizeof(getRegs));
      
      uint8_t ltssmState = 0;
      getRegs.debug0 = &debug0;
      if (Pcie_readRegs (handle, pcie_LOCATION_LOCAL, &getRegs) != pcie_RET_OK)
      {
           System_printf ("Read LTSSM state failed!\n");
           return;
      }
      System_printf ("Debug0 Value #: 0x%08x\n\n",  debug0);
      while(ltssmState != pcie_LTSSM_L0)
      {
        cycleDelay(100);
        getRegs.debug0 = &debug0;
        if (Pcie_readRegs (handle, pcie_LOCATION_LOCAL, &getRegs) != pcie_RET_OK) 
        {
          System_printf ("Read LTSSM state failed!\n");
          return;
        }
        ltssmState = debug0.ltssmState;
      }
    }
    
    
    
    /*****************************************************************************
     * Function: Converts a core local L2 address to a global L2 address 
     *   Input addr:  L2 address to be converted to global.
     *   return:  uint32_t   Global L2 address
     *****************************************************************************/
    uint32_t pcieConvert_CoreLocal2GlobalAddr (uint32_t  addr)
    {
      uint32_t coreNum;
    
      /* Get the core number. */
      coreNum = CSL_chipReadReg(CSL_CHIP_DNUM); 
      
      /* Compute the global address. */
      return ((1 << 28) | (coreNum << 24) | (addr & 0x00ffffff));
    }    
    
    
    /*****************************************************************************
     * Function: Main 
     ****************************************************************************/
    void main (void)
    {
      TSCL = 1;
    #if !defined(DEVICE_K2K) && !defined(DEVICE_K2H)
      uint16_t lock=0;
    #endif
      pcieRet_e        retVal;
      pcieIbTransCfg_t ibCfg;
      pcieBarCfg_t     barCfg;
      Pcie_Handle      handle = NULL;
      void             *pcieBase;
      uint32_t    i;
    
      /* Unlock kicker once, and don't relock, because its not multicore safe */
      CSL_BootCfgUnlockKicker();
    
      System_printf ("**********************************************\n");
      System_printf ("*             PCIe Test Start                *\n");
      
      if(PcieModeGbl == pcie_RC_MODE)
        System_printf ("*                RC mode                     *\n");
      else
        System_printf ("*                EP mode                     *\n");
      
      System_printf ("**********************************************\n\n");
      
      System_printf ("Version #: 0x%08x; string %s\n\n", Pcie_getVersion(), Pcie_getVersionStr());
      
      /* Pass device config to LLD */
      if ((retVal = Pcie_init (&pcieInitCfg)) != pcie_RET_OK)
      {
        System_printf ("LLD device configuration failed\n");
        exit(1);
      }
    
      /* Initialize application buffers */
      pcieInitAppBuf();
    
      /* Configure SERDES*/
      if ((retVal = pcieSerdesCfg()) != pcie_RET_OK) {
        System_printf ("PCIe Serdes config failed (%d)\n", (int)retVal);
        exit(1);
      }
    
      /* Set the PCIe mode*/
      if ((retVal = Pcie_setMode(PcieModeGbl)) != pcie_RET_OK) {
        System_printf ("Set PCIe Mode failed (%d)\n", (int)retVal);
        exit(1);
      }
      
      /* Power up PCIe Module */
      if ((retVal = pciePowerCfg()) != pcie_RET_OK) {
        System_printf ("PCIe Power Up failed (%d)\n", (int)retVal);
        exit(1);
      }
    
      System_printf ("PCIe Power Up.\n");
      
      /* Wait until the PCIe SERDES PLL locks */
    #if !defined(DEVICE_K2K) && !defined(DEVICE_K2H)
      while (!lock)
      {
        CSL_BootCfgGetPCIEPLLLock(&lock);
      }                    
    #endif /* !DEVICE_K2K && !DEVICE_K2H */
    
      if ((retVal = Pcie_open(0, &handle)) != pcie_RET_OK) 
      {
        System_printf ("Open failed (%d)\n", (int)retVal);
        exit(1);
      }
    
      System_printf ("PLL configured.\n");
    
      if(PcieModeGbl == pcie_RC_MODE)
      {
        /* Configure application registers for Root Complex*/
        if ((retVal = pcieCfgRC(handle)) != pcie_RET_OK) 
        {
          System_printf ("Failed to configure PCIe in RC mode (%d)\n", (int)retVal);
          exit(1);
        }
    
        /* Configure Address Translation */
        
        barCfg.location = pcie_LOCATION_LOCAL;
        barCfg.mode     = pcie_RC_MODE;
        barCfg.base     = PCIE_IB_LO_ADDR_M;
        barCfg.prefetch = pcie_BAR_NON_PREF;
        barCfg.type     = pcie_BAR_TYPE32;
        barCfg.memSpace = pcie_BAR_MEM_MEM;
        barCfg.idx      = PCIE_BAR_IDX_M;
        
        if ((retVal = Pcie_cfgBar(handle, &barCfg)) != pcie_RET_OK) 
        {
          System_printf ("Failed to configure BAR (%d)\n", (int)retVal);
          exit(1);
        }
    
        ibCfg.ibBar         = PCIE_BAR_IDX_M; /* Match BAR that was configured above*/
        ibCfg.ibStartAddrLo = PCIE_IB_LO_ADDR_M;
        ibCfg.ibStartAddrHi = PCIE_IB_HI_ADDR_M;
        ibCfg.ibOffsetAddr  = (uint32_t)pcieConvert_CoreLocal2GlobalAddr ((uint32_t)dstBuf.buf);
        ibCfg.region        = PCIE_IB_REGION_M;       
    
        if ((retVal = pcieIbTransCfg(handle, &ibCfg)) != pcie_RET_OK) 
        {
          System_printf ("Failed to configure Inbound Translation (%d)\n", (int)retVal);
          exit(1);
        }
        else
        {
          System_printf ("Successfully configured Inbound Translation!\n");
        }
    
        if ((retVal = pcieObTransCfg (handle, PCIE_OB_LO_ADDR_M, PCIE_OB_HI_ADDR_M, PCIE_OB_REGION_M)) != pcie_RET_OK) 
        {
          System_printf ("Failed to configure Outbound Address Translation (%d)\n", (int)retVal);
          exit(1);
        }
        else
        {
          System_printf ("Successfully configured Outbound Translation!\n");
        }
      }
      else
      {
        /* Configure application registers for End Point*/
        if ((retVal = pcieCfgEP(handle)) != pcie_RET_OK) 
        {
          System_printf ("Failed to configure PCIe in EP mode (%d)\n", (int)retVal);
          exit(1);
        }
    
        /* Configure Address Translation */
        
        barCfg.location = pcie_LOCATION_LOCAL;
        barCfg.mode     = pcie_EP_MODE;
        barCfg.base     = PCIE_IB_LO_ADDR_S;
        barCfg.prefetch = pcie_BAR_NON_PREF;
        barCfg.type     = pcie_BAR_TYPE32;
        barCfg.memSpace = pcie_BAR_MEM_MEM;
        barCfg.idx      = PCIE_BAR_IDX_S;
        
        if ((retVal = Pcie_cfgBar(handle, &barCfg)) != pcie_RET_OK) 
        {
          System_printf ("Failed to configure BAR!\n");
          exit(1);
        }
    
        ibCfg.ibBar         = PCIE_BAR_IDX_S; /* Match BAR that was configured above*/
        ibCfg.ibStartAddrLo = PCIE_IB_LO_ADDR_S;
        ibCfg.ibStartAddrHi = PCIE_IB_HI_ADDR_S;
        ibCfg.ibOffsetAddr  = (uint32_t)pcieConvert_CoreLocal2GlobalAddr ((uint32_t)dstBuf.buf);
        ibCfg.region        = PCIE_IB_REGION_S;       
    
        if ((retVal = pcieIbTransCfg(handle, &ibCfg)) != pcie_RET_OK) 
        {
          System_printf ("Failed to configure Inbound Translation!\n", (int)retVal);
          exit(1);
        }
        else
        {
          System_printf ("Successfully configured Inbound Translation!\n");
        }
    
        if ((retVal = pcieObTransCfg (handle, PCIE_OB_LO_ADDR_S, PCIE_OB_HI_ADDR_S, PCIE_OB_REGION_S)) != pcie_RET_OK) 
        {
          System_printf ("Failed to configure Outbound Address Translation!\n", (int)retVal);
          exit(1);
        }
        else
        {
          System_printf ("Successfully configured Outbound Translation!\n");
        }
      }
    
    #ifdef ENABLE_PHYLOOPBACK
      System_printf ("Configure PHY Loopback...\n");
      pcieSerDesLoopback(handle);
    #endif
      System_printf ("Starting link training...\n");
    
      /*Enable link training*/
       if ((retVal = pcieLtssmCtrl(handle, TRUE)) != pcie_RET_OK)
      {
        System_printf ("Failed to Enable Link Training!\n", (int)retVal);
        exit(1);
      }
    #ifdef ENABLE_PHYLOOPBACK
       System_printf ("Force PCIe Link state...\n");
       pcieForceLink(handle);
    #endif
      /* Wait for link to be up */
      System_printf ("PCIe pcieWaitLinkUp...\n");
      pcieWaitLinkUp(handle);
    
    
      System_printf ("Link is up.\n");
    
    
      if(PcieModeGbl == pcie_RC_MODE)
      {
        /**********************************************************************/
        /* Push a single message to the EP then verify that it is echoed back */
        /**********************************************************************/
    
        /* Write from RC to EP                                                */
        if ((retVal = Pcie_getMemSpaceRange (handle, &pcieBase, NULL)) != pcie_RET_OK) {
          System_printf ("getMemSpaceRange failed\n", (int)retVal);
          exit(1);
        }
    
        for (i=0; i<PCIE_BUFSIZE_APP; i++)
        {
          *((volatile uint32_t *)pcieBase + i) = srcBuf[i];
        }
        
        /* Mark that the buffer is full, so EP can process it */
        *((volatile uint32_t *)pcieBase + PCIE_BUFSIZE_APP) = PCIE_EXAMPLE_BUF_FULL;
    
        /* Note on cache coherence: Write back is not necessary because pcieBase is in
           peripheral address space instead of physical memory*/
        
        /* Data sent to EP.
           RC waits for the loopback to be completed and
           receive data back from EP */
    
        do {
          unsigned int key;
    
          /* Disable Interrupts */
          key = _disable_interrupts();
    
          /*  Cleanup the prefetch buffer also. */
          CSL_XMC_invalidatePrefetchBuffer();    
    
          CACHE_invL1d ((void *)dstBuf.buf,  PCIE_EXAMPLE_DSTBUF_BYTES, CACHE_FENCE_WAIT);
          CACHE_invL2  ((void *)dstBuf.buf,  PCIE_EXAMPLE_DSTBUF_BYTES, CACHE_FENCE_WAIT);
    
          /* Reenable Interrupts. */
          _restore_interrupts(key);
    
        } while(dstBuf.buf[PCIE_BUFSIZE_APP] != PCIE_EXAMPLE_BUF_FULL);
    
    
        /* check all the data */
        for (i=0; i<PCIE_BUFSIZE_APP; i++)
        {
          if(dstBuf.buf[i] != srcBuf[i])
          {
            System_printf ("Received data = %d\nTransmited data = %d\nIndex = %d.\n\nTest failed.\n", 
                            dstBuf.buf[i], srcBuf[i], i);
            exit(1);
          }
        }
        
        System_printf ("Root Complex received data.\nTest passed.\n");
      }
      else
      {
        /**********************************************************************/
        /* Wait for a single message from the RC then echo it back            */
        /**********************************************************************/
    
        /* EP waits for the data received from RC */
        do {
          unsigned int key;
    
          /* Disable Interrupts */
          key = _disable_interrupts();
    
          /*  Cleanup the prefetch buffer also. */
          CSL_XMC_invalidatePrefetchBuffer();    
    
          CACHE_invL1d ((void *)dstBuf.buf,  PCIE_EXAMPLE_DSTBUF_BYTES, CACHE_FENCE_WAIT);
          CACHE_invL2  ((void *)dstBuf.buf,  PCIE_EXAMPLE_DSTBUF_BYTES, CACHE_FENCE_WAIT);
    
          /* Reenable Interrupts. */
          _restore_interrupts(key);
    
        } while(dstBuf.buf[PCIE_BUFSIZE_APP] != PCIE_EXAMPLE_BUF_FULL);
    
        System_printf ("End Point received data.\n");
    
        /* Loopback to RC what was written in the DST buffer.
           Write from EP to RC */
        if ((retVal = Pcie_getMemSpaceRange (handle, &pcieBase, NULL)) != pcie_RET_OK) {
          System_printf ("getMemSpaceRange failed\n", (int)retVal);
          exit(1);
        }
    
        for (i=0; i<PCIE_BUFSIZE_APP; i++)
        {
          *((volatile uint32_t *)pcieBase + i) = dstBuf.buf[i];
        }
        
        /* Mark that the buffer is full, so RC can process it */
        *((volatile uint32_t *)pcieBase + PCIE_BUFSIZE_APP) = PCIE_EXAMPLE_BUF_FULL;
    
        /* Note on cache coherence: Write back is not necessary because pcieBase is in
           peripheral address space instead of physical memory*/
    
        System_printf ("End Point sent data to Root Complex, completing the loopback.\nEnd of Test.\n");
      }
    
      exit(0);
    }
    
    

    [C66xx_0] **********************************************

    * PCIe Test Start *
    * RC mode *
    **********************************************

    Version #: 0x02000004; string PCIE LLD Revision: 02.00.00.04:Nov 24 2013:17:35:53

    Power domain is already enabled. You probably re-ran without device reset (which is OK)
    PCIe Power Up.
    PLL configured.
    Successfully configured Inbound Translation!
    Successfully configured Outbound Translation!
    Configure PHY Loopback...
    Starting link training...
    Force PCIe Link state...
    PCIe pcieWaitLinkUp...
    Debug0 Value #: 0x008209f8

  • Hi ,

    Please ignore the Debug0 Value which is printed incorrect.  The LTSSM code is 0x00 (DETECT_QUIET).

    What are the possible reasons for LTSSM state to be in DETECT_QUIET in PHY LOOPBACK configuration?

    Thanks

    Rams

  • Rams,

    I realized that User Guide only given the details for PHY loopback on KS I device. For KS II,

    Configure the SERDES in loopback mode, see below code for: ENABLE_PHYLOOPBACK
    • Then initialize link training (Step 8 in Section 2.11.1.1).
    • Before checking link training status (Step 9 in Section 2.11.1.1), we need to skip
    Detect state in LTSSM and force link to begin with POLL_ACTIVE state.
    – Set 0x2 (POLL_ACTIVE state) in LNK_STATE field of Port Force Link
    Register (PL_FORCE_LINK[LINK_STATE]=0x2).
    – Set 0x1 in FORCE_LINK field of PL_FORCE_LINK register to force the link
    to the state specified by LINK_STATE field
    (PL_FORCE_LINK[FORCE_LINK]=0x1).
    • Then insure link training completion (Step 9 in Section 2.11.1.1)
    • With the initialization above, the PCIESS should be configured in PHY loopback
    mode.

    I tested the below code for loopback on PHY level on K2H EVM. DEBUG0 showed ltssm = 0x11, and I can do inbound/outbound translation (PCIE packet W/R to/from itself).

    pcieMode_e PcieModeGbl = pcie_RC_MODE;
    #define ENABLE_PHYLOOPBACK

    void pcieSSDefSbSerdesSetup(volatile uint32_t  base_addr)
    {
        write_32_mask(base_addr, 0x000,0xffff00ff,0x00000800);
        write_32_mask(base_addr, 0x0060,0xff000000,0x00041c5c);
        write_32_mask(base_addr, 0x0064,0x000000ff,0x0343c700);
        write_32_mask(base_addr, 0x006c,0xffffff00,0x00000012);
        write_32_mask(base_addr, 0x0068,0xff00ffff,0x00070000);
        write_32_mask(base_addr, 0x0078,0xffff00ff,0x0000c000);

        write_32_mask(base_addr, 0x0200,0xffffff00,0x00000000);
        write_32_mask(base_addr, 0x0204,0x00ffff00,0x5e000080);
        write_32_mask(base_addr, 0x0208,0xffffff00,0x00000006);
        write_32_mask(base_addr, 0x0210,0xffffff00,0x00000023);
        write_32_mask(base_addr, 0x0214,0x00ff0000,0x2e003060);
        write_32_mask(base_addr, 0x0218,0x00ffffff,0x76000000);
        write_32_mask(base_addr, 0x022c,0xff00ff00,0x00100002);
        write_32_mask(base_addr, 0x02a0,0x0000ffff,0xffee0000);
        write_32_mask(base_addr, 0x02a4,0xffffff00,0x0000000f);
        write_32_mask(base_addr, 0x0204,0x00ffffff,0x5e000000);
        write_32_mask(base_addr, 0x0208,0xffffff00,0x00000006);
        write_32_mask(base_addr, 0x0278,0xffff00ff,0x00002000);
        write_32_mask(base_addr, 0x0280,0xff00ff00,0x00280028);
        write_32_mask(base_addr, 0x0284,0x00000000,0x2d0f0385);
        write_32_mask(base_addr, 0x0250,0x00ffffff,0xd0000000);   
        write_32_mask(base_addr, 0x0284,0xffffff00,0x00000085);
        write_32_mask(base_addr, 0x0294,0x00ffffff,0x20000000);
       
        write_32_mask(base_addr, 0x0400,0xffffff00,0x00000000);
        write_32_mask(base_addr, 0x0404,0x00ffff00,0x5e000080);
        write_32_mask(base_addr, 0x0408,0xffffff00,0x00000006);
        write_32_mask(base_addr, 0x0410,0xffffff00,0x00000023);
        write_32_mask(base_addr, 0x0414,0x00ff0000,0x2e003060);
        write_32_mask(base_addr, 0x0418,0x00ffffff,0x76000000);
        write_32_mask(base_addr, 0x042c,0xff00ff00,0x00100002);
        write_32_mask(base_addr, 0x04a0,0x0000ffff,0xffee0000);
        write_32_mask(base_addr, 0x04a4,0xffffff00,0x0000000f);
        write_32_mask(base_addr, 0x0404,0x00ffffff,0x5e000000);
        write_32_mask(base_addr, 0x0408,0xffffff00,0x00000006);
        write_32_mask(base_addr, 0x0478,0xffff00ff,0x00002000);
        write_32_mask(base_addr, 0x0480,0xff00ff00,0x00280028);
        write_32_mask(base_addr, 0x0484,0x00000000,0x2d0f0385);
        write_32_mask(base_addr, 0x0450,0x00ffffff,0xd0000000);  
        write_32_mask(base_addr, 0x0494,0x00ffffff,0x20000000);
       
        write_32_mask(base_addr, 0x0604,0xffffff00,0x00000080);
        write_32_mask(base_addr, 0x0600,0xffffff00,0x00000000);
        write_32_mask(base_addr, 0x0604,0x00ffffff,0x5e000000);
        write_32_mask(base_addr, 0x0608,0xffffff00,0x00000006);
        write_32_mask(base_addr, 0x0610,0xffffff00,0x00000023);
        write_32_mask(base_addr, 0x0614,0x00ff0000,0x2e003060);
        write_32_mask(base_addr, 0x0618,0x00ffffff,0x76000000);
        write_32_mask(base_addr, 0x062c,0xff00ff00,0x00100002);
        write_32_mask(base_addr, 0x06a0,0x0000ffff,0xffee0000);
        write_32_mask(base_addr, 0x06a4,0xffffff00,0x0000000f);
        write_32_mask(base_addr, 0x0604,0x00ffffff,0x5e000000);
        write_32_mask(base_addr, 0x0608,0xffffff00,0x00000006);
        write_32_mask(base_addr, 0x0678,0xffff00ff,0x00002000);
        write_32_mask(base_addr, 0x0680,0xff00ff00,0x00280028);
        write_32_mask(base_addr, 0x0684,0x00000000,0x2d0f0385);
        write_32_mask(base_addr, 0x0650,0x00ffffff,0xd0000000);
        write_32_mask(base_addr, 0x0694,0x00ffffff,0x20000000);
       
        write_32_mask(base_addr, 0x0800,0xffffff00,0x00000000);
        write_32_mask(base_addr, 0x0804,0x00ffff00,0x5e000080);
        write_32_mask(base_addr, 0x0808,0xffffff00,0x00000006);
        write_32_mask(base_addr, 0x0810,0xffffff00,0x00000023);
        write_32_mask(base_addr, 0x0814,0x00ff0000,0x2e003060);
        write_32_mask(base_addr, 0x0818,0x00ffffff,0x76000000);
        write_32_mask(base_addr, 0x082c,0xff00ff00,0x00100002);
        write_32_mask(base_addr, 0x08a0,0x0000ffff,0xffee0000);
        write_32_mask(base_addr, 0x08a4,0xffffff00,0x0000000f);
        write_32_mask(base_addr, 0x0804,0x00ffffff,0x5e000000);
        write_32_mask(base_addr, 0x0808,0xffffff00,0x00000006);
        write_32_mask(base_addr, 0x0878,0xffff00ff,0x00002000);
        write_32_mask(base_addr, 0x0880,0xff00ff00,0x00280028);
        write_32_mask(base_addr, 0x0884,0x00000000,0x2d0f0385);
        write_32_mask(base_addr, 0x0850,0x00ffffff,0xd0000000);
        write_32_mask(base_addr, 0x0894,0x00ffffff,0x20000000);
       
        write_32_mask(base_addr, 0x0a00,0xffff00ff,0x00000100);
        write_32_mask(base_addr, 0x0a08,0xff000000,0x00e12c08);
        write_32_mask(base_addr, 0x0a0c,0xffffff00,0x00000081);
        write_32_mask(base_addr, 0x0a18,0xff00ffff,0x00e80000);
        write_32_mask(base_addr, 0x0a30,0x00ffff00,0x002f2f00);
        write_32_mask(base_addr, 0x0a48,0xff0000ff,0x00e3ce00);
        write_32_mask(base_addr, 0x0a4c,0x0000ffff,0xac820000);
        write_32_mask(base_addr, 0x0a54,0x00ffffff,0xc0000000);
        write_32_mask(base_addr, 0x0a58,0xffff0000,0x00001441);
        write_32_mask(base_addr, 0x0a84,0xffff0000,0x00000301);
       
        write_32_mask(base_addr, 0x0a8c,0x0000ffff,0x81030000);   
        write_32_mask(base_addr, 0x0a90,0xffff0000,0x00006001);   
        write_32_mask(base_addr, 0x0a94,0x00ffffff,0x01000000);   
        write_32_mask(base_addr, 0x0aa0,0x00ffffff,0x81000000);   
        write_32_mask(base_addr, 0x0abc,0x00ffffff,0xff000000);   
        write_32_mask(base_addr, 0x0ac0,0xffffff00,0x0000008b);

    // Added For PHY Loop Back
    #ifdef ENABLE_PHYLOOPBACK
       uint32_t old_val;
       old_val = DEVICE_REG32_R(base_addr + 0x200);
       DEVICE_REG32_W(base_addr + 0x200, ((old_val & 0x0FFFFFFF)|0x40000000));
       old_val = DEVICE_REG32_R(base_addr + 0x400);
       DEVICE_REG32_W(base_addr + 0x400, ((old_val & 0x0FFFFFFF)|0x40000000));
       old_val = DEVICE_REG32_R(base_addr + 0x600);
       DEVICE_REG32_W(base_addr + 0x600, ((old_val & 0x0FFFFFFF)|0x40000000));
       old_val = DEVICE_REG32_R(base_addr + 0x800);
       DEVICE_REG32_W(base_addr + 0x800, ((old_val & 0x0FFFFFFF)|0x40000000));
    #endif
        write_32_mask(base_addr, 0x0000,0xffffff00,0x00000003);   
        write_32_mask(base_addr, 0x0a00,0xffffff00,0x0000009f);
    }

    Inside main() {

    ......
     
    #ifdef ENABLE_PHYLOOPBACK
       System_printf ("Force PCIe Link state...\n");
       pcieForceLink(handle); ============> this is in your code
    #endif
      
      /* Wait for link to be up */
      pcieWaitLinkUp(handle);

    ....

    }

    Regards, Eric

  • Hi Eric,

    Thanks for the support.  With your additional SERDES configuration for KS2, the link is up for EVM for PHY loopback.

    But when I try to run same code for our custom board, the link is not up.  

    1. Could you please provide me a checklist which needs to be verified for the custom board that can impact PHY loopback?

    We have measured the PCIe clock and it seems to be fine.

    2. If we assume that the PCIe Switch or EP in the PCIe bus is not working because of some hardware issue, can this affect the PHY loopback of Keystone 2?

    3. Is there a new SERDES user guide for Keystone 2?  If so, could you please share it.  We could not find it on the product page.

    Thanks

    Rams

  • Rams,

    For Q1 and Q2, I will check with our HW engeineers. Can you clarify in your customized board, how K2H SOC is connected to another PCIE EP?

    For Q3, the latest SERDES is http://www.ti.com/lit/ug/spruho3/spruho3.pdf

    Regards, Eric

     

  • Eric,

    Thanks again for the guidance and support.  Please find the attached block diagram which shows interfacing of K2 with PLX PCIe Switch. There are two other EP devices interfaced with the PLX switch those are not part of the block diagram.  It would be nice to your feedback  on this.

    Thanks

    Rams

    5040.K2_pcie.pdf

  • Eric,

    I also want to add a point that the PLX switch is held in reset while I performed the PHY loopback on custome board.  Hope PHY loopback should be independent of the state of other PCIe devices in the PCIe bus.

    Let me know your input.

    Thanks

    Rams

  • Eric,

    I am adding the block diagram which captures all the devices in PCIe bus.  Awaiting your feedback.

    Thanks

    Rams

    4061.pcie_plx_ep.pdf

  • Eric,

    Do you have any update?

    Thanks

    Rams

  • Hi Eric,

    The issue is resolved now.  There was issue with voltage levels in SERDES interface.  The PHY loopback was very useful test case as it helped to focus on the SERDES interface.

    Now the loopback is working on the custom board and also the link between Keystone 2 and PLX Switch.

    Thanks

    Rams