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.

AM5706: Configuring MSI on PCIe End POint

Part Number: AM5706

Hello,

I am currently trying to get MSI working on a custom board based on the AM571x IDK.

The Root Complex is a QNX system.

 The PCIe link comes up and dat transfers are working.

We are now trying to get the MSI interrupts working.

According to the TRM spruhz7j section 24.9.4.6.2.2.2 PCIe Controller MSI Transmission Methods (EP mode)  there are two methods for MSI transmission.

We are using the HW method as that seem to be the one used in all the example code.

I understand that the MSI is an outbound memory write operation from the EP and requires an outbound address translation.

The example code for setting up the outbound translation for MSI is

    /* Set up OB region for MSI generation on EP */
    /* Configure OB region for MSI generation access space */
    regionParams.regionDir = PCIE_ATU_REGION_DIR_OUTBOUND;
    regionParams.tlpType = PCIE_TLP_TYPE_MEM;
    regionParams.enableRegion = 1;

    regionParams.lowerBaseAddr = PCIE_WINDOW_MSI_ADDR + resSize;
    regionParams.upperBaseAddr = 0; /* only 32 bits needed given data area size */
    regionParams.regionWindowSize = PCIE_WINDOW_MSI_MASK;

    regionParams.lowerTargetAddr = PCIE_PCIE_MSI_BASE;
    regionParams.upperTargetAddr = 0U;

    retVal = Pcie_atuRegionConfig(handle, pcie_LOCATION_LOCAL, (uint32_t) 0U, &regionParams);

I understand the lower and upper base address is the local memory region the MSI will be written to. The lower and upper target address should be in the PCIe RC memory space. All the example code appears to be written with the expectation that the RC will be another TI processor and has the target address hard coded.

Am I correct in that I should read the PCIECTRL_EP_DBICS_MSI_ADD_L32 and PCIECTRL_EP_DBICS_MSI_ADD_U32 registers and used these for the target address for MSI outbound translation?

Joe

  • Hi Joe,

    I was going through some old threads that were open. Apologies for the long delay, but is this thread still open?

    I looked into what is being done for the next generation device after AM57x in the Linux driver and found this function for sending MSI: https://git.ti.com/cgit/ti-linux-kernel/ti-linux-kernel/tree/drivers/pci/controller/cadence/pcie-cadence-ep.c?h=ti-linux-5.10.y#n443

    In the code, what is being done is the following:

    	/* Get the PCI address where to write the data into. */
    	pci_addr = cdns_pcie_ep_fn_readl(pcie, fn, cap + PCI_MSI_ADDRESS_HI);
    	pci_addr <<= 32;
    	pci_addr |= cdns_pcie_ep_fn_readl(pcie, fn, cap + PCI_MSI_ADDRESS_LO);
    	pci_addr &= GENMASK_ULL(63, 2);
    
    	/* Set the outbound region if needed. */
    	if (unlikely(ep->irq_pci_addr != (pci_addr & ~pci_addr_mask) ||
    		     ep->irq_pci_fn != fn)) {
    		/* First region was reserved for IRQ writes. */
    		cdns_pcie_set_outbound_region(pcie, 0, fn, 0,
    					      false,
    					      ep->irq_phys_addr,
    					      pci_addr & ~pci_addr_mask,
    					      pci_addr_mask + 1);
    		ep->irq_pci_addr = (pci_addr & ~pci_addr_mask);
    		ep->irq_pci_fn = fn;
    	}

    I assume it would be similar for AM57x, in which the HI and LO address for MSI is read and used for outbound writes. Hope this can be of reference.

    Regards,

    Takuma