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.

C6678 PCIe Problem - LINK_RST_REQ - Link Request Reset interrupt raw status.

Hy

I want to report a problem that I obtain when I connect my board, that I project, to PC, using PCIe interface. In particular I have use TI DSP C6678. When I power up PC, the link PCIe comes up (LTSSAM state : L0), but immediately it shuts down (LTSSAM state: DETECT_QUIET).

On DSP I can see that the bit “LINK_RST_REQ - Link Request Reset interrupt raw status.” of the register “Power Management and Reset Interrupt Status Register (PMRST_IRQ_STATUS_RAW)” turns on.

I made several attempts to restore the connection but without result. Have you experience with this kind of error? How shod I behave?

 

Thank you.

Stefano

  • The team is notified. They will post their feedback directly here.

    BR
    Tsvetolin Shulev
  • Hi,

    There is an errata for Keystone II device: www.ti.com/.../sprz402e.pdf. KeyStoneII.BTS_errata_advisory.38 PCI-Express Hot Reset Not Handled During Boot
    This also applied to Keystone I (C6678) PCIE interface.

    Regards, Eric
  • Thank you for the answer.

    How I can make local reset of the PCIE?

    Sorry but  I would like to be sure I understood the procedure well.

    Thank you.

    Ste

  • Hi,

    You can do a PCIE PSC domain power off, then follow the Processor SDK RTOS PCIE example code to do the PCIE initialization (PSC power on, serdes setup, PCIE EP mode, BAR, inbound, outbound, ...). processors.wiki.ti.com/.../Processor_SDK_RTOS_PCIe

    Regards, Eric
  • Hy, unfortunately the error is still there. 
    I see that after the reset of the PCIESS module and the reconfiguration (PSC power on, serdes setup, PCIE EP mode, BAR …) the bit LINK_RST_REQ turn on.
    I make this operation also many times during a single reboot of PC but the result is the same. I report the configuration function ‘SetupPCIe’ and the ‘PCIeHotResetReInitialize’.
    Can you tell me if I configure well the peripheric? Have you another idea to exceed the Link request reset interrupt ?


    #define DEVICE_PCIE_INITIAL_BAR_32BIT(x) ((x) < 3 ? (0x10800000 + ((x) * 0x01000000)) : 0x80000000)

    void SetupPCIe()

    { KICKUNLOCK(); //Unlock Registers

    prPSC_PDCTL[3] = 1; // Power Domain 3 (PCIe)
    prPSC_MDCTL[10] = (1 << 8) | 3; // Module Control Register 10 (PCIe)
    rPSC_PTCMD = (1 << 3); // Power Domain n3 (PCIe)

    while( rPSC_PTSTAT & (1<<3) ) { ; }
    rPCIE_SERDES_CFGPLL = 0x181 << 0;

    int Pll_Lockup = 0;
    while ( (Pll_Lockup != 0x1))
    {
    Pll_Lockup = rPCIE_SERDES_STS & 0x1;
    }

    rDEV_STAT = 1 << 16
    | 0 << 14; // PCIe in End Point Mode.


    rPL_LINK_CTRL = (1 << 16) // Link mode enable 1 = x1 | 3 = x2
    | (1 << 8) // Link Rate 2.5GT/s [Don't change it]
    | (1 << 5); // DLL Link Enable. Enable link initialization

    rPL_GEN2 = (PCIE_GEN << 17) // Initialize the PLL's speed change from PCIe_Gen1 to PCIe_Gen2
    | (1 << 8) // Set enable 2 lanes [1 for 1 lane, 2 for 2 lanes]
    | (0xF << 0); // Number of fast training sequences

    rCMD_STATUS = (1 << 5) // Unlock writing to BAR mask registers
    | (0 << 0); // Disable link training

    rBAR_T0(0) = 0x0000FFFF; // Define BAR0 Mask
    rBAR_T0(1) = 0x0000FFFF; // Define BAR1 Mask
    rBAR_T0(2) = 0x0000FFFF; // Define BAR2 Mask
    rBAR_T0(3) = 0x0000FFFF; // Define BAR3 Mask
    rBAR_T0(4) = 0x0000FFFF; // Define BAR4 Mask
    rBAR_T0(5) = 0x0000FFFF; // Define BAR5 Mask

    rCMD_STATUS = (0 << 5) // Lock writing to BAR mask registers
    | (0 << 0); // Disable link training

    rSTATUS_COMMAND = (1 << 20) // For PCIe, this field must be set to 1.
    | (1 << 8) // Enable PCI Express error message generation
    | (1 << 6) // Detect poisoned TLP
    | (1 << 2) // Mastership of bus
    | (1 << 1); // Enable memory access

    rDEV_STAT_CTRL = (2 << 12) // Maximum Read Request Size
    | (1 << 11) // Enable no snoop
    | (1 << 4) // Enable Relaxed Ordering
    | (1 << 3) // Enable Unsupported Request Reporting
    | (1 << 2) // Fatal Error Reporting Enable
    | (1 << 1) // Non-fatal Error Reporting Enable
    | (1 << 0); // Correctable Error Reporting Enable

    rPCIE_ACCR = (1 << 8) // ECRC Check Enable
    | (1 << 7) // ECRC Check Capable
    | (1 << 6) // ECRC Generation Enable
    | (1 << 5); // ECRC Generation Capability

    rVENDOR_DEVICE_ID = (0xB005 << 16) //Device ID [esempio]
    | (0x104C << 0); //Vendor ID

    rBAR_T0(0) = 0x0;
    rBAR_T0(1) = 0x8;
    rBAR_T0(2) = 0x8;
    rBAR_T0(3) = 0x8;
    rBAR_T0(4) = 0x8;
    rBAR_T0(5) = 0x8;


    rIB_BAR(0)= 1; // Associate BAR1 at first region
    rIB_START_LO(0)= DEVICE_PCIE_INITIAL_BAR_32BIT(0); // Low Inbound Start Address
    rIB_START_HI(0)= 0x0; // Hight Inbound Start Address
    rIB_OFFSET(0)= 0; //Offset

    rIB_BAR(1)= 2;
    rIB_START_LO(1)= DEVICE_PCIE_INITIAL_BAR_32BIT(1); // Low Inbound Start Address
    rIB_START_HI(1)= 0x0; // Hight Inbound Start Address
    rIB_OFFSET(1)= 0; //Offset

    rIB_BAR(2)= 3;
    rIB_START_LO(2)= DEVICE_PCIE_INITIAL_BAR_32BIT(2); // Low Inbound Start Address
    rIB_START_HI(2)= 0x0; // Hight Inbound Start Address
    rIB_OFFSET(2)= 0; //Offset

    rIB_BAR(3)= 4;
    rIB_START_LO(3)= DEVICE_PCIE_INITIAL_BAR_32BIT(3); // Low Inbound Start Address
    rIB_START_HI(3)= 0x0; // Hight Inbound Start Address
    rIB_OFFSET(3)= 0; //Offset

    /* Enable MSI0 IRQ vector 0 */
    rMSI_IRQ_ENABLE_SET(0) = 1;

    /* Enable all legacy interrupts */
    rLEGACY_A_IRQ_ENABLE_SET = 1;
    rLEGACY_B_IRQ_ENABLE_SET = 1;
    rLEGACY_C_IRQ_ENABLE_SET = 1;
    rLEGACY_D_IRQ_ENABLE_SET = 1;


    rCMD_STATUS = (0 << 5) // Unlock writing to BAR mask registers
    | (0 << 4) // Application request retry enable. [verificare]
    | (1 << 2) // Inbound address translation enable.
    | (1 << 0); // Enable link training

    int ltssmState3 = 0;
    while ( (ltssmState3 != 0x11))
    {
    HardWait(1);

    ltssmState3 = rDEBUG0 & 0x1F;
    }
    }


    void PCIeHotResetReInitialize()

    {

    int linkrstreq = 0;

    while ( (linkrstreq != 0x8))
    {
    linkrstreq = rPMRST_IRQ_STATUS_RAW & 0x8;
    }

    HardWait(100000); // HardWait (Wait Time[microsecond])

    prPSC_PDCTL[3] = 0; // Power Domain 3 (PCIe)
    prPSC_MDCTL[10] = 0; // Module Control Register 10 (PCIe) Reset
    rPSC_PTCMD = (1 << 3); // Power Domain n3 (PCIe)
    while( rPSC_PTSTAT & (1<<3) ) { ; } // Wait until the state transition process is completed

    HardWait(10); // HardWait (Wait Time[microsecond])

    prPSC_PDCTL[3] = 1; // Power Domain 3 (PCIe)
    prPSC_MDCTL[10] = (1 << 8) | 3; // Module Control Register 10 (PCIe)
    rPSC_PTCMD = (1 << 3); // Power Domain n3 (PCIe)
    while( rPSC_PTSTAT & (1<<3) ) { ; } // Wait until the state transition process is completed

    HardWait(10);

    }

  • Hy, unfortunately the error is still there.
    I see that after the reset of the PCIESS module and the reconfiguration (PSC power on, serdes setup, PCIE EP mode, BAR …) the bit LINK_RST_REQ turn on.
    I make this operation also many times during a single reboot of PC but the result is the same. I report the configuration function ‘SetupPCIe’ and the ‘PCIeHotResetReInitialize’.
    Can you tell me if I configure well the peripheric? Have you another idea to exceed the Link request reset interrupt ?
  • Hi,

    When you connect the C6678 PCIE into a PC and power it on, the BIOS of the PC scans the PCIE bus and enumerate the devices connected to it. At this moment, the 6678 PCIE card is enumerated and comes into L0 state. Some PC sends out a hot reset shortly after this, the PCIE link is lost and LINK_RST_REQ is set in the C6678 side.

    It is not expected that PC sends multiple hot reset. So after the first one hot reset, you detects the link lost, quickly run PCIeHotResetReInitialize() to power it off, then SetupPCIe() to re-initialization, this should work. It is just like you power on the C6678 PCIE from beginning, configure it (but missed the hot reset from PC).

    Some other choice, like our EVM, the PCIE boot from EEPROM, this is connected via I2C bus, the code load takes sometime so we missed the hot reset from PC but still inside the BIOS enumeration time window. We can still have the enumeration happening.

    Regards, Eric
  • Thank you
    but all attempts did not go well. Do you know if the same error could be generated by another reason?
    Could be depend to the long connection that I have with the PC motherboard?
    I don't know if it can affect but in the PCIE_CERR register I read 0x81
    while in the PCIE_UNCERR I can no find anithing (0x0).

    Sorry but unfortunately I haven't a EVB to test my code.
    Ste
  • Hi,

    You may look at some HW design guide for PCIE interface to see if your board is in good design:

    www.ti.com/.../sprabc1.pdf
    www.ti.com/.../sprabi2c.pdf

    Regards, Eric