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.

TMS320C6657: PCIe : MSI interrupts configuration

Part Number: TMS320C6657

Hello , 

I need some assistance to configure MSI interruption between RC and EPP (evm : tms320c6657).

Thank you 

  • ,

    Once you install, PROCESSOR-SDK-RTOS-C665x 06_03_00_106
    http://software-dl.ti.com/processor-sdk-rtos/esd/C665x/latest/index_FDS.html

    in PDK package, in the file pcie.c, the configuration of MSI interrupts and other MSI functions are given.

    File location : C:\ti\pdk_c665x_2_0_16\packages\ti\csl\src\ip\pcie\V1\priv

    void PCIEMsiMailboxConfig(uint32_t                      baseAddr,
                              const pcieLocationParams_t   *locationParams,
                              const pcieMsiMailboxParams_t *msiMailboxParams)
    {
        uint32_t cfgAddr;
    
        if (PCIE_DEVICE_TYPE_RC == PCIEGetDeviceType(baseAddr))
        {
            if (PCIE_LOCATION_LOCAL == locationParams->location)
            {
                /* Configure local MSI mail box lower address. */
                cfgAddr = baseAddr + PCIECTRL_PL_OFFSET +
                          PCIECTRL_PL_MSI_CTRL_ADDRESS;
    
                HW_WR_REG32(cfgAddr, msiMailboxParams->lowerAddr);
    
                /* Configure local MSI mail box upper address. */
                cfgAddr = baseAddr + PCIECTRL_PL_OFFSET +
                          PCIECTRL_PL_MSI_CTRL_UPPER_ADDRESS;
    
                HW_WR_REG32(cfgAddr, msiMailboxParams->upperAddr);
            }
            else
            {
                /* Get outbound remote configuration space. */
                if ((uint32_t) SOC_PCIE_SS1_CONF_BASE == baseAddr)
                {
                    cfgAddr = (uint32_t) SOC_PCIE_SS1_DAT_BASE +
                              locationParams->outboundCfgOffset +
                              PCIECTRL_EP_PCIEWIRE_OFFSET;
                }
                else
                {
                    cfgAddr = (uint32_t) SOC_PCIE_SS2_DAT_BASE +
                              locationParams->outboundCfgOffset +
                              PCIECTRL_EP_PCIEWIRE_OFFSET;
                }
    
                /* Configure Remote MSI descriptor lower address. */
                HW_WR_REG32(
                    cfgAddr + PCIECTRL_EP_PCIEWIRE_MSI_ADDR_L32,
                    msiMailboxParams->lowerAddr);
    
                /* Configure Remote MSI descriptor upper address. */
                HW_WR_REG32(
                    cfgAddr + PCIECTRL_EP_PCIEWIRE_MSI_ADDR_U32,
                    msiMailboxParams->upperAddr);
    
                /* Configure Remote MSI descriptor data. */
                HW_WR_REG32(
                    cfgAddr + PCIECTRL_EP_PCIEWIRE_MSI_DATA,
                    msiMailboxParams->data);
            }
        }
        else
        {
            if (PCIE_LOCATION_LOCAL == locationParams->location)
            {
                /* Configure local MSI mail box lower address. */
                cfgAddr = baseAddr + PCIECTRL_EP_DBICS_OFFSET +
                          PCIECTRL_EP_DBICS_MSI_ADDR_L32;
    
                HW_WR_REG32(cfgAddr, msiMailboxParams->lowerAddr);
    
                /* Configure local MSI mail box upper address. */
                cfgAddr = baseAddr + PCIECTRL_EP_DBICS_OFFSET +
                          PCIECTRL_EP_DBICS_MSI_ADDR_U32;
    
                HW_WR_REG32(cfgAddr, msiMailboxParams->upperAddr);
    
                /* Configure local MSI mail box Data. */
                cfgAddr = baseAddr + PCIECTRL_EP_DBICS_OFFSET +
                          PCIECTRL_EP_DBICS_MSI_DATA;
    
                HW_WR_REG32(cfgAddr, msiMailboxParams->data);
            }
        }
    }
    
    void PCIEMsiCtrl(uint32_t                    baseAddr,
                     const pcieLocationParams_t *locationParams,
                     const pcieMsiCtrlParams_t  *msiCtrlParams)
    {
        uint32_t regVal;
        uint32_t cfgAddr;
    
        if (PCIE_DEVICE_TYPE_RC == PCIEGetDeviceType(baseAddr))
        {
            if (PCIE_LOCATION_LOCAL == locationParams->location)
            {
                /* Configure local MSI capabilities. */
                cfgAddr = baseAddr + PCIECTRL_RC_DBICS_OFFSET +
                          PCIECTRL_RC_DBICS_MSI_CAP;
    
                regVal = HW_RD_REG32(cfgAddr);
    
                /* Enable or disable  64 bit MSI generation. */
                HW_SET_FIELD32(
                    regVal,
                    PCIECTRL_RC_DBICS_MSI_CAP_MSI_64_EN,
                    msiCtrlParams->enable64Bit);
    
                /* Enable or disable multiple msg capability. */
                HW_SET_FIELD32(
                    regVal,
                    PCIECTRL_RC_DBICS_MSI_CAP_MME,
                    msiCtrlParams->enableMultiMsg);
    
                /* Enable or disable MSI generation. */
                HW_SET_FIELD32(
                    regVal,
                    PCIECTRL_RC_DBICS_MSI_CAP_MSI_EN,
                    msiCtrlParams->enableMsi);
    
                HW_WR_REG32(cfgAddr, regVal);
            }
            else
            {
                /* Get outbound remote configuration space. */
                if ((uint32_t) SOC_PCIE_SS1_CONF_BASE == baseAddr)
                {
                    cfgAddr = (uint32_t) SOC_PCIE_SS1_DAT_BASE +
                              locationParams->outboundCfgOffset +
                              PCIECTRL_EP_PCIEWIRE_OFFSET +
                              PCIECTRL_EP_PCIEWIRE_MSI_CAP;
                }
                else
                {
                    cfgAddr = (uint32_t) SOC_PCIE_SS2_DAT_BASE +
                              locationParams->outboundCfgOffset +
                              PCIECTRL_EP_PCIEWIRE_OFFSET +
                              PCIECTRL_EP_PCIEWIRE_MSI_CAP;
                }
    
                regVal = HW_RD_REG32(cfgAddr);
    
                /* Enable or disable  64 bit MSI generation. */
                HW_SET_FIELD32(
                    regVal,
                    PCIECTRL_EP_PCIEWIRE_MSI_CAP_MSI_64_EN,
                    msiCtrlParams->enable64Bit);
    
                /* Enable or disable multiple msg capability. */
                HW_SET_FIELD32(
                    regVal,
                    PCIECTRL_EP_PCIEWIRE_MSI_CAP_MME,
                    msiCtrlParams->enableMultiMsg);
    
                /* Enable or disable MSI generation. */
                HW_SET_FIELD32(
                    regVal,
                    PCIECTRL_EP_PCIEWIRE_MSI_CAP_MSI_EN,
                    msiCtrlParams->enableMsi);
    
                HW_WR_REG32(cfgAddr, regVal);
            }
        }
        else
        {
            if (PCIE_LOCATION_LOCAL == locationParams->location)
            {
                /* Configure local MSI capabilities. */
                cfgAddr = baseAddr + PCIECTRL_EP_DBICS_OFFSET +
                          PCIECTRL_EP_DBICS_MSI_CAP;
    
                regVal = HW_RD_REG32(cfgAddr);
    
                /* Enable or disable  64 bit MSI generation. */
                HW_SET_FIELD32(
                    regVal,
                    PCIECTRL_EP_DBICS_MSI_CAP_MSI_64_EN,
                    msiCtrlParams->enable64Bit);
    
                /* Enable or disable multiple msg capability. */
                HW_SET_FIELD32(
                    regVal,
                    PCIECTRL_EP_DBICS_MSI_CAP_MME,
                    msiCtrlParams->enableMultiMsg);
    
                /* Enable or disable MSI generation. */
                HW_SET_FIELD32(
                    regVal,
                    PCIECTRL_EP_DBICS_MSI_CAP_MSI_EN,
                    msiCtrlParams->enableMsi);
    
                HW_WR_REG32(cfgAddr, regVal);
            }
        }
    }
    
    void PCIEMsiIntrCtrl(uint32_t baseAddr,
                         uint32_t msiIntrNum,
                         uint32_t msiIntrGroup,
                         uint32_t enableMsiIntr)
    {
        uint32_t regVal;
        uint32_t cfgAddr;
    
        /* Enable or disable MSI interrupt. */
        cfgAddr = baseAddr + PCIECTRL_PL_OFFSET +
                  PCIECTRL_PL_MSI_CTRL_INT_ENABLE(msiIntrGroup);
    
        regVal = HW_RD_REG32(cfgAddr);
    
        if (TRUE == enableMsiIntr)
        {
            regVal |= ((uint32_t) 1U << msiIntrNum);
        }
        else
        {
            regVal &= (~((uint32_t) 1U << msiIntrNum));
        }
    
        HW_WR_REG32(cfgAddr, regVal);
    }
    
    uint32_t PCIEMsiActiveIntrStatus(uint32_t baseAddr, uint32_t msiIntrGroup)
    {
        return HW_RD_REG32(
                   baseAddr + PCIECTRL_PL_OFFSET +
                   PCIECTRL_PL_MSI_CTRL_INT_STATUS(msiIntrGroup));
    }
    
    void PCIEMsiActiveIntrClear(uint32_t baseAddr,
                                uint32_t msiIntrGroup,
                                uint32_t intrMask)
    {
        HW_WR_REG32(
            baseAddr + PCIECTRL_PL_OFFSET +
            PCIECTRL_PL_MSI_CTRL_INT_STATUS(msiIntrGroup),
            intrMask);
    }
    
    void PCIEMsiTransmit(uint32_t          baseAddr,
                         pcieMsiIntrType_t msiType,
                         uint32_t          msiOutboundCfgSpace)
    {
        uint32_t regVal;
        uint32_t msiData;
        uint32_t cfgAddr;
    
        /* Get MSI data. */
        msiData = HW_RD_REG32(
            baseAddr + PCIECTRL_EP_DBICS_OFFSET +
            PCIECTRL_EP_DBICS_MSI_DATA);
    
        if (PCIE_MSI_INTR_TYPE_HW == msiType)
        {
            /* Configure MSI data to be written into XMT register. */
            regVal =
                ((msiData <<
                  PCIECTRL_TI_CONF_MSI_XMT_VECTOR_SHIFT) &
                 PCIECTRL_TI_CONF_MSI_XMT_VECTOR_MASK);
    
            regVal |=
                ((uint32_t) PCIECTRL_TI_CONF_MSI_XMT_REQ_GRANT <<
                 PCIECTRL_TI_CONF_MSI_XMT_REQ_GRANT_SHIFT);
    
            /* Grant MSI request. */
            HW_WR_REG32(
                baseAddr + PCIECTRL_TI_CONF_OFFSET + PCIECTRL_TI_CONF_MSI_XMT,
                regVal);
    
            /* Wait till MSI request is granted. */
            do
            {
                regVal = HW_RD_REG32(
                    baseAddr + PCIECTRL_TI_CONF_OFFSET +
                    PCIECTRL_TI_CONF_MSI_XMT) &
                         PCIECTRL_TI_CONF_MSI_XMT_REQ_GRANT_MASK;
            } while (PCIECTRL_TI_CONF_MSI_XMT_REQ_GRANT_PENDING == regVal);
        }
        else
        {
            /* Get outbound remote configuration space. */
            if ((uint32_t) SOC_PCIE_SS1_CONF_BASE == baseAddr)
            {
                cfgAddr = (uint32_t) SOC_PCIE_SS1_DAT_BASE + msiOutboundCfgSpace;
            }
            else
            {
                cfgAddr = (uint32_t) SOC_PCIE_SS2_DAT_BASE + msiOutboundCfgSpace;
            }
    
            HW_WR_REG32(cfgAddr, msiData);
        }
    }
    

    Regards

    Shankari G