Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c24a8a7a authored by Jayachandran C's avatar Jayachandran C Committed by Ralf Baechle
Browse files

MIPS: Netlogic: Add MSI support for XLP



Add MSI chip and MSIX chip definitions.

For MSI, we map the link interrupt to a MSI link IRQ which will
do a second level of dispatch based on the MSI status register.

The MSI chip definitions use the MSI enable register to enable
and disable the MSI irqs.

For MSI-X, we split the 32 available MSI-X vectors across the
four PCIe links (8 each). These PIC interrupts generate an IRQ
per link which uses a second level dispatch as well.

The MSI-X chip definition uses the standard functions to enable
and disable interrupts.

Signed-off-by: default avatarJayachandran C <jchandra@broadcom.com>
Signed-off-by: default avatarJohn Crispin <blogic@openwrt.org>
Patchwork: http://patchwork.linux-mips.org/patch/6270/
parent 27547abf
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -775,6 +775,7 @@ config NLM_XLP_BOARD
	select CEVT_R4K
	select CSRC_R4K
	select IRQ_CPU
	select ARCH_SUPPORTS_MSI
	select ZONE_DMA32 if 64BIT
	select SYNC_R4K
	select SYS_HAS_EARLY_PRINTK
+2 −1
Original line number Diff line number Diff line
@@ -9,7 +9,8 @@
#define __ASM_NETLOGIC_IRQ_H

#include <asm/mach-netlogic/multi-node.h>
#define NR_IRQS			(64 * NLM_NR_NODES)
#define NLM_IRQS_PER_NODE	1024
#define NR_IRQS			(NLM_IRQS_PER_NODE * NLM_NR_NODES)

#define MIPS_CPU_IRQ_BASE	0

+6 −0
Original line number Diff line number Diff line
@@ -112,8 +112,14 @@ struct nlm_soc_info {

struct irq_data;
uint64_t nlm_pci_irqmask(int node);
void nlm_setup_pic_irq(int node, int picirq, int irq, int irt);
void nlm_set_pic_extra_ack(int node, int irq,  void (*xack)(struct irq_data *));

#ifdef CONFIG_PCI_MSI
void nlm_dispatch_msi(int node, int lirq);
void nlm_dispatch_msix(int node, int msixirq);
#endif

/*
 * The NR_IRQs is divided between nodes, each of them has a separate irq space
 */
+25 −8
Original line number Diff line number Diff line
@@ -52,25 +52,42 @@
#define PCIE_BYTE_SWAP_MEM_LIM		0x248
#define PCIE_BYTE_SWAP_IO_BASE		0x249
#define PCIE_BYTE_SWAP_IO_LIM		0x24A

#define PCIE_BRIDGE_MSIX_ADDR_BASE	0x24F
#define PCIE_BRIDGE_MSIX_ADDR_LIMIT	0x250
#define PCIE_MSI_STATUS			0x25A
#define PCIE_MSI_EN			0x25B
#define PCIE_MSIX_STATUS		0x25D
#define PCIE_INT_STATUS0		0x25F
#define PCIE_INT_STATUS1		0x260
#define PCIE_INT_EN0			0x261
#define PCIE_INT_EN1			0x262

/* PCIE_MSI_EN */
#define PCIE_MSI_VECTOR_INT_EN		0xFFFFFFFF

/* PCIE_INT_EN0 */
#define PCIE_MSI_INT_EN			(1 << 9)
/* other */
#define PCIE_NLINKS			4

/* MSI addresses */
#define MSI_ADDR_BASE			0xfffee00000ULL
#define MSI_ADDR_SZ			0x10000
#define MSI_LINK_ADDR(n, l)		(MSI_ADDR_BASE + \
				(PCIE_NLINKS * (n) + (l)) * MSI_ADDR_SZ)
#define MSIX_ADDR_BASE			0xfffef00000ULL
#define MSIX_LINK_ADDR(n, l)		(MSIX_ADDR_BASE + \
				(PCIE_NLINKS * (n) + (l)) * MSI_ADDR_SZ)
#ifndef __ASSEMBLY__

#define nlm_read_pcie_reg(b, r)		nlm_read_reg(b, r)
#define nlm_write_pcie_reg(b, r, v)	nlm_write_reg(b, r, v)
#define nlm_get_pcie_base(node, inst)	\
			nlm_pcicfg_base(XLP_IO_PCIE_OFFSET(node, inst))
#define nlm_get_pcie_regbase(node, inst)	\
			(nlm_get_pcie_base(node, inst) + XLP_IO_PCI_HDRSZ)

int xlp_pcie_link_irt(int link);
#ifdef CONFIG_PCI_MSI
void xlp_init_node_msi_irqs(int node, int link);
#else
static inline void xlp_init_node_msi_irqs(int node, int link) {}
#endif

struct pci_dev *xlp_get_pcie_link(const struct pci_dev *dev);

#endif
#endif /* __NLM_HAL_PCIBUS_H__ */
+0 −5
Original line number Diff line number Diff line
@@ -193,14 +193,9 @@
#define PIC_IRT_PCIE_LINK_INDEX(num)	((num) + PIC_IRT_PCIE_LINK_0_INDEX)

#define PIC_CLOCK_TIMER			7
#define PIC_IRQ_BASE			8

#if !defined(LOCORE) && !defined(__ASSEMBLY__)

#define PIC_IRT_FIRST_IRQ		(PIC_IRQ_BASE)
#define PIC_IRT_LAST_IRQ		63
#define PIC_IRQ_IS_IRT(irq)		((irq) >= PIC_IRT_FIRST_IRQ)

/*
 *   Misc
 */
Loading