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.

TDA2SX/TDA2XX: PCIe subsystem 2 utilization

Other Parts Discussed in Thread: TDA2SX

Hello,

reading through the Technical Reference Manual for TDA2XX I understood that the PCIe controller instantiates 2 subsystems which can operate in following usecases:

1) Only subsystem 1 working in x1 mode

2) Only subsystem 2 working in x1 mode

3) Subsystem 1 and subsystem 2 both working in x1 mode simultaneously

4) Subsystem 1 working in x2 mode while subsystem 2 cannot be used

I'm working on PROCESSOR_SDK_VISION_03_02_00_00 and have successfully tried usecases 1 and 4. However I'm trying variant 2 and 3 right now. When I do the programming of the PCIe subsystems I refer to the tables that contain typical programming sequences that I found in Technical Reference Manual for TDA2XX. The testing is done using PCIe example from PDK.

I'm working on utilizing only subsystem 2 in x1 mode, first. The initialization of the clocks and PHY pass correctly but when it comes to choosing which type of pcie the subsystem will be (RC or EP) the execution hangs. Important thing to say is that this happened for the first time when programming SS2, haven't had those problems with SS1.

Therefore I have a few questions:

1) The SoC that I'm using is TDA2SX whereas the documentation that I refer to is for TDA2XX. Are those two the same and can I assume that there are indeed two PCIe subsystems in my SoC?

2) If there are 2 PCIe subsystems, why does the execution hang during RC/EP mode choice? I was mimicking the code that is present in the test for SS1 but also following the programming sequence table from TRM (that is for pcie_app.c). In the RC and EP parts of the test I just replaced every ocurrence of "SS1" with "SS2" (the code of course compiles and builds and I am able to run it).

Thank you in advance.

Regards,

Nick

  • Hi Nick,

    1. TDA2SX SoC belong to TDA2xx family and indeed has two PCIe subsystems.
    2. It is not very clear what changes you have made to pcie_app.c for SS2. Can you review the APIs of pcie_app.c and check if you have missed out on any required change. If you can't find it please share modified pcie_app.c.

    Regards,
    Rishabh
  • Hi Nick,
    I think you are getting hung condition while the very first PCIe register access. If I'm right, the reason could be not enabled clocks from PRCM. You could read the CM_PCIE_PCIESS2_CLKCTRL registers to check if PCIe2 was enabled.

    Regards,
    Stan
  • Hi Rishabh and Stanislav,

    The CM_PCIE_PCIESS2_CLKCTRL is being read while waiting for the SS2 to become fully functional, its IDLEST bits are polled as you will see in the source that is attached with this post. I have tried to change the code as little as possible but have also changed the order of initialization function calls in PCIEAppPrcmConfig() to fullfill the table 24-644. "Main Sequence PCIe Controller Global Initialization" from TRM. To be honest, this programming sequence in TRM is a little confusing because points 1 and 4 are both included in table 26-61. "PCIePHY Subsystem Low-Level Programming Sequence" and there is a software reset of SS1/2 between them.

    Let me explain in more detail what the behavior is. When I do the software reset of SS2 it gets stuck there, I didn't mention that in my original post (reset of SS1 passes ok). However, when I comment out that part, the execution continues but gets stuck at choosing RC/EP mode for SS2 in "ep_write_loopback_app_main.c" and "rc_write_loopback_app_main.c".

    As I said, you will find the modified "pcie_app.c" attached with this post while "ep_write_loopback_app_main.c" and "rc_write_loopback_app_main.c" are modified such that every occurence of "SS1" is replaced with "SS2", nothing else.

    Thank you in advance.

    Regards,
    Nick

    Attachment:

    /*
     *  Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
     *
     *  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_app.c
     *
     *  \brief    Source file containing the PCIe IP related configuration
     *            functions. These functions will be called by example
     *            applications.
     *
    **/
    
    /* ========================================================================== */
    /*                             Include Files                                  */
    /* ========================================================================== */
    
    #include "stdint.h"
    #include <string.h>
    #include <ti/csl/csl_types.h>
    #include <ti/csl/hw_types.h>
    #include <ti/csl/soc.h>
    #include <ti/csl/csl_pcie.h>
    #include <ti/csl/example/utils/uart_console/inc/uartConfig.h>
    
    /* Application header files */
    #include "pcie_app.h"
    
    /* ========================================================================== */
    /*                                Macros                                      */
    /* ========================================================================== */
    /* None */
    
    /* ========================================================================== */
    /*                         Structures and Enums                               */
    /* ========================================================================== */
    
    /* None */
    
    /* ========================================================================== */
    /*                 Internal Function Declarations                             */
    /* ========================================================================== */
    
    /* None */
    
    /* ========================================================================== */
    /*                            Global Variables                                */
    /* ========================================================================== */
    
    /* None */
    
    /* ========================================================================== */
    /*                          Function Definitions                              */
    /* ========================================================================== */
    #if    defined (__TI_ARM_V7M4__)
    #if    defined (SOC_AM572x) || defined (SOC_AM571x)
    void AppUtilsConfigIPU1DefaultAMMU(void)
    {
        ammuPageConfig_t      pageConfig       = {0U};
        ammuPolicyRegParams_t pagePolicyParams = {0U};
        uint32_t policyReg;
    
        /*******************************************
         * LARGE PAGE MAPPINGS                     *
         *******************************************/
        /* 0th large page mapping: P.A. 0x40000000U V.A 0x40000000U */
        /* Set Policy Params for the page */
        AMMUInitPolicyParams(&pagePolicyParams);
        pagePolicyParams.pageEnable = AMMU_PAGE_ENABLED;
        pagePolicyParams.pageSize   = AMMU_PAGE_SIZE_512MB;
        policyReg                   = AMMUMakePolicyReg(&pagePolicyParams);
    
        pageConfig.ammuPageType    = AMMU_PAGE_TYPE_LARGE;
        pageConfig.ammuPageNum     = 0U;
        pageConfig.policyRegVal    = policyReg; /* 0x00000007 */
        pageConfig.physicalAddress = 0x40000000U;
        pageConfig.logicalAddress  = 0x40000000U;
        AMMUConfigPage(SOC_IPU1_TARGET_UNICACHE_MMU_BASE, &pageConfig);
    
        /* 1st large page mapping: P.A. 0x80000000U V.A 0x80000000U */
        AMMUInitPolicyParams(&pagePolicyParams);
        pagePolicyParams.pageEnable      = AMMU_PAGE_ENABLED;
        pagePolicyParams.pageSize        = AMMU_PAGE_SIZE_512MB;
        pagePolicyParams.l1CacheEnable   = AMMU_L1_CACHE_ENABLED;
        pagePolicyParams.l1PostedWrite   = AMMU_L1_POSTED_WRITE_ENABLED;
        pagePolicyParams.l1WritePolicy   = AMMU_L1_WRITE_POLICY_WRITEBACK;
        policyReg                        = AMMUMakePolicyReg(&pagePolicyParams);
    
        pageConfig.ammuPageType          = AMMU_PAGE_TYPE_LARGE;
        pageConfig.ammuPageNum           = 1U;
        pageConfig.policyRegVal          = policyReg; /* 0x000B0007; */
        pageConfig.physicalAddress       = 0x80000000U;
        pageConfig.logicalAddress        = 0x80000000U;
        AMMUConfigPage(SOC_IPU1_TARGET_UNICACHE_MMU_BASE, &pageConfig);
    
        /* 2nd large page mapping: P.A. 0xA0000000U V.A 0xA0000000U */
        AMMUInitPolicyParams(&pagePolicyParams);
        pagePolicyParams.pageEnable      = AMMU_PAGE_ENABLED;
        pagePolicyParams.pageSize        = AMMU_PAGE_SIZE_512MB;
        pagePolicyParams.l1PostedWrite   = AMMU_L1_POSTED_WRITE_ENABLED;
        policyReg                        = AMMUMakePolicyReg(&pagePolicyParams);
    
        pageConfig.ammuPageType          = AMMU_PAGE_TYPE_LARGE;
        pageConfig.ammuPageNum           = 2U;
        pageConfig.policyRegVal          = policyReg;
        pageConfig.physicalAddress       = 0xA0000000U;
        pageConfig.logicalAddress        = 0xA0000000U;
        AMMUConfigPage(SOC_IPU1_TARGET_UNICACHE_MMU_BASE, &pageConfig);
    
        /* 3rd large page mapping: P.A. 0x40000000U V.A 0x60000000U */
        AMMUInitPolicyParams(&pagePolicyParams);
        pagePolicyParams.pageEnable      = AMMU_PAGE_ENABLED;
        pagePolicyParams.pageSize        = AMMU_PAGE_SIZE_512MB;
        policyReg                        = AMMUMakePolicyReg(&pagePolicyParams);
    
        pageConfig.ammuPageType          = AMMU_PAGE_TYPE_LARGE;
        pageConfig.ammuPageNum           = 3U;
        pageConfig.policyRegVal          = policyReg; /* 0x00000007; */
        pageConfig.physicalAddress       = 0x40000000U;
        pageConfig.logicalAddress        = 0x60000000U;
        AMMUConfigPage(SOC_IPU1_TARGET_UNICACHE_MMU_BASE, &pageConfig);
    
        /*******************************************
         * MEDIUM PAGE MAPPINGS                     *
         *******************************************/
        /* 0th medium page mapping: P.A. 0x40300000 V.A. 0x00300000 */
        /* Set Policy Params for the page */
        AMMUInitPolicyParams(&pagePolicyParams);
        pagePolicyParams.pageEnable      = AMMU_PAGE_ENABLED;
        pagePolicyParams.pageSize        = AMMU_PAGE_SIZE_256KB;
        pagePolicyParams.l1PostedWrite   = AMMU_L1_POSTED_WRITE_ENABLED;
        policyReg                        = AMMUMakePolicyReg(&pagePolicyParams);
    
        pageConfig.ammuPageType          = AMMU_PAGE_TYPE_MEDIUM;
        pageConfig.policyRegVal          = policyReg; /* 0x0001000B; */
        pageConfig.ammuPageNum           = 0;
        pageConfig.logicalAddress        = 0x00300000;
        pageConfig.physicalAddress       = 0x40300000;
        AMMUConfigPage(SOC_IPU1_TARGET_UNICACHE_MMU_BASE, &pageConfig);
    
        /* 1st medium page mapping: P.A. 0x40400000 V.A. 0x00400000 */
        /* Set Policy Params for the page */
        AMMUInitPolicyParams(&pagePolicyParams);
        pagePolicyParams.pageEnable      = AMMU_PAGE_ENABLED;
        pagePolicyParams.pageSize        = AMMU_PAGE_SIZE_256KB;
        policyReg                        = AMMUMakePolicyReg(&pagePolicyParams);
    
        pageConfig.ammuPageType          = AMMU_PAGE_TYPE_MEDIUM;
        pageConfig.policyRegVal          = policyReg; /* 0x0001000B; */
        pageConfig.ammuPageNum           = 1;
        pageConfig.logicalAddress        = 0x00400000;
        pageConfig.physicalAddress       = 0x40400000;
        AMMUConfigPage(SOC_IPU1_TARGET_UNICACHE_MMU_BASE, &pageConfig);
    
    
        /*******************************************
         * SMALL PAGE MAPPINGS                     *
         *******************************************/
        /* 0th small page mapping: P.A. 0x55020000U V.A. 0x00000000U */
        /* Set Policy Params for the page */
        AMMUInitPolicyParams(&pagePolicyParams);
        pagePolicyParams.pageEnable      = AMMU_PAGE_ENABLED;
        pagePolicyParams.pageSize        = AMMU_PAGE_SIZE_16KB;
        pagePolicyParams.l1CacheEnable   = AMMU_L1_CACHE_ENABLED;
        pagePolicyParams.volatileEnable  = AMMU_VOLATILE_ENABLED;
        policyReg                        = AMMUMakePolicyReg(&pagePolicyParams);
    
        pageConfig.ammuPageType          = AMMU_PAGE_TYPE_SMALL;
        pageConfig.policyRegVal          = policyReg; /* 0x0001000B; */
        pageConfig.ammuPageNum           = 0;
        pageConfig.logicalAddress        = 0x00000000U;
        pageConfig.physicalAddress       = 0x55020000U;
        AMMUConfigPage(SOC_IPU1_TARGET_UNICACHE_MMU_BASE, &pageConfig);
    
        /* 1st small page mapping: P.A. 0x55080000U V.A. 0x40000000U */
        /* Set Policy Params for the page */
        AMMUInitPolicyParams(&pagePolicyParams);
        pagePolicyParams.pageEnable      = AMMU_PAGE_ENABLED;
        pagePolicyParams.pageSize        = AMMU_PAGE_SIZE_16KB;
        pagePolicyParams.volatileEnable  = AMMU_VOLATILE_ENABLED;
        policyReg                        = AMMUMakePolicyReg(&pagePolicyParams);
    
        pageConfig.ammuPageType          = AMMU_PAGE_TYPE_SMALL;
        pageConfig.policyRegVal          = policyReg; /* 0x0000000B; */
        pageConfig.ammuPageNum           = 1;
        pageConfig.logicalAddress        = 0x40000000U;
        pageConfig.physicalAddress       = 0x55080000U;
        AMMUConfigPage(SOC_IPU1_TARGET_UNICACHE_MMU_BASE, &pageConfig);
    
        /* 2nd small page mapping: P.A. 0x55024000 V.A. 0x00004000 */
        /* Set Policy Params for the page */
        AMMUInitPolicyParams(&pagePolicyParams);
        pagePolicyParams.pageEnable      = AMMU_PAGE_ENABLED;
        pagePolicyParams.pageSize        = AMMU_PAGE_SIZE_16KB;
        pagePolicyParams.l1CacheEnable   = AMMU_L1_CACHE_ENABLED;
        policyReg                        = AMMUMakePolicyReg(&pagePolicyParams);
    
        pageConfig.ammuPageType          = AMMU_PAGE_TYPE_SMALL;
        pageConfig.policyRegVal          = policyReg; /* 0x0001000B; */
        pageConfig.ammuPageNum           = 2;
        pageConfig.logicalAddress        = 0x00004000U;
        pageConfig.physicalAddress       = 0x55024000U;
        AMMUConfigPage(SOC_IPU1_TARGET_UNICACHE_MMU_BASE, &pageConfig);
    
        /* 3rd small page mapping: P.A. 0x55028000 V.A. 0x00008000 */
        /* Set Policy Params for the page */
        AMMUInitPolicyParams(&pagePolicyParams);
        pagePolicyParams.pageEnable      = AMMU_PAGE_ENABLED;
        pagePolicyParams.pageSize        = AMMU_PAGE_SIZE_16KB;
        policyReg                        = AMMUMakePolicyReg(&pagePolicyParams);
    
        pageConfig.ammuPageType          = AMMU_PAGE_TYPE_SMALL;
        pageConfig.policyRegVal          = policyReg; /* 0x00000003; */
        pageConfig.ammuPageNum           = 3;
        pageConfig.logicalAddress        = 0x00008000U;
        pageConfig.physicalAddress       = 0x55028000U;
        AMMUConfigPage(SOC_IPU1_TARGET_UNICACHE_MMU_BASE, &pageConfig);
    
    
        /* 4th small page mapping: P.A. 0x55020000 V.A. 0x20000000 */
        /* Set Policy Params for the page */
        AMMUInitPolicyParams(&pagePolicyParams);
        pagePolicyParams.pageEnable      = AMMU_PAGE_ENABLED;
        pagePolicyParams.pageSize        = AMMU_PAGE_SIZE_16KB;
        policyReg                        = AMMUMakePolicyReg(&pagePolicyParams);
    
        pageConfig.ammuPageType          = AMMU_PAGE_TYPE_SMALL;
        pageConfig.policyRegVal          = policyReg; /* 0x00000003; */
        pageConfig.ammuPageNum           = 4;
        pageConfig.logicalAddress        = 0x20000000U;
        pageConfig.physicalAddress       = 0x55020000U;
        AMMUConfigPage(SOC_IPU1_TARGET_UNICACHE_MMU_BASE, &pageConfig);
    
        /* 5th small page mapping: P.A. 0x24000000U V.A. 0x24000000U */
        /* Set Policy Params for the page */
        AMMUInitPolicyParams(&pagePolicyParams);
        pagePolicyParams.pageEnable      = AMMU_PAGE_ENABLED;
        pagePolicyParams.pageSize        = AMMU_PAGE_SIZE_16KB;
        policyReg                        = AMMUMakePolicyReg(&pagePolicyParams);
    
        pageConfig.ammuPageType          = AMMU_PAGE_TYPE_SMALL;
        pageConfig.policyRegVal          = policyReg; /* 0x00000003; */
        pageConfig.ammuPageNum           = 5;
        pageConfig.logicalAddress        = 0x24000000U;
        pageConfig.physicalAddress       = 0x24000000U;
        AMMUConfigPage(SOC_IPU1_TARGET_UNICACHE_MMU_BASE, &pageConfig);
    
        /* 6th small page mapping: P.A. 0x29FFC000U V.A. 0x29FFC000U */
        /* Set Policy Params for the page */
        AMMUInitPolicyParams(&pagePolicyParams);
        pagePolicyParams.pageEnable      = AMMU_PAGE_ENABLED;
        pagePolicyParams.pageSize        = AMMU_PAGE_SIZE_16KB;
        policyReg                        = AMMUMakePolicyReg(&pagePolicyParams);
    
        pageConfig.ammuPageType          = AMMU_PAGE_TYPE_SMALL;
        pageConfig.policyRegVal          = policyReg; /* 0x00000003; */
        pageConfig.ammuPageNum           = 6;
        pageConfig.logicalAddress        = 0x25FFC000U;
        pageConfig.physicalAddress       = 0x25FFC000U;
        AMMUConfigPage(SOC_IPU1_TARGET_UNICACHE_MMU_BASE, &pageConfig);
    
    }
    #else
    void AppUtilsConfigIPU1DefaultAMMU(void)
    {
       /* Implement AMMU for tda devices here */
       return;
    }
    #endif
    #endif /* __TI_ARM_V7M4__ */
    
    
    
    void PlatformPCIEClockEnable(void)
    {
        uint32_t regVal;
    
        /*OCP2SCP1 enables accessing the PCIe PHY serial configuration*/
        HW_WR_FIELD32(SOC_L3INIT_CM_CORE_BASE + CM_L3INIT_OCP2SCP1_CLKCTRL,
                        CM_L3INIT_OCP2SCP1_CLKCTRL_MODULEMODE,
                        CM_L3INIT_OCP2SCP1_CLKCTRL_MODULEMODE_AUTO);
    
        /*OCP2SCP3 enables accessing the PCIe PHY serial configuration*/
        HW_WR_FIELD32(SOC_L3INIT_CM_CORE_BASE + CM_L3INIT_OCP2SCP3_CLKCTRL,
                        CM_L3INIT_OCP2SCP3_CLKCTRL_MODULEMODE,
                        CM_L3INIT_OCP2SCP3_CLKCTRL_MODULEMODE_AUTO);
    
        /*PCIeSS CLKSTCTRL SW WakeUp*/
        HW_WR_FIELD32(SOC_L3INIT_CM_CORE_BASE + CM_PCIE_CLKSTCTRL,
                        CM_PCIE_CLKSTCTRL_CLKTRCTRL,
                        CM_PCIE_CLKSTCTRL_CLKTRCTRL_SW_WKUP);
    
        /*L3 Init PCIeSS1 CLKCTRL SW Enable*/
        HW_WR_FIELD32(SOC_L3INIT_CM_CORE_BASE + CM_PCIE_PCIESS1_CLKCTRL,
                        CM_PCIE_PCIESS1_CLKCTRL_MODULEMODE,
                        CM_PCIE_PCIESS1_CLKCTRL_MODULEMODE_ENABLED);
    
        while ((HW_RD_REG32(SOC_L3INIT_CM_CORE_BASE + CM_PCIE_PCIESS1_CLKCTRL) &
                CM_PCIE_PCIESS1_CLKCTRL_IDLEST_MASK) !=
                CM_PCIE_PCIESS1_CLKCTRL_IDLEST_FUNC)
        {
            ;
        }
    
        /*Enable PCIeSS1 PHY optional clk*/
        regVal = HW_RD_REG32(SOC_L3INIT_CM_CORE_BASE + CM_PCIE_PCIESS1_CLKCTRL);
    
        HW_SET_FIELD32(regVal, CM_PCIE_PCIESS1_CLKCTRL_OPTFCLKEN_PCIEPHY_CLK_DIV,
                        CM_PCIE_PCIESS1_CLKCTRL_OPTFCLKEN_PCIEPHY_CLK_DIV_FCLK_EN);
    
        HW_SET_FIELD32(regVal, CM_PCIE_PCIESS1_CLKCTRL_OPTFCLKEN_PCIEPHY_CLK,
                        CM_PCIE_PCIESS1_CLKCTRL_OPTFCLKEN_PCIEPHY_CLK_FCLK_EN);
    
        HW_SET_FIELD32(regVal, CM_PCIE_PCIESS1_CLKCTRL_OPTFCLKEN_32KHZ,
                        CM_PCIE_PCIESS1_CLKCTRL_OPTFCLKEN_32KHZ_FCLK_EN);
    
        HW_WR_REG32(SOC_L3INIT_CM_CORE_BASE + CM_PCIE_PCIESS1_CLKCTRL, regVal);
    
    
        /*L3 Init PCIeSS2 CLKCTRL SW Enable*/
        HW_WR_FIELD32(SOC_L3INIT_CM_CORE_BASE + CM_PCIE_PCIESS2_CLKCTRL,
                        CM_PCIE_PCIESS2_CLKCTRL_MODULEMODE,
                        CM_PCIE_PCIESS2_CLKCTRL_MODULEMODE_ENABLED);
    
        while ((HW_RD_REG32(SOC_L3INIT_CM_CORE_BASE + CM_PCIE_PCIESS2_CLKCTRL) &
                CM_PCIE_PCIESS2_CLKCTRL_IDLEST_MASK) !=
                CM_PCIE_PCIESS2_CLKCTRL_IDLEST_FUNC)
        {
            ;
        }
    
        /*Enable PCIeSS2 PHY optional clk*/
        regVal = HW_RD_REG32(SOC_L3INIT_CM_CORE_BASE + CM_PCIE_PCIESS2_CLKCTRL);
    
        HW_SET_FIELD32(regVal, CM_PCIE_PCIESS2_CLKCTRL_OPTFCLKEN_PCIEPHY_CLK_DIV,
                        CM_PCIE_PCIESS2_CLKCTRL_OPTFCLKEN_PCIEPHY_CLK_DIV_FCLK_EN);
    
        HW_SET_FIELD32(regVal, CM_PCIE_PCIESS2_CLKCTRL_OPTFCLKEN_PCIEPHY_CLK,
                        CM_PCIE_PCIESS2_CLKCTRL_OPTFCLKEN_PCIEPHY_CLK_FCLK_EN);
    
        HW_SET_FIELD32(regVal, CM_PCIE_PCIESS2_CLKCTRL_OPTFCLKEN_32KHZ,
                        CM_PCIE_PCIESS2_CLKCTRL_OPTFCLKEN_32KHZ_FCLK_EN);
    
        HW_WR_REG32(SOC_L3INIT_CM_CORE_BASE + CM_PCIE_PCIESS2_CLKCTRL, regVal);
    
    }
    
    void PlatformPCIEPllConfig(void)
    {
        uint32_t regVal;
    
        /*OCP2SCP_SYSCONFIG[1] Soft Reset*/
        regVal = HW_RD_REG32(SOC_OCP2SCP3_BASE + 0x10U) & 0xFFFFFFFDU;
    
        regVal |= 0x02U;
    
        HW_WR_REG32(SOC_OCP2SCP3_BASE + 0x10U, regVal);
    
        /*OCP2SCP_SYSSTATUS[0] Reset Done*/
        while ((HW_RD_REG32(SOC_OCP2SCP3_BASE + 0x14U) & 0x01U) != 0x01U)
        {
            ;
        }
    
        /*OCP2SCP_TIMING[9:7] Division Ratio = 1*/
        regVal = HW_RD_REG32(SOC_OCP2SCP3_BASE + 0x18U) & 0xFFFFFC7FU;
    
        regVal |= (uint32_t) 0x8U << 4U;
    
        HW_WR_REG32(SOC_OCP2SCP3_BASE + 0x18U, regVal);
    
        /*OCP2SCP_TIMING[3:0] (SYNC2) = 0xF*/
        regVal = HW_RD_REG32(SOC_OCP2SCP3_BASE + 0x18U) & 0xFFFFFFF0U;
    
        regVal |= 0xFU;
    
        HW_WR_REG32(SOC_OCP2SCP3_BASE + 0x18U, regVal);
    
        /*PCIe DPLL - M&N programming; CLKSEL*/
        regVal = HW_RD_REG32(SOC_CKGEN_CM_CORE_BASE + CM_CLKSEL_DPLL_PCIE_REF);
    
        HW_SET_FIELD32(regVal, CM_CLKSEL_DPLL_PCIE_REF_DPLL_DIV, 0x09U);
    
        HW_SET_FIELD32(regVal, CM_CLKSEL_DPLL_PCIE_REF_DPLL_MULT, 0x2EEU);
    
        HW_WR_REG32(SOC_CKGEN_CM_CORE_BASE + CM_CLKSEL_DPLL_PCIE_REF, regVal);
    
        /*SigmaDelta SD DIV programming */
        HW_WR_FIELD32(SOC_CKGEN_CM_CORE_BASE + CM_CLKSEL_DPLL_PCIE_REF,
                        CM_CLKSEL_DPLL_PCIE_REF_DPLL_SD_DIV, 0x06U);
    
        /*PCIe DPLL - M2 programming*/
        HW_WR_FIELD32(SOC_CKGEN_CM_CORE_BASE + CM_DIV_M2_DPLL_PCIE_REF,
                        CM_DIV_M2_DPLL_PCIE_REF_DIVHS, 0x0FU);
    
        /*DPLL Enable*/
        HW_WR_FIELD32(SOC_CKGEN_CM_CORE_BASE + CM_CLKMODE_DPLL_PCIE_REF,
                        CM_CLKMODE_DPLL_PCIE_REF_DPLL_EN,
                        CM_CLKMODE_DPLL_PCIE_REF_DPLL_EN_DPLL_LOCK_MODE);
    
        /* Check for DPLL lock status */
        while (((HW_RD_REG32(SOC_CKGEN_CM_CORE_BASE + CM_IDLEST_DPLL_PCIE_REF) &
                CM_IDLEST_DPLL_PCIE_REF_ST_DPLL_CLK_MASK) <<
                CM_IDLEST_DPLL_PCIE_REF_ST_DPLL_CLK_SHIFT) !=
                CM_IDLEST_DPLL_PCIE_REF_ST_DPLL_CLK_DPLL_LOCKED)
        {
            ;
        }
    
        /*PCIe Tx and Rx Control of ACSPCIe*/
        HW_WR_FIELD32(SOC_SEC_EFUSE_REGISTERS_BASE + CTRL_CORE_SMA_SW_6,
                        CTRL_CORE_SMA_SW_6_PCIE_TX_RX_CONTROL, 0x02U);
    
        /*Locking APLL to 2.5GHz with 100MHz input*/
        regVal = HW_RD_REG32(SOC_CKGEN_CM_CORE_BASE + CM_CLKMODE_APLL_PCIE);
    
        HW_SET_FIELD32(regVal, CM_CLKMODE_APLL_PCIE_CLKDIV_BYPASS,
                        CM_CLKMODE_APLL_PCIE_CLKDIV_BYPASS_PCIEDIVBY2_BYPASS_1);
    
        HW_SET_FIELD32(regVal, CM_CLKMODE_APLL_PCIE_REFSEL,
                        CM_CLKMODE_APLL_PCIE_REFSEL_CLKREF_ADPLL);
    
        HW_WR_REG32(SOC_CKGEN_CM_CORE_BASE + CM_CLKMODE_APLL_PCIE, regVal);
    
        HW_WR_FIELD32(SOC_CKGEN_CM_CORE_BASE + CM_CLKMODE_APLL_PCIE,
                        CM_CLKMODE_APLL_PCIE_MODE_SELECT,
                        CM_CLKMODE_APLL_PCIE_MODE_SELECT_APLL_FORCE_LOCK_MODE);
    
        /*Wait for APLL lock*/
        while (((HW_RD_REG32(SOC_CKGEN_CM_CORE_BASE + CM_IDLEST_APLL_PCIE) &
                CM_IDLEST_APLL_PCIE_ST_APLL_CLK_MASK) <<
                CM_IDLEST_APLL_PCIE_ST_APLL_CLK_SHIFT) !=
                CM_IDLEST_APLL_PCIE_ST_APLL_CLK_APLL_LOCKED)
        {
            ;
        }
    }
    
    void PlatformPCIECtrlConfig(void)
    {
        uint32_t regVal;
    
        /* Configure the PCIE PHYs to x1 or x2 mode */
        regVal = HW_RD_REG32(
            SOC_SEC_EFUSE_REGISTERS_BASE + CTRL_CORE_PCIE_CONTROL);
    
        HW_SET_FIELD32(regVal, CTRL_CORE_PCIE_CONTROL_PCIE_B1C0_MODE_SEL,
                        0x00U);
    
        HW_WR_REG32(SOC_SEC_EFUSE_REGISTERS_BASE + CTRL_CORE_PCIE_CONTROL,
                    regVal);
    
        regVal = HW_RD_REG32(
            SOC_SEC_EFUSE_REGISTERS_BASE + CTRL_CORE_PCIE_CONTROL);
    
        HW_SET_FIELD32(regVal, CTRL_CORE_PCIE_CONTROL_PCIE_B0_B1_TSYNCEN,
                        0x00U);
    
        HW_WR_REG32(SOC_SEC_EFUSE_REGISTERS_BASE + CTRL_CORE_PCIE_CONTROL,
                    regVal);
    
        /*CONTROL MODULE PWR CTL REG status of PCIeSS1*/
        regVal = HW_RD_REG32(
            SOC_SEC_EFUSE_REGISTERS_BASE + CTRL_CORE_PHY_POWER_PCIESS1);
    
        HW_SET_FIELD32(regVal, CTRL_CORE_PHY_POWER_PCIESS1_PCIESS1_PWRCTL_CMD,
                        0x03U);
    
        HW_SET_FIELD32(regVal, CTRL_CORE_PHY_POWER_PCIESS1_PCIESS1_PWRCTL_CLKFREQ,
                        0x1AU);
    
        HW_WR_REG32(SOC_SEC_EFUSE_REGISTERS_BASE + CTRL_CORE_PHY_POWER_PCIESS1,
                    regVal);
    
        /*CONTROL MODULE PWR CTL REG status of PCIeSS2*/
        regVal = HW_RD_REG32(
            SOC_SEC_EFUSE_REGISTERS_BASE + CTRL_CORE_PHY_POWER_PCIESS2);
    
        HW_SET_FIELD32(regVal, CTRL_CORE_PHY_POWER_PCIESS2_PCIESS2_PWRCTL_CMD,
                        0x03U);
    
        HW_SET_FIELD32(regVal, CTRL_CORE_PHY_POWER_PCIESS2_PCIESS2_PWRCTL_CLKFREQ,
                        0x1AU);
    
        HW_WR_REG32(SOC_SEC_EFUSE_REGISTERS_BASE + CTRL_CORE_PHY_POWER_PCIESS2,
                    regVal);
    
        /*Set PCIeSS1 delay count*/
        HW_WR_FIELD32(SOC_SEC_EFUSE_REGISTERS_BASE + CTRL_CORE_PCIE_PCS,
                        CTRL_CORE_PCIE_PCS_PCIESS1_PCS_RC_DELAY_COUNT, 0xF1U);
    
    
        /*Set PCIeSS2 delay count*/
        HW_WR_FIELD32(SOC_SEC_EFUSE_REGISTERS_BASE + CTRL_CORE_PCIE_PCS,
                        CTRL_CORE_PCIE_PCS_PCIESS2_PCS_RC_DELAY_COUNT, 0xF1U);
    }
    
    void PlatformPCIEReset(void)
    {
        /*Reset PCIeSS1*/
        HW_WR_FIELD32(SOC_L3INIT_PRM_BASE + RM_PCIESS_RSTCTRL,
                        RM_PCIESS_RSTCTRL_RST_LOCAL_PCIE1,
                      RM_PCIESS_RSTCTRL_RST_LOCAL_PCIE1_CLEAR);
    
        /* Wait till PCIeSS1 is out of reset */
        while (((HW_RD_REG32(SOC_L3INIT_PRM_BASE + RM_PCIESS_RSTST) &
                RM_PCIESS_RSTST_RST_LOCAL_PCIE1_MASK) <<
                RM_PCIESS_RSTST_RST_LOCAL_PCIE1_SHIFT) !=
                RM_PCIESS_RSTST_RST_LOCAL_PCIE1_RESET_YES)
        {
            ;
        }
    
        /*Reset PCIeSS2*/
        HW_WR_FIELD32(SOC_L3INIT_PRM_BASE + RM_PCIESS_RSTCTRL,
                        RM_PCIESS_RSTCTRL_RST_LOCAL_PCIE2,
                      RM_PCIESS_RSTCTRL_RST_LOCAL_PCIE2_CLEAR);
    
        /* Wait till PCIeSS2 is out of reset */
        while (((HW_RD_REG32(SOC_L3INIT_PRM_BASE + RM_PCIESS_RSTST) &
                RM_PCIESS_RSTST_RST_LOCAL_PCIE2_MASK) <<
                RM_PCIESS_RSTST_RST_LOCAL_PCIE2_SHIFT) !=
                RM_PCIESS_RSTST_RST_LOCAL_PCIE2_RESET_YES)
        {
            ;
        }
    }
    
    void PlatformPCIESS1PhyConfig(void)
    {
        uint32_t regVal;
    
        /*Program for Analog circuits in the IP.*/
        regVal  = HW_RD_REG32(SOC_OCP2SCP3_USB3RX_PHY_PCIE1_BASE + 0x0CU);
        regVal &= 0x07FFFFFFU;
        regVal |= ((uint32_t) 0x10U << 24U);
        HW_WR_REG32(SOC_OCP2SCP3_USB3RX_PHY_PCIE1_BASE + 0x0CU, regVal);
    
        regVal  = HW_RD_REG32(SOC_OCP2SCP3_USB3RX_PHY_PCIE1_BASE + 0x0CU);
        regVal &= 0xFFFC3FFFU;
        regVal |= ((uint32_t) 0x10U << 12U);
        HW_WR_REG32(SOC_OCP2SCP3_USB3RX_PHY_PCIE1_BASE + 0x0CU, regVal);
    
        /*Program for digital section of the IP.*/
        regVal  = HW_RD_REG32(SOC_OCP2SCP3_USB3RX_PHY_PCIE1_BASE + 0x28U);
        regVal &= 0xE30007FFU;
        regVal |= 0x001B3000U;
        HW_WR_REG32(SOC_OCP2SCP3_USB3RX_PHY_PCIE1_BASE + 0x28U, regVal);
    
        regVal  = HW_RD_REG32(SOC_OCP2SCP3_USB3RX_PHY_PCIE1_BASE + 0x0CU);
        regVal &= 0xFFFFFF9FU;
        regVal |= ((uint32_t) 0x0U << 4U);
        HW_WR_REG32(SOC_OCP2SCP3_USB3RX_PHY_PCIE1_BASE + 0x0CU, regVal);
    
        /*Determines which of the 4 EFUSE registers. Selects dll_rate2_coarsetrim*/
        regVal  = HW_RD_REG32(SOC_OCP2SCP3_USB3RX_PHY_PCIE1_BASE + 0x1CU);
        regVal &= 0x3FFFFFFFU;
        regVal |= ((uint32_t) 0x8U << 28U);
        HW_WR_REG32(SOC_OCP2SCP3_USB3RX_PHY_PCIE1_BASE + 0x1CU, regVal);
    
        /*
        * Programs the DLL and the Phase Interpolator analog RW 0x3
        * circuits to work with different clock frequencies
        */
        regVal  = HW_RD_REG32(SOC_OCP2SCP3_USB3RX_PHY_PCIE1_BASE + 0x24U);
        regVal &= 0x3FFFFFFFU;
        regVal |= ((uint32_t) 0xCU << 28U);
        HW_WR_REG32(SOC_OCP2SCP3_USB3RX_PHY_PCIE1_BASE + 0x24U, regVal);
    
        /*Program IP Equalizer*/
        regVal  = HW_RD_REG32(SOC_OCP2SCP3_USB3RX_PHY_PCIE1_BASE + 0x38U);
        regVal &= 0x0U;
        regVal |= 0x0000F80FU;
        HW_WR_REG32(SOC_OCP2SCP3_USB3RX_PHY_PCIE1_BASE + 0x38U, regVal);
    }
    
    void PlatformPCIESS2PhyConfig(void)
    {
        uint32_t regVal;
    
        /*Program for Analog circuits in the IP.*/
        regVal  = HW_RD_REG32(SOC_OCP2SCP3_USB3RX_PHY_PCIE2_BASE + 0x0CU);
        regVal &= 0x07FFFFFFU;
        regVal |= ((uint32_t) 0x10U << 24U);
        HW_WR_REG32(SOC_OCP2SCP3_USB3RX_PHY_PCIE2_BASE + 0x0CU, regVal);
    
        regVal  = HW_RD_REG32(SOC_OCP2SCP3_USB3RX_PHY_PCIE2_BASE + 0x0CU);
        regVal &= 0xFFFC3FFFU;
        regVal |= ((uint32_t) 0x10U << 12U);
        HW_WR_REG32(SOC_OCP2SCP3_USB3RX_PHY_PCIE2_BASE + 0x0CU, regVal);
    
        /*Program for digital section of the IP.*/
        regVal  = HW_RD_REG32(SOC_OCP2SCP3_USB3RX_PHY_PCIE2_BASE + 0x28U);
        regVal &= 0xE30007FFU;
        regVal |= 0x001B3000U;
        HW_WR_REG32(SOC_OCP2SCP3_USB3RX_PHY_PCIE2_BASE + 0x28U, regVal);
    
        regVal  = HW_RD_REG32(SOC_OCP2SCP3_USB3RX_PHY_PCIE2_BASE + 0x0CU);
        regVal &= 0xFFFFFF9FU;
        regVal |= ((uint32_t) 0x0U << 4U);
        HW_WR_REG32(SOC_OCP2SCP3_USB3RX_PHY_PCIE2_BASE + 0x0CU, regVal);
    
        /*Determines which of the 4 EFUSE registers. Selects dll_rate2_coarsetrim*/
        regVal  = HW_RD_REG32(SOC_OCP2SCP3_USB3RX_PHY_PCIE2_BASE + 0x1CU);
        regVal &= 0x3FFFFFFFU;
        regVal |= ((uint32_t) 0x8U << 28U);
        HW_WR_REG32(SOC_OCP2SCP3_USB3RX_PHY_PCIE2_BASE + 0x1CU, regVal);
    
        /*
        * Programs the DLL and the Phase Interpolator analog RW 0x3
        * circuits to work with different clock frequencies
        */
        regVal  = HW_RD_REG32(SOC_OCP2SCP3_USB3RX_PHY_PCIE2_BASE + 0x24U);
        regVal &= 0x3FFFFFFFU;
        regVal |= ((uint32_t) 0xCU << 28U);
        HW_WR_REG32(SOC_OCP2SCP3_USB3RX_PHY_PCIE2_BASE + 0x24U, regVal);
    
        /*Program IP Equalizer*/
        regVal  = HW_RD_REG32(SOC_OCP2SCP3_USB3RX_PHY_PCIE2_BASE + 0x38U);
        regVal &= 0x0U;
        regVal |= 0x0000F80FU;
        HW_WR_REG32(SOC_OCP2SCP3_USB3RX_PHY_PCIE2_BASE + 0x38U, regVal);
    }
    
    void PCIEAppPrcmConfig(void)
    {
        PlatformPCIEClockEnable();
    
        UARTConfigPuts(SOC_UART1_BASE,"*** 11 ***", -1);
    
        PlatformPCIEPllConfig();
    
        UARTConfigPuts(SOC_UART1_BASE,"*** 22 ***", -1);
    
        PlatformPCIEReset(); // gets stuck here, also gets stuck here with the original order of function calls
    
        UARTConfigPuts(SOC_UART1_BASE,"*** 33 ***", -1);
    
        PlatformPCIECtrlConfig();
    
        UARTConfigPuts(SOC_UART1_BASE,"*** 44 ***", -1);
    
        PlatformPCIESS1PhyConfig();
    
        UARTConfigPuts(SOC_UART1_BASE,"*** 55 ***", -1);
    
        PlatformPCIESS2PhyConfig();
    
        UARTConfigPuts(SOC_UART1_BASE,"*** 66 ***", -1);
    
    }

  • Hi Nick,

    Are you using 23x23 package or 17x17 package?

    Regards,
    Rishabh
  • Hi Nick,

    One additional question. When you got the two lanes working what was the value of PCIE_1LANE_2LANE_SELECTION field of CTRL_CORE_CONTROL_IO_2 register.

    Regards,
    Rishabh
  • Hi Rishabh,

    I don't remember writing to that register, right now I see on page 4582 of TRM that the PCIE_1LANE_2LANE_SELECTION field is reserved.
    As for the SoC I'm using, its 23x23.

    Regards,
    Nick
  • Hi Nick,

    Can you read the same bit from the memory browser window of the CCS and confirm the value.
    Also I am assuming you are still using your custom board and not the EVM.
    There is something fundamental that seems to be missing here.
    RM_PCIESS_RSTST[1] should update when you set RM_PCIESS_RSTCTRL[1] to 0 irrespective of the PHY/Control Module settings.

    Regards,
    Rishabh
  • Hi Rishabh,

    I have just run the example in CCS and watched RM_PCIESS_RSTCTRL and RM_PCIESS_RSTST registers while debugging step by step (I built the example in debug profile). They don't seem to change at all, even when the reset of PCIeSS1 occurs which successfully polls the RM_PCIESS_RSTST[0]. I will copy their values from memory view below:

    0x4AE07310 L3INIT_PRM_RM_PCIESS_RSTCTRL
    0x4AE07310 00000000
    0x4AE07314 L3INIT_PRM_RM_PCIESS_RSTST
    0x4AE07314 00000003 00000000 00000000 00000000 00000000

    I have enabled continuous memory refresh and I can confirm that it is working because I can see DSPEVE temperature sensor register change its value all the time. The PCIE_1LANE_2LANE_SELECTION also remains unchanged with its value of 0.

    0x4A002558 CTRL_MODULE_CORE_CTRL_CORE_CONTROL_IO_2
    0x4A002558 00000001

    Regards,
    Nick
  • Hi Nick,

    As per the values you have shared above RM_PCIESS_RSTCTRL(0x0000_0000) and RM_PCIESS_RSTST(0x0000_0003) are correct.

    Please see the description of these two registers in the TRM.

    In order to lift/de-assert the reset you have to write 0 and the state bit should be set to 1.

    You are observing a hang due to bug in the code. You should use >> instead of <<

        /*Reset PCIeSS1*/
        HW_WR_FIELD32(SOC_L3INIT_PRM_BASE + RM_PCIESS_RSTCTRL,
                        RM_PCIESS_RSTCTRL_RST_LOCAL_PCIE1,
                      RM_PCIESS_RSTCTRL_RST_LOCAL_PCIE1_CLEAR);
    
        /* Wait till PCIeSS1 is out of reset */
        while (((HW_RD_REG32(SOC_L3INIT_PRM_BASE + RM_PCIESS_RSTST) &
                RM_PCIESS_RSTST_RST_LOCAL_PCIE1_MASK) >>
                RM_PCIESS_RSTST_RST_LOCAL_PCIE1_SHIFT) !=
                RM_PCIESS_RSTST_RST_LOCAL_PCIE1_RESET_YES)
        {
            ;
        }
    
        /*Reset PCIeSS2*/
        HW_WR_FIELD32(SOC_L3INIT_PRM_BASE + RM_PCIESS_RSTCTRL,
                        RM_PCIESS_RSTCTRL_RST_LOCAL_PCIE2,
                      RM_PCIESS_RSTCTRL_RST_LOCAL_PCIE2_CLEAR);
    
        /* Wait till PCIeSS2 is out of reset */
        while (((HW_RD_REG32(SOC_L3INIT_PRM_BASE + RM_PCIESS_RSTST) &
                RM_PCIESS_RSTST_RST_LOCAL_PCIE2_MASK) >>
                RM_PCIESS_RSTST_RST_LOCAL_PCIE2_SHIFT) !=
                RM_PCIESS_RSTST_RST_LOCAL_PCIE2_RESET_YES)
        {
            ;
        }

    Regards,

    Rishabh

  • Hi Rishabh,

    Yes, that seems to have resolved my problem and I have successfully transfered data via PCIeSS2. I investigated a bit further and have seen the same mistake in a few more places in the example.
    It would be great if that could be patched for the next release of PDK.

    Thank you for the help on my journey to utilizing PCIe. I hope that this would be the last of my problems.

    Regards,
    Nick
  • Hi Nick,

    Thanks for the confirmation. We will make the necessary changes in the app.

    Regards,
    Rishabh
  • Hi Nick,

    I need one more information.
    As per HW team PCIE_1LANE_2LANE_SELECTION bit needs to be set to 0x1 for Subsystem 1 to work in x2 mode and set to 0x0 for Subsystem 1 and subsystem 2 to work in x1 mode simultaneously.
    As per your observation this bit is set to 0x0 when your example is working fine in both cases.
    Can you change this bit to 0x1 and try both the cases once again.
    This will help us understand the correct configuration in order to make necessary changes to the TRM.

    Regards,
    Rishabh
  • Hi Rishabh,

    I apologize for the delayed response. Here's what I've done: I commented out the code that  chooses x1 or x2 mode frome the code snippet I shared in my previous PCIe thread (e2e.ti.com/.../2474480 and set the PCIE_1LANE_2LANE_SELECTION and now code looks like this:

    void PlatformPCIECtrlConfig(void)
    {
        uint32_t regVal;
    
        /* Configure the PCIE PHYs to x1 or x2 mode BY SETTING PCIE_1LANE_2LANE_SELECTION */
        regVal = HW_RD_REG32(
            SOC_CTRL_MODULE_CORE_CORE_REGISTERS_BASE + CTRL_CORE_CONTROL_IO_2);
    
        HW_SET_FIELD32(regVal, CTRL_CORE_CONTROL_IO_2_PCIE_1LANE_2LANE_SELECTION,
                        CTRL_CORE_CONTROL_IO_2_PCIE_1LANE_2LANE_SELECTION_2_LANE);
    
        HW_WR_REG32(SOC_CTRL_MODULE_CORE_CORE_REGISTERS_BASE + CTRL_CORE_CONTROL_IO_2,
                    regVal);
    
        /*CONTROL MODULE PWR CTL REG status of PCIeSS1*/
        regVal = HW_RD_REG32(
            SOC_SEC_EFUSE_REGISTERS_BASE + CTRL_CORE_PHY_POWER_PCIESS1);
    
        HW_SET_FIELD32(regVal, CTRL_CORE_PHY_POWER_PCIESS1_PCIESS1_PWRCTL_CMD,
                        0x03U);
    
        HW_SET_FIELD32(regVal, CTRL_CORE_PHY_POWER_PCIESS1_PCIESS1_PWRCTL_CLKFREQ,
                        0x1AU);
    
        HW_WR_REG32(SOC_SEC_EFUSE_REGISTERS_BASE + CTRL_CORE_PHY_POWER_PCIESS1,
                    regVal);
    
        /*CONTROL MODULE PWR CTL REG status of PCIeSS2*/
        regVal = HW_RD_REG32(
            SOC_SEC_EFUSE_REGISTERS_BASE + CTRL_CORE_PHY_POWER_PCIESS2);
    
        HW_SET_FIELD32(regVal, CTRL_CORE_PHY_POWER_PCIESS2_PCIESS2_PWRCTL_CMD,
                        0x03U);
    
        HW_SET_FIELD32(regVal, CTRL_CORE_PHY_POWER_PCIESS2_PCIESS2_PWRCTL_CLKFREQ,
                        0x1AU);
    
        HW_WR_REG32(SOC_SEC_EFUSE_REGISTERS_BASE + CTRL_CORE_PHY_POWER_PCIESS2,
                    regVal);
    
        /*Set PCIeSS1 delay count*/
        HW_WR_FIELD32(SOC_SEC_EFUSE_REGISTERS_BASE + CTRL_CORE_PCIE_PCS,
                        CTRL_CORE_PCIE_PCS_PCIESS1_PCS_RC_DELAY_COUNT, 0xF1U);
    
    
        /*Set PCIeSS2 delay count*/
        HW_WR_FIELD32(SOC_SEC_EFUSE_REGISTERS_BASE + CTRL_CORE_PCIE_PCS,
                        CTRL_CORE_PCIE_PCS_PCIESS2_PCS_RC_DELAY_COUNT, 0xF1U);
    }

    The results of the tests are following:

    - when PCIeSS1's link configured as 2-lane later in the code (PCIEConfigLink() call) on both the RC and EP side I'm getting transfer speed of 370MBps which corresponds to single lane usage ---> conclusion: PCIE_1LANE_2LANE_SELECTION does not affect the configuration and 1 lane is selected by default

    - when I utilize both PCIeSS1 and PCIeSS2 with one lane each the example expectedly works with 370MBps per lane. Why? Because it seems that the value of CTRL_CORE_PCIE_CONTROL_PCIE_B1C0_MODE_SEL matters and it is by default 0 (notice that I do not change its value in the code above) which means 1 lane per PCIe subsystem and the PCIE_1LANE_2LANE_SELECTION does not affect anything.

    In conclusion, as I said I followed the PCIe programming sequence from current version of PRM (I have SPRUI29D) and everything works ok. Also, in the registers specification the PCIE_1LANE_2LANE_SELECTION is denoted as RESERVED which makes sense since it does not seem to affect anything.

    I hope that my explaination is clear. I am looking forward to hearing from you. I am quite interested in this issue.

    Regards,

    Nick

  • Hi Nick,

    Thanks for the confirmation.
    I will contact the HW team with this observation and let's see their response.
    Turnaround time for this might be a few days so apologies in advance.
    For now you can continue your development using the code that is working for you.

    Regards,
    Rishabh
  • Hi Nick,

    I have checked with the HW team.
    PCIE_1LANE_2LANE_SELECTION field should not affect the selection as observed by you.
    It was an old information which created the confusion.
    Thanks for your patience.

    Regards,
    Rishabh
  • Hi Rishabh,

    Glad I could help :)

    Regards,
    Nick
  • Hi Nick,

    Let's close this thread.
    Kindly mark the post that answered your question as "This resolved my issue".

    Regards,
    Rishabh