77 * Author: Daire McNamara <daire.mcnamara@microchip.com>
88 */
99
10+ #include <linux/bitfield.h>
1011#include <linux/clk.h>
1112#include <linux/irqchip/chained_irq.h>
1213#include <linux/irqdomain.h>
2021#include "../pci.h"
2122
2223/* Number of MSI IRQs */
23- #define MC_NUM_MSI_IRQS 32
24- #define MC_NUM_MSI_IRQS_CODED 5
24+ #define MC_MAX_NUM_MSI_IRQS 32
2525
2626/* PCIe Bridge Phy and Controller Phy offsets */
2727#define MC_PCIE1_BRIDGE_ADDR 0x00008000u
3131#define MC_PCIE_CTRL_ADDR (MC_PCIE1_CTRL_ADDR)
3232
3333/* PCIe Bridge Phy Regs */
34+ #define PCIE_PCI_IRQ_DW0 0xa8
35+ #define MSIX_CAP_MASK BIT(31)
36+ #define NUM_MSI_MSGS_MASK GENMASK(6, 4)
37+ #define NUM_MSI_MSGS_SHIFT 4
38+
3439#define IMASK_LOCAL 0x180
3540#define DMA_END_ENGINE_0_MASK 0x00000000u
3641#define DMA_END_ENGINE_0_SHIFT 0
7984#define IMASK_HOST 0x188
8085#define ISTATUS_HOST 0x18c
8186#define IMSI_ADDR 0x190
82- #define MSI_ADDR 0x190
8387#define ISTATUS_MSI 0x194
8488
8589/* PCIe Master table init defines */
158162
159163/* PCIe Config space MSI capability structure */
160164#define MC_MSI_CAP_CTRL_OFFSET 0xe0u
161- #define MC_MSI_MAX_Q_AVAIL (MC_NUM_MSI_IRQS_CODED << 1)
162- #define MC_MSI_Q_SIZE (MC_NUM_MSI_IRQS_CODED << 4)
163165
164166/* Events */
165167#define EVENT_PCIE_L2_EXIT 0
@@ -259,7 +261,7 @@ struct mc_msi {
259261 struct irq_domain * dev_domain ;
260262 u32 num_vectors ;
261263 u64 vector_phy ;
262- DECLARE_BITMAP (used , MC_NUM_MSI_IRQS );
264+ DECLARE_BITMAP (used , MC_MAX_NUM_MSI_IRQS );
263265};
264266
265267struct mc_pcie {
@@ -382,25 +384,27 @@ static struct {
382384
383385static char poss_clks [][5 ] = { "fic0" , "fic1" , "fic2" , "fic3" };
384386
385- static void mc_pcie_enable_msi (struct mc_pcie * port , void __iomem * base )
387+ static void mc_pcie_enable_msi (struct mc_pcie * port , void __iomem * ecam )
386388{
387389 struct mc_msi * msi = & port -> msi ;
388- u32 cap_offset = MC_MSI_CAP_CTRL_OFFSET ;
389- u16 msg_ctrl = readw_relaxed ( base + cap_offset + PCI_MSI_FLAGS ) ;
390+ u16 reg ;
391+ u8 queue_size ;
390392
391- msg_ctrl |= PCI_MSI_FLAGS_ENABLE ;
392- msg_ctrl &= ~PCI_MSI_FLAGS_QMASK ;
393- msg_ctrl |= MC_MSI_MAX_Q_AVAIL ;
394- msg_ctrl &= ~PCI_MSI_FLAGS_QSIZE ;
395- msg_ctrl |= MC_MSI_Q_SIZE ;
396- msg_ctrl |= PCI_MSI_FLAGS_64BIT ;
393+ /* Fixup MSI enable flag */
394+ reg = readw_relaxed (ecam + MC_MSI_CAP_CTRL_OFFSET + PCI_MSI_FLAGS );
395+ reg |= PCI_MSI_FLAGS_ENABLE ;
396+ writew_relaxed (reg , ecam + MC_MSI_CAP_CTRL_OFFSET + PCI_MSI_FLAGS );
397397
398- writew_relaxed (msg_ctrl , base + cap_offset + PCI_MSI_FLAGS );
398+ /* Fixup PCI MSI queue flags */
399+ queue_size = FIELD_GET (PCI_MSI_FLAGS_QMASK , reg );
400+ reg |= FIELD_PREP (PCI_MSI_FLAGS_QSIZE , queue_size );
401+ writew_relaxed (reg , ecam + MC_MSI_CAP_CTRL_OFFSET + PCI_MSI_FLAGS );
399402
403+ /* Fixup MSI addr fields */
400404 writel_relaxed (lower_32_bits (msi -> vector_phy ),
401- base + cap_offset + PCI_MSI_ADDRESS_LO );
405+ ecam + MC_MSI_CAP_CTRL_OFFSET + PCI_MSI_ADDRESS_LO );
402406 writel_relaxed (upper_32_bits (msi -> vector_phy ),
403- base + cap_offset + PCI_MSI_ADDRESS_HI );
407+ ecam + MC_MSI_CAP_CTRL_OFFSET + PCI_MSI_ADDRESS_HI );
404408}
405409
406410static void mc_handle_msi (struct irq_desc * desc )
@@ -473,10 +477,7 @@ static int mc_irq_msi_domain_alloc(struct irq_domain *domain, unsigned int virq,
473477{
474478 struct mc_pcie * port = domain -> host_data ;
475479 struct mc_msi * msi = & port -> msi ;
476- void __iomem * bridge_base_addr =
477- port -> axi_base_addr + MC_PCIE_BRIDGE_ADDR ;
478480 unsigned long bit ;
479- u32 val ;
480481
481482 mutex_lock (& msi -> lock );
482483 bit = find_first_zero_bit (msi -> used , msi -> num_vectors );
@@ -490,11 +491,6 @@ static int mc_irq_msi_domain_alloc(struct irq_domain *domain, unsigned int virq,
490491 irq_domain_set_info (domain , virq , bit , & mc_msi_bottom_irq_chip ,
491492 domain -> host_data , handle_edge_irq , NULL , NULL );
492493
493- /* Enable MSI interrupts */
494- val = readl_relaxed (bridge_base_addr + IMASK_LOCAL );
495- val |= PM_MSI_INT_MSI_MASK ;
496- writel_relaxed (val , bridge_base_addr + IMASK_LOCAL );
497-
498494 mutex_unlock (& msi -> lock );
499495
500496 return 0 ;
@@ -1111,6 +1107,7 @@ static int mc_platform_init(struct pci_config_window *cfg)
11111107 struct mc_pcie * port ;
11121108 void __iomem * bridge_base_addr ;
11131109 int ret ;
1110+ u32 val ;
11141111
11151112 port = devm_kzalloc (dev , sizeof (* port ), GFP_KERNEL );
11161113 if (!port )
@@ -1131,12 +1128,24 @@ static int mc_platform_init(struct pci_config_window *cfg)
11311128
11321129 bridge_base_addr = port -> axi_base_addr + MC_PCIE_BRIDGE_ADDR ;
11331130
1134- port -> msi .vector_phy = MSI_ADDR ;
1135- port -> msi .num_vectors = MC_NUM_MSI_IRQS ;
1131+ /* Allow enabling MSI by disabling MSI-X */
1132+ val = readl (bridge_base_addr + PCIE_PCI_IRQ_DW0 );
1133+ val &= ~MSIX_CAP_MASK ;
1134+ writel (val , bridge_base_addr + PCIE_PCI_IRQ_DW0 );
11361135
11371136 /* Hardware doesn't setup MSI by default */
11381137 mc_pcie_enable_msi (port , cfg -> win );
11391138
1139+ /* Pick num vectors from bitfile programmed onto FPGA fabric */
1140+ val = readl (bridge_base_addr + PCIE_PCI_IRQ_DW0 );
1141+ val &= NUM_MSI_MSGS_MASK ;
1142+ val >>= NUM_MSI_MSGS_SHIFT ;
1143+
1144+ port -> msi .num_vectors = 1 << val ;
1145+
1146+ /* Pick vector address from design */
1147+ port -> msi .vector_phy = readl_relaxed (bridge_base_addr + IMSI_ADDR );
1148+
11401149 /* Configure Address Translation Table 0 for PCIe config space */
11411150 mc_pcie_setup_window (bridge_base_addr , 0 , cfg -> res .start & 0xffffffff ,
11421151 cfg -> res .start , resource_size (& cfg -> res ));
0 commit comments