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.

有关DSP多核 PCIE loopback回环测试问题



1、请问DSP C6657 PCIE能做 PHY loopback回环测试吗?
2、是不是可以这样理解这个回环测试可以DSP单端进行pcie回路测试?不需要PCie连接接口?
3、是否能提供PHY loopback回环测试示例代码?

  • 可以做loopback,参考下面链接中STK中的PCIE 例程。

    http://www.deyisupport.com/question_answer/dsp_arm/c6000_multicore/f/53/t/47664.aspx?pi2132219853=2

  • 按PCIE手册的步骤,到最后检测链接状态始终是0x1B,我将代码发出来麻烦找找原因,代码是在示例程序基础上增加PHY loopback:

    主程序中PCIe初始段:

    ............

    TSCL = 1;
    uint16_t lock=0;

    pcieRet_e retVal;
    pcieIbTransCfg_t ibCfg;
    pcieBarCfg_t barCfg;
    Pcie_Handle handle = NULL;
    void *pcieBase;
    uint32_t i;
    printfInfoLevel level;
    level = PRINT_DEBUG;

    print_infos(PRINT_SYS_INFO,"**********************************************\n");
    print_infos (PRINT_SYS_INFO,"* PCIe Test Start *\n");

    if(PcieModeGbl == pcie_RC_MODE)
    print_infos (PRINT_SYS_INFO,"* RC mode *\n");
    else
    print_infos (PRINT_SYS_INFO,"* EP mode *\n");

    print_infos (PRINT_SYS_INFO,"**********************************************\n\n");

    print_infos (PRINT_SYS_INFO,"Version #: 0x%08x; string %s =%x\n", Pcie_getVersion(), Pcie_getVersionStr(),(int)level);

    if((retVal = Pcie_init(&pcieInitCfg)) != pcie_RET_OK)
    {
    System_printf ("LLD device configuration failed (%d)\n", (int)retVal);
    exit(1);
    }
    /* Initialize application buffers */
    pcieInitAppBuf();

    if ((retVal = Pcie_open(0, &handle)) != pcie_RET_OK)
    {
    System_printf ("Open failed (%d)\n", (int)retVal);
    exit(1);
    }
    pcie_getDeviceId(handle);
    /*1、 Configure SERDES*/
    if ((retVal = pcieSerdesCfg()) != pcie_RET_OK) {
    print_infos (PRINT_ERROR,"PCIe Serdes config failed (%d)\n", (int)retVal);
    exit(1);
    }

    /*3、 Set the PCIe mode*/
    if ((retVal = Pcie_setInterfaceMode(handle,PcieModeGbl)) != pcie_RET_OK) {
    print_infos (PRINT_ERROR,"Set PCIe Mode failed (%d)\n", (int)retVal);
    exit(1);
    }

    /*2、 Power up PCIe Module */
    if ((retVal = pciePowerCfg()) != pcie_RET_OK) {
    print_infos (PRINT_ERROR,"PCIe Power Up failed (%d)\n", (int)retVal);
    exit(1);
    }

    System_printf ("PCIe Power Up.\n");

    /*5、 Wait until the PCIe SERDES PLL locks */
    while (!lock)
    {
    CSL_BootCfgGetPCIEPLLLock(&lock);
    }

    System_printf ("PLL configured.\n");
    /*6、CMD_STATUS[LTSSM_EN]=0 禁止链路训练 link training 复位过来自动清除*/
    //7、Program the configuration registers in the PCIESS to desired values.
    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 ret=%d!\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 ret=%d!\n", (int)retVal);
    exit(1);
    }else
    {
    System_printf ("Successfully configured Outbound Translation!\n");
    }
    }

    //loopback、TX、RX loopback允许
    if((retVal = pcie_cfgLoopBack(handle)) != pcie_RET_OK)
    {
    print_infos (PRINT_ERROR,"Set loopback failed (%d)\n",retVal);
    exit(1);
    }

    System_printf ("Starting link training...\n");
    /*8、Enable link training*/
    if ((retVal = pcieLtssmCtrl(handle, TRUE)) != pcie_RET_OK)
    {
    System_printf ("Failed to Enable Link Training ret=%d!\n", (int)retVal);
    exit(1);
    }

    //强制链接从POLL_ACTIVE状态开始
    if((retVal = pcie_forceLink(handle)) != pcie_RET_OK)
    {
    System_printf ("Failed to force Link Training ret=%d!\n", (int)retVal);
    exit(1);
    }
    /*
    //pcie_LTSSM_LPBK_ACTIVE 查询POLL_ACTIVE状态
    if((retVal = pcie_IsThisState(handle,pcie_LTSSM_LPBK_ACTIVE)) != pcie_RET_OK)
    {
    printf_debug(PRINT_DEBUG,"Set force link failed!\n");
    exit(1);
    }*/

    /* if((retVal=IsDllActvie(handle)) != pcie_RET_OK)
    {
    printf_debug(PRINT_DEBUG,"Data Link Layer Active failed!\n");
    exit(1);
    }*/
    /*9、 Wait for link to be up */
    pcieWaitLinkUp(handle); //pcie_LTSSM_L0=0x11   ----------------------->一直在这这个地方链接状态一直是0x1B
    System_printf ("Link is up.\n");

    .............

    //PHY loopback配置

    static pcieRet_e pcie_cfgLoopBack(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));

    pcieLnkCtrlReg_t linkCtr;

    memset(&linkCtr,0,sizeof(pcieLnkCtrlReg_t));

    getRegs.lnkCtrl = &linkCtr;
    if ((retVal = Pcie_readRegs (handle, pcie_LOCATION_LOCAL, &getRegs)) != pcie_RET_OK)
    {
    printf_debug(PRINT_DEBUG,"Read loopback failed!\n");
    return retVal;
    }

    linkCtr.lpbkEn = 1;
    setRegs.lnkCtrl = &linkCtr;
    if((retVal = Pcie_writeRegs(handle,pcie_LOCATION_LOCAL, &setRegs)) != pcie_RET_OK)
    {
    printf_debug(PRINT_DEBUG,"Set loopback failed!\n");
    return retVal;
    }

    memset (&setRegs, 0, sizeof(setRegs));
    memset (&getRegs, 0, sizeof(getRegs));
    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;

    //force link

    static inline pcieRet_e pcie_forceLink(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;
    }