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.

66AK2L06: C66x CorePac Primary Interrupt #17 (PCIE_0_INT4_PLUS_N)

Part Number: 66AK2L06

Hi All!

66AK2L06 datasheet mentions interrupt #17 as primary C66x CorePac interrupt (table 7-22). It is described as PCIE_0_INT4_PLUS_N.

Looking further in ARM CorePac interrupt table INT4 is bound to MSI[0-3] (if I understand correctly).

Does it mean that PCIE_0_INT4_PLUS_N interrupt is

  • MSI[0-3] for core #0
  • MSI[4-7] for core #1
  • MSI[8-11] for core #2
  • MSI[12-15] for core #3

?

Now I am successfully receiving MSI0 with ARM CorePac. But with C66x no PCIE_0_INT4_PLUS_N events are generated.

Is it possible to receive MSI0 by ARM CorePac and C66x CorePac simultaneously?

Best Regards,
Yurii

  • Hi,

    I think you can process interrupt by one IRQ controller. You cannot map it to both C66x CorePac & ARM CorePac interrupt controllers simultaneously.

    Best Regards,
    Yordan

  • Hi Yordan,

    Thank you for the answer.

    Yordan Kovachev said:
    You cannot map it to both C66x CorePac & ARM CorePac interrupt controllers simultaneously.


    This is very strange. Because I can handle my MSI interrupt from CIC0 as secondary interrupt to C66X CorePac. I've dumped raw interrupts status from CIC0 registers and found that PCIE_0_INT5 is continuously triggering an event. From my understanding, MSI0 should map to PCIE_0_INT4 (event #279), not PCIE_0_INT5 (event #280). Maybe this is our hardware issue, which generates MSI1 instead of MSI0. But on the Linux side I call

    err = pci_alloc_irq_vectors(dev, 1, 1, PCI_IRQ_ALL_TYPES);
    pci_request_irq(pci_dev, 0, msi_handler, NULL, dev, "msi%i", 0);

    to allocate and handle MSI0 interrupt. And I thought that this will map to single MSI0. Can you confirm that CIC0 PCIE_0_INT4 (table 7-24 of datasheet) maps to MSI0?

    Looking at PCIe user guide, I think that I was wrong in my first assumption with PCIE_0_INT4_PLUS_N. It should be rewritten as:

    • MSI[0,4,8,12] for core #0
    • MSI[1,5,9,13] for core #1
    • MSI[2,6,10,14] for core #2
    • MSI[3,7,11,15] for core #3

    Can you give some explanation about PCIE_0_INT4_PLUS_N?

    Best Regards,
    Yurii

  • Hi,

    Sorry, for the confusion, but to clear things out:

    You are running linux on ARM and RTOS on DSP, right? And you want to trigger PCIE irq which should be handled by both ARM IRQ controller & DSP IRQ controller (have irq handler on both sides Linux & RTOS) at the same time?

    I was answering assuming you want to handle the interrupt with both arm & dsp irq controllers, and I see that you just want to receive (read irqregisters) at the same time, right (?); and maybe caused a confusion with my initial reply.

    Best Regards,
    Yordan

  • Yordan,

    Yordan Kovachev said:
    You are running linux on ARM and RTOS on DSP, right?


    I'm running Linux on ARM and bare metal on DSP (core #0 only for now). I boot DSP core #0 with simple driver (not mpmcl) which is able to mmap DSP's L2 and handles reset with syscon. Firmware is loaded from userspace by means of misc device (as in SDK).

    Yordan Kovachev said:
    And you want to trigger PCIE irq which should be handled by both ARM IRQ controller & DSP IRQ controller (have irq handler on both sides Linux & RTOS) at the same time?


    Exactly. And I've even managed to achieve this by routing MSI interrupt through CIC0. With little confusion about MSI interrupt to CIC0 system event mapping (as described in previous post).

    Best Regards,
    Yurii

    PS. I've made some edits in my previous before your reply.

  • Yordan Kovachev said:
    I was answering assuming you want to handle the interrupt with both arm & dsp irq controllers


    I want to receive MSI interrupts on both ARM and DSP. But MSI interrupt handling (e.g. writing MSIn_IRQ_STATUS and IRQ_EOI registers) is done by ARM side in keystone-pcie driver.

  • Hi,

    The PCIE legacy and MSI 0....31 interrupts are listed below:

    0 PCIe express legacy interrupt mode - INTA (RC mode only)
    1 PCIe express legacy interrupt mode - INTB (RC mode only)
    2 PCIe express legacy interrupt mode - INTC (RC mode only)
    3 PCIe express legacy interrupt mode - INTD (RC mode only)
    4 MSI interrupts 0, 8, 16, 24 (EP/RC modes)
    5 MSI interrupts 1, 9, 17, 25 (EP/RC modes)
    6 MSI interrupts 2, 10, 18, 26 (EP/RC modes)
    7 MSI interrupts 3, 11, 19, 27 (EP/RC modes)
    8 MSI Interrupts 4, 12, 20, 28 (EP/RC modes)
    9 MSI Interrupts 5, 13, 21, 29 (EP/RC modes)
    10 MSI Interrupts 6, 14, 22, 30 (EP/RC modes)
    11 MSI Interrupts 7, 15, 23, 31 (EP/RC modes)

    I thought PCIE_0_INT4_PLUS_N means that you can use this for MSI interrupt 0, 8, 16, 24 for core 0; 1,9, 17, 25 for core 1, .... up to 4 DSP cores. Those are the primary interrupt to CPU.

    You can also use CIC0 input (279, ... 282) for the same purpose.

    Regards, Eric

  • Hi lding,

    Thank you for the answer, PCIE_0_INT4_PLUS_N purpose is completely clear now.

    The only thing I can't figure out is that why our driver handles MSI1.

    pci_alloc_irq_vectors(pci_dev, 1, 1, PCI_IRQ_MSI);
    pci_request_irq(pci_dev, 0, &msi_handler, NULL, dev, "msi%i", 0);

    From my point of view the code above should handle MSI0 only because we allocate one vector.

    But msi_handler get called when I write 1 to MSI_IRQ register. And writing 0 does not trigger interrupt handler.

    Best Regards,
    Yurii

  • Hi Yurii,

    This is the Linux driver code, I am not the right person for this. Please open a new query, thanks!

    Regards, Eric

  • Hi Eric,

    I have some problems understanding endpoint's MSI generation algorithm.

    For example, Message Data register in EP configuration is programmed to 0x04.

    Endpoint writes 0x04 to address 0x21800054. MSI0 is generated by hardware and caught by Linux driver code (and I can also simulate it by writing 0x04 to MSI_IRQ reg).

    But I observe that no MSI0 (system event #279) is generated in CIC0. And it is only generated when I write 0x00 to MSI_IRQ register with devmem utility.

    Best Regards,
    Yurii

  • Yurii,

    PCIE RC is K2L running Linux kernel, and PCIE EP is another device you didn't mentioned, correct?

    "Endpoint writes 0x04 to address 0x21800054. "(and I can also simulate it by writing 0x04 to MSI_IRQ reg)." ============>MSI_IRQ is already  0x2180_0054 on PCIE 0, what is the difference between two trials? Also, your EP writes to the RC's MSI_IRQ (0x2180_0054), not your own EP's address, correct?

    Let's assume the 0x04 landed at the RC side's MSI_IRQ, which MSIx_IRQ_STATUS_RAW (where x=0,1 .... 7) get set and what bit? You can see the PCIE user guide for the offset of those registers.

    There are some discussions on MSI generation,see https://e2e.ti.com/support/processors/f/791/t/335664. Note the device is different from K2L and so the CIC interrupt number. The PCIE module is the same, so the way to generate MSI, how to do translation and check MSIx_IRQ_STATUS_RAW are the same.

    Regards, Eric 

  • Eric,

    We have K2L as RC and Xilinx FPGA as endpoint (using 7 Series Integrated Block for PCI Express v3.0).

    lding said:
    MSI_IRQ is already 0x2180_0054 on PCIE 0, what is the difference between two trials?


    There is no difference, it was my lack of understanding.

    lding said:
    Let's assume the 0x04 landed at the RC side's MSI_IRQ, which MSIx_IRQ_STATUS_RAW (where x=0,1 .... 7) get set and what bit?


    I've disabled all MSI interrupts with MSIx_IRQ_ENABLE_CLR registers and devmem. Looking at MSIx_IRQ_STATUS_RAW it seems that MSI4_IRQ_STATUS_RAW[0] bit is set and MSI4 generated, as per PCIe datasheet. There is some problem in MSI Data register setup for EP. Linux kernel writes 0x04 (i.e. number of vectors allocated) instead of 0x00.

    I think that this issue is resolved, thank you. Now I'll look for some way to customize MSI Data register setup.

    Best Regards,
    Yurii

  • I've figured out why Linux setup MSI interrupts in this way.

    The problem is that MSI0 is always allocated during PCIe port initialization as port service interrupt (power management, hotplug or Advanced Error Reporting events). Hotplug is not supported by Keystone PCIe, so MSI0 interrupt is allocated for power management and AER. Every next interrupt allocation actually starts with MSI1.

    AER can be disabled in Linux kernel config, but PM cannot be disabled (switching off CONFIG_PCIE_PME does nothing in this case). This capability is read from PCIe port hardware registers and power management service interrupts are enabled by Linux. To prevent kernel from allocating service interrupts completely we set pcie_ports=compat as kernel command line option in u-boot. After this requesting 0 interrupt with pci_request_interrupt correctly allocates MSI0.

    Best Regards,
    Yurii