LS1046A EP MSI

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

LS1046A EP MSI

941 Views
fcenedese
Contributor I

Hello

We're creating a PCIe board for PC using an LS1046A as PCIe endpoint. It doesn't run linux but a proprietary RTOS, you can assume bare-metal. I already set up a BAR and can exchange data with PC (Windows for now, later also linux). But that's only using polling. For better performance I'd like to use interrupts.

PC -> LS1046A: As MSI is not possible I'm writing directly into register MSIIR (0x0158_0000) which triggers an interrupt. However the value in MSIR (0x0158_0004) is always 0x0000_0080, no matter what value I write. Is my understanding wrong that MSIIR can select which bit in which MSIR will be set? Shoould I do it differently?

LS1046A -> PC: I'm looking for code that can send an MSI on LS1046A which works without linux as OS. I saw the pci_endpoint_test.c but it didn't help me that much. Is there some other example code available? Or can somebody describe the necessary steps?

Thanks a lot

0 Kudos
Reply
6 Replies

823 Views
fcenedese
Contributor I

Sorry for the multiple posts, they didn't show up on my end and I thought they got lost

0 Kudos
Reply

829 Views
fcenedese
Contributor I

I've seen that before and have also studied it, but that didn't really help that much as it's mostly linux-specific config that I don't know how to read. However I seem to got it to work with this:

volatile uint64_t uAddr = m_pPcieReg->m_uMSIAddress + (((uint64_t)m_pPcieReg->m_uMSIAddressUpper) << 32);
volatile uint32_t* volatile pWrite = (uint32_t*)(0x4000000000 + uAddr);
// read configured MSI_Data and write it to MSI_Address (outgoing iATU)
*pWrite = m_pPcieReg->m_uMSIData;

I can't just use any address in a iATU, it must be the one for PCIe (0x40_0000_0000). However that is nowhere explained in the reference manual, it was rather a guess. And only then did I also see that u-boot already set up an outgoing iATU from this address to 0 (on the bus). Maybe a little explanation in the manual might be useful.

(That message got lost or was deleted)

 

0 Kudos
Reply

835 Views
fcenedese
Contributor I

I've seen that before and have also studied it, but that didn't really help that much as it's mostly linux-specific config that I don't know how to read. However I seem to got it to work with this:

volatile uint64_t uAddr = m_pPcieReg->m_uMSIAddress + (((uint64_t)m_pPcieReg->m_uMSIAddressUpper) << 32);
volatile uint32_t* volatile pWrite = (uint32_t*)(0x4000000000 + uAddr);
// read configured MSI_Data and write it to MSI_Address (outgoing iATU)
*pWrite = m_pPcieReg->m_uMSIData;

I can't just use any address in a iATU, it must be the one for PCIe (0x40_0000_0000). However that is nowhere explained in the reference manual, it was rather a guess. And only then did I also see that u-boot already set up an outgoing iATU from this address to 0 (on the bus). Maybe a little explanation in the manual might be useful.

0 Kudos
Reply

905 Views
fcenedese
Contributor I

Hi

Here's what I'm trying so far to send an interrupt from EP:

// Enabled Bus_master and Memory_space in Command_register, done in init
// *(volatile uint16*)0x03400004 = 0x0406
// Enabled MSI generation, done in init
// *(volatile uint16*)0x03400052 = 0x0089
// MSI
// with outgoing iATU from 0x015B0000 to 0xFEE00000, MSI_Address = 0xFEE00530)
volatile uint32* pReg = ((uint32*)0x015B0530);
// read configured MSI_Data and write it to MSI_Address (outgoing iATU)
*pReg = *(volatile uint32*)0x034C005C;

// legacy interrupt:
*(volatile uint32*)0x034C002C = 0x00000010;

But so far I couldn't get an interrupt on the driver side (RC) with any method. I assume the driver is correct as it works with other hardware. Is there anything else I need to do? Can the interrupt generation be checked without hardware analyzer?

0 Kudos
Reply

870 Views
yipingwang
NXP TechSupport
NXP TechSupport
0 Kudos
Reply

827 Views
fcenedese
Contributor I

I've seen that before and have also studied it, but that didn't really help that much as it's mostly linux-specific config that I don't know how to read. However I seem to got it to work with this:

volatile uint64_t uAddr = m_pPcieReg->m_uMSIAddress + (((uint64_t)m_pPcieReg->m_uMSIAddressUpper) << 32);
volatile uint32_t* volatile pWrite = (uint32_t*)(0x4000000000 + uAddr);
// read configured MSI_Data and write it to MSI_Address (outgoing iATU)
*pWrite = m_pPcieReg->m_uMSIData;

I can't just use any address in a iATU, it must be the one for PCIe (0x40_0000_0000). However that is nowhere explained in the reference manual, it was rather a guess. And only then did I also see that u-boot already set up an outgoing iATU from this address to 0 (on the bus). Maybe a little explanation in the manual might be useful.

0 Kudos
Reply