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.

Trouble retrain PCIe link on C6678

I has the following configuration:

C6678 (RC) directly connected via PCI to FPGA(EP).

On power on FPGA loading image_1 from EPCS.

C6678 can send Remote Update command to FPGA. If FPGA contain image_1 and receive  Remote Update command, when in FPGA from EPCS wil be loaded image_2.

For example:

image_1 has PCIe DevID = 0x00AA VendorID = 0x1111

image_2 has PCIe DevID = 0x00BB VendorID = 0x1111

I'm doing the following steps:

1. Turn on board power;

- In FPGA from EPCS loading image_1.

2. Using Code Composer  Studio connect to C6678 via JTAG;

3. Loading program to C6678;

4. Lunch program. Program make initialization PCIe bus and find device with DevID = 0x00AA VendorID = 0x1111 (image_1 in FPGA);

5. Program send Remote Update command to FPGA. FPGA from EPCS load image_2 (DevID = 0x00BB, VendorID = 0x1111);

- FPGA rebooted -> PCIe link down

- LTSSM_EN bit in register CMD_STATUS self set to 0

6. Try reinitialization of PCI bus.

My problems begin in paragraph 6.

After setting bit LTSSM_EN value to 1, i see that register Debug_0 field [4..0] constantly changes its state between codes 0x0D and 0x11. -> Link can't stabilize.

I tried to do retrain PCIe link by setting 5 bit in LINK_STAT_CTRL register -> No effect. (LTSSM_EN = 1 and before i set him to 1).

Tried to restart PCIe power domain -> didn't help.

At the same time, if in paragraph 6 i don't doing reinitialization PCIe, but do System_reset and reload program by JTAG , then everything is fine and the device DevID = 0x00BB VendorID = 0x1111 (image_2 in FPGA) finding successfully.

What i'm doing wrong?

How correctly restart PCIe link after EP restarts and drop link?

  • Did retrain finished?

    PCIE USER GUIDE 2.16.2.2.3 Link Errors

    The physical link connecting two devices may fail causing a variety of errors. Because the link has incurred errors, the error cannot be reported to the host via the failed link. Therefore, link errors must be reported via the upstream port of switches or by the Root Port itself. Also the related fields in the PCI Express Link Status and Control Register
    (LINK_STAT_CTRL) are valid only in RC (not applicable within EP device). This permits system software to access link-related error registers on the port that is closest to the host.

    The Link Status and Control Register includes a RETRAIN_LINK bit (bit 5) that when set forces the RC to retrain the link. If transaction (upon completion of the retraining) can once again traverse the link without errors, the problem will have been solved. Software can monitor the LINK_TRAINING bit (bit 27) in the Link Status and Control Register to determine when retraining has completed.

    Tried to restart PCIe power domain -> didn't help. =====> If you turned off the PSC domain of PCIE, all the PCIE registers (0x2180_0000 region) will be cleared to zero. Then you need to use PSC to turn it on again, and reprogram the PCIE interface. I didn't see what was done here and can you elaborate? 

    Regards, Eric 

  • Hello Eric.

    1.No. I'm reload FPGA with image_2 and set LTSSM_EN bit. Thereafter i see that DEBUG_0[4..0] register have changing state between RCVRY_LOCK and L0. L0 state not stable. LTSSM_EN not self cleared.

    2.If after reload FPGA with image_2 i set RETRAIN_LINK bit (bit 5), i see that LINK_TRAINING bit (bit 27) don't change its state.

    3.As you say i try this.

    Restart power:

    if (CSL_PSC_getModuleState(CSL_PSC_LPSC_PCIEX) == PSC_MODSTATE_ENABLE)

    {

      CSL_PSC_setModuleNextState(CSL_PSC_LPSC_PCIEX,PSC_MODSTATE_DISABLE);

      CSL_PSC_startStateTransition(CSL_PSC_PD_PCIEX);

      while(!CSL_PSC_isStateTransitionDone(CSL_PSC_PD_PCIEX));

      CSL_PSC_disablePowerDomain(CSL_PSC_PD_PCIEX);

    }

    //after that condition CSL_PCS_getModuleState(CSL_PSC_LPSC_PCIEX) != PSC_MODSTATE_ENABLE still true

    if (CSL_PSC_getModuleState(CSL_PSC_LPSC_PCIEX) != PSC_MODSTATE_ENABLE)

    {

      CSL_PSC_enablePowerDomain(CSL_PSC_PD_PCIEX);

      CSL_PSC_setModuleNextState(CSL_PSC_LPSC_PCIEX,PSC_MODSTATE_ENABLE);

      CSL_PSC_startStateTransition(CSL_PSC_PD_PCIEX);

      while(!CSL_PSC_isStateTransitionDone(CSL_PSC_PD_PCIEX));

    }

    What i'm doing wrong while try to restart power PCIe?