Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 26 Feb 2015 02:22:48 +0000 (UTC)
From:      "Jayachandran C." <jchandra@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r279306 - in head/sys: boot/fdt/dts/mips mips/nlm
Message-ID:  <201502260222.t1Q2MmS2083006@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jchandra
Date: Thu Feb 26 02:22:47 2015
New Revision: 279306
URL: https://svnweb.freebsd.org/changeset/base/279306

Log:
  Remove run-time allocation of XLP IRQs
  
  Follow the same static IRQ to Interrupt Table Entry mapping as the other
  OS supported on XLP.

Modified:
  head/sys/boot/fdt/dts/mips/xlp-basic.dts
  head/sys/mips/nlm/interrupt.h
  head/sys/mips/nlm/intr_machdep.c
  head/sys/mips/nlm/xlp.h
  head/sys/mips/nlm/xlp_pci.c

Modified: head/sys/boot/fdt/dts/mips/xlp-basic.dts
==============================================================================
--- head/sys/boot/fdt/dts/mips/xlp-basic.dts	Thu Feb 26 02:05:45 2015	(r279305)
+++ head/sys/boot/fdt/dts/mips/xlp-basic.dts	Thu Feb 26 02:22:47 2015	(r279306)
@@ -62,7 +62,7 @@
 			current-speed = <115200>;
 			clock-frequency = <133000000>;
 			interrupt-parent = <&pic>;
-			interrupts = <9>;
+			interrupts = <17>;
 		};
 
 	};

Modified: head/sys/mips/nlm/interrupt.h
==============================================================================
--- head/sys/mips/nlm/interrupt.h	Thu Feb 26 02:05:45 2015	(r279305)
+++ head/sys/mips/nlm/interrupt.h	Thu Feb 26 02:22:47 2015	(r279306)
@@ -43,13 +43,26 @@
 #define	XLP_IRQ_IS_PICINTR(irq)	((irq) >= PIC_IRQ_BASE && \
 				    (irq) <= PIC_IRT_LAST_IRQ)
 
-#define	PIC_UART_0_IRQ		9
-#define	PIC_PCIE_0_IRQ		11
-#define	PIC_PCIE_1_IRQ		12
-#define	PIC_PCIE_2_IRQ		13
-#define	PIC_PCIE_3_IRQ		14
-#define	PIC_EHCI_0_IRQ		16
-#define	PIC_MMC_IRQ		21
+#define	PIC_UART_0_IRQ		17
+#define	PIC_UART_1_IRQ		18
+
+#define	PIC_PCIE_0_IRQ		19
+#define	PIC_PCIE_1_IRQ		20
+#define	PIC_PCIE_2_IRQ		21
+#define	PIC_PCIE_3_IRQ		22
+#define	PIC_PCIE_IRQ(l)		(PIC_PCIE_0_IRQ + (l))
+
+#define	PIC_USB_0_IRQ		23
+#define	PIC_USB_1_IRQ		24
+#define	PIC_USB_2_IRQ		25
+#define	PIC_USB_3_IRQ		26
+#define	PIC_USB_4_IRQ		27
+#define	PIC_USB_IRQ(n)		(PIC_USB_0_IRQ + (n))
+
+#define	PIC_MMC_IRQ		29
+#define	PIC_I2C_0_IRQ		30
+#define	PIC_I2C_1_IRQ		31
+#define	PIC_I2C_IRQ(n)		(PIC_I2C_0_IRQ + (n))
 
 /*
  * XLR needs custom pre and post handlers for PCI/PCI-e interrupts

Modified: head/sys/mips/nlm/intr_machdep.c
==============================================================================
--- head/sys/mips/nlm/intr_machdep.c	Thu Feb 26 02:05:45 2015	(r279305)
+++ head/sys/mips/nlm/intr_machdep.c	Thu Feb 26 02:22:47 2015	(r279306)
@@ -61,12 +61,46 @@ struct xlp_intrsrc {
 	void (*busack)(int);		/* Additional ack */
 	struct intr_event *ie;		/* event corresponding to intr */
 	int irq;
+	int irt;
 };
 	
 static struct xlp_intrsrc xlp_interrupts[XLR_MAX_INTR];
 static mips_intrcnt_t mips_intr_counters[XLR_MAX_INTR];
 static int intrcnt_index;
 
+int
+xlp_irq_to_irt(int irq)
+{
+	uint32_t offset;
+
+	switch (irq) {
+	case PIC_UART_0_IRQ:
+	case PIC_UART_1_IRQ:
+		offset =  XLP_IO_UART_OFFSET(0, irq - PIC_UART_0_IRQ);
+		return (xlp_socdev_irt(offset));
+	case PIC_PCIE_0_IRQ:
+	case PIC_PCIE_1_IRQ:
+	case PIC_PCIE_2_IRQ:
+	case PIC_PCIE_3_IRQ:
+		offset = XLP_IO_PCIE_OFFSET(0, irq - PIC_PCIE_0_IRQ);
+		return (xlp_socdev_irt(offset));
+	case PIC_USB_0_IRQ:
+	case PIC_USB_1_IRQ:
+	case PIC_USB_2_IRQ:
+	case PIC_USB_3_IRQ:
+	case PIC_USB_4_IRQ:
+		offset = XLP_IO_USB_OFFSET(0, irq - PIC_USB_0_IRQ);
+		return (xlp_socdev_irt(offset));
+	case PIC_I2C_0_IRQ:
+	case PIC_I2C_1_IRQ:
+		offset = XLP_IO_I2C0_OFFSET(0);
+		return (xlp_socdev_irt(offset) + irq - PIC_I2C_0_IRQ);
+	default:
+		printf("ERROR: %s: unknown irq %d\n", __func__, irq);
+		return (-1);
+	}
+}
+
 void
 xlp_enable_irq(int irq)
 {
@@ -102,7 +136,7 @@ xlp_post_filter(void *source)
 	
 	if (src->busack)
 		src->busack(src->irq);
-	nlm_pic_ack(xlp_pic_base, xlp_irq_to_irt(src->irq));
+	nlm_pic_ack(xlp_pic_base, src->irt);
 }
 
 static void
@@ -119,7 +153,7 @@ xlp_post_ithread(void *source)
 {
 	struct xlp_intrsrc *src = source;
 
-	nlm_pic_ack(xlp_pic_base, xlp_irq_to_irt(src->irq));
+	nlm_pic_ack(xlp_pic_base, src->irt);
 }
 
 void
@@ -163,6 +197,13 @@ xlp_establish_intr(const char *name, dri
 		src->busack = busack;
 		src->ie = ie;
 	}
+	if (XLP_IRQ_IS_PICINTR(irq)) {
+		/* Set all irqs to CPU 0 for now */
+		src->irt = xlp_irq_to_irt(irq);
+		nlm_pic_write_irt_direct(xlp_pic_base, src->irt, 1, 0,
+		    PIC_LOCAL_SCHEDULING, irq, 0);
+	}
+
 	intr_event_add_handler(ie, name, filt, handler, arg,
 	    intr_priority(flags), flags, cookiep);
 	xlp_enable_irq(irq);

Modified: head/sys/mips/nlm/xlp.h
==============================================================================
--- head/sys/mips/nlm/xlp.h	Thu Feb 26 02:05:45 2015	(r279305)
+++ head/sys/mips/nlm/xlp.h	Thu Feb 26 02:22:47 2015	(r279306)
@@ -62,7 +62,6 @@ extern void xlp_enable_threads(int code)
 #endif
 uint32_t xlp_get_cpu_frequency(int node, int core);
 int nlm_set_device_frequency(int node, int devtype, int frequency);
-int xlp_irt_to_irq(int irt);
 int xlp_irq_to_irt(int irq);
 
 static __inline int nlm_processor_id(void)
@@ -127,5 +126,12 @@ static __inline int nlm_is_xlp8xx_b0(voi
 		rev == XLP_REVISION_B0);
 }
 
+static __inline int xlp_socdev_irt(uint32_t offset)
+{
+	uint64_t base;
+
+	base = nlm_pcicfg_base(offset);
+	return (nlm_irtstart(base));
+}
 #endif /* LOCORE */
 #endif /* __NLM_XLP_H__ */

Modified: head/sys/mips/nlm/xlp_pci.c
==============================================================================
--- head/sys/mips/nlm/xlp_pci.c	Thu Feb 26 02:05:45 2015	(r279305)
+++ head/sys/mips/nlm/xlp_pci.c	Thu Feb 26 02:22:47 2015	(r279306)
@@ -74,31 +74,6 @@ __FBSDID("$FreeBSD$");
 #define	EMUL_MEM_START	0x16000000UL
 #define	EMUL_MEM_END	0x18ffffffUL
 
-/* SoC device qurik handling */
-static int irt_irq_map[4 * 256];
-static int irq_irt_map[64];
-
-static void
-xlp_add_irq(int node, int irt, int irq)
-{
-	int nodeirt = node * 256 + irt;
-
-	irt_irq_map[nodeirt] = irq;
-	irq_irt_map[irq] = nodeirt;
-}
-
-int
-xlp_irq_to_irt(int irq)
-{
-	return irq_irt_map[irq];
-}
-
-int
-xlp_irt_to_irq(int nodeirt)
-{
-	return irt_irq_map[nodeirt];
-}
-
 /* Override PCI a bit for SoC devices */
 
 enum {
@@ -108,24 +83,6 @@ enum {
 	DEV_MMIO32	= 0x8,	/* byte access not allowed to mmio */
 };
 
-struct soc_dev_desc {
-	u_int	devid;		/* device ID */
-	int	irqbase;	/* start IRQ */
-	u_int	flags;		/* flags */
-	int	ndevs;		/* to keep track of number of devices */
-};
-
-struct soc_dev_desc xlp_dev_desc[] = {
-	{ PCI_DEVICE_ID_NLM_ICI,               0, INTERNAL_DEV },
-	{ PCI_DEVICE_ID_NLM_PIC,               0, INTERNAL_DEV },
-	{ PCI_DEVICE_ID_NLM_FMN,               0, INTERNAL_DEV },
-	{ PCI_DEVICE_ID_NLM_UART, PIC_UART_0_IRQ, MEM_RES_EMUL | DEV_MMIO32},
-	{ PCI_DEVICE_ID_NLM_I2C,               0, MEM_RES_EMUL | DEV_MMIO32 },
-	{ PCI_DEVICE_ID_NLM_NOR,               0, MEM_RES_EMUL },
-	{ PCI_DEVICE_ID_NLM_MMC,     PIC_MMC_IRQ, MEM_RES_EMUL },
-	{ PCI_DEVICE_ID_NLM_EHCI, PIC_EHCI_0_IRQ, 0 }
-};
-
 struct  xlp_devinfo {
 	struct pci_devinfo pcidev;
 	int	irq;
@@ -133,19 +90,6 @@ struct  xlp_devinfo {
 	u_long	mem_res_start;
 };
 
-static __inline struct soc_dev_desc *
-xlp_find_soc_desc(int devid)
-{
-	struct soc_dev_desc *p;
-	int i, n;
-
-	n = sizeof(xlp_dev_desc) / sizeof(xlp_dev_desc[0]);
-	for (i = 0, p = xlp_dev_desc; i < n; i++, p++)
-		if (p->devid == devid)
-			return (p);
-	return (NULL);
-}
-
 static struct resource *
 xlp_pci_alloc_resource(device_t bus, device_t child, int type, int *rid,
     u_long start, u_long end, u_long count, u_int flags)
@@ -219,9 +163,7 @@ xlp_add_soc_child(device_t pcib, device_
 {
 	struct pci_devinfo *dinfo;
 	struct xlp_devinfo *xlp_dinfo;
-	struct soc_dev_desc *si;
-	uint64_t pcibase;
-	int domain, node, irt, irq, flags, devoffset, num;
+	int domain, node, irq, devoffset, flags;
 	uint16_t devid;
 
 	domain = pcib_get_domain(dev);
@@ -232,36 +174,35 @@ xlp_add_soc_child(device_t pcib, device_
 
 	/* Find if there is a desc for the SoC device */
 	devid = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_DEVICE, 2);
-	si = xlp_find_soc_desc(devid);
-
-	/* update flags and irq from desc if available */
-	irq = 0;
 	flags = 0;
-	if (si != NULL) {
-		if (si->irqbase != 0)
-			irq = si->irqbase + si->ndevs;
-		flags = si->flags;
-		si->ndevs++;
-	}
-
-	/* skip internal devices */
-	if ((flags & INTERNAL_DEV) != 0)
+	irq = 0;
+	switch (devid) {
+	case PCI_DEVICE_ID_NLM_UART:
+		irq = PIC_UART_0_IRQ + f;
+		flags = MEM_RES_EMUL | DEV_MMIO32;
+		break;
+	case PCI_DEVICE_ID_NLM_I2C:
+		flags = MEM_RES_EMUL | DEV_MMIO32;
+		break;
+	case PCI_DEVICE_ID_NLM_NOR:
+		flags = MEM_RES_EMUL;
+		break;
+	case PCI_DEVICE_ID_NLM_MMC:
+		irq = PIC_MMC_IRQ;
+		flags = MEM_RES_EMUL;
+		break;
+	case PCI_DEVICE_ID_NLM_EHCI:
+		irq = PIC_USB_0_IRQ + f;
+		break;
+	case PCI_DEVICE_ID_NLM_PCIE:
+		break;
+	case PCI_DEVICE_ID_NLM_ICI:
+	case PCI_DEVICE_ID_NLM_PIC:
+	case PCI_DEVICE_ID_NLM_FMN:
+	default:
 		return;
-
-	/* PCIe interfaces are special, bug in Ax */
-	if (devid == PCI_DEVICE_ID_NLM_PCIE) {
-		xlp_add_irq(node, xlp_pcie_link_irt(f), PIC_PCIE_0_IRQ + f);
-	} else {
-		/* Stash intline and pin in shadow reg for devices */
-		pcibase = nlm_pcicfg_base(devoffset);
-		irt = nlm_irtstart(pcibase);
-		num = nlm_irtnum(pcibase);
-		if (irq != 0 && num > 0) {
-			xlp_add_irq(node, irt, irq);
-			nlm_write_reg(pcibase, XLP_PCI_DEVSCRATCH_REG0,
-			    (1 << 8) | irq);
-		}
 	}
+
 	dinfo = pci_read_device(pcib, domain, b, s, f, sizeof(*xlp_dinfo));
 	if (dinfo == NULL)
 		return;
@@ -269,6 +210,11 @@ xlp_add_soc_child(device_t pcib, device_
 	xlp_dinfo->irq = irq;
 	xlp_dinfo->flags = flags;
 
+	/* SoC device with interrupts need fixup (except PCIe controllers) */
+	if (irq != 0 && devid != PCI_DEVICE_ID_NLM_PCIE)
+		PCIB_WRITE_CONFIG(pcib, b, s, f, XLP_PCI_DEVSCRATCH_REG0 << 2,
+		    (1 << 8) | irq, 4);
+
 	/* memory resource from ecfg space, if MEM_RES_EMUL is set */
 	if ((flags & MEM_RES_EMUL) != 0)
 		xlp_dinfo->mem_res_start = XLP_DEFAULT_IO_BASE + devoffset +
@@ -601,21 +547,17 @@ static int
 xlp_map_msi(device_t pcib, device_t dev, int irq, uint64_t *addr,
     uint32_t *data)
 {
-	int msi, irt;
+	int link;
 
-	if (irq >= 64) {
-		msi = irq - 64;
-		*addr = MIPS_MSI_ADDR(0);
-
-		irt = xlp_pcie_link_irt(msi/32);
-		if (irt != -1)
-			*data = MIPS_MSI_DATA(xlp_irt_to_irq(irt));
-		return (0);
-	} else {
+	if (irq < 64) {
 		device_printf(dev, "%s: map_msi for irq %d  - ignored", 
 		    device_get_nameunit(pcib), irq);
 		return (ENXIO);
 	}
+	link = (irq - 64) / 32;
+	*addr = MIPS_MSI_ADDR(0);
+	*data = MIPS_MSI_DATA(PIC_PCIE_IRQ(link));
+	return (0);
 }
 
 static void
@@ -711,18 +653,13 @@ mips_platform_pcib_setup_intr(device_t d
 		nlm_write_pci_reg(base, PCIE_BRIDGE_MSI_CAP, 
 		    (val | (PCIM_MSICTRL_MSI_ENABLE << 16) |
 		        (PCIM_MSICTRL_MMC_32 << 16)));
+		xlpirq = PIC_PCIE_IRQ(link);
+	}
 
-		xlpirq = xlp_pcie_link_irt(xlpirq / 32);
-		if (xlpirq == -1)
-			return (EINVAL);
-		xlpirq = xlp_irt_to_irq(xlpirq);
-	}
-	/* Set all irqs to CPU 0 for now */
-	nlm_pic_write_irt_direct(xlp_pic_base, xlp_irq_to_irt(xlpirq), 1, 0,
-	    PIC_LOCAL_SCHEDULING, xlpirq, 0);
-	extra_ack = NULL;
 	if (xlpirq >= PIC_PCIE_0_IRQ && xlpirq <= PIC_PCIE_3_IRQ)
 		extra_ack = bridge_pcie_ack;
+	else
+		extra_ack = NULL;
 	xlp_establish_intr(device_get_name(child), filt,
 	    intr, arg, xlpirq, flags, cookiep, extra_ack);
 
@@ -816,7 +753,7 @@ xlp_pcib_deactivate_resource(device_t bu
 static int
 mips_pcib_route_interrupt(device_t bus, device_t dev, int pin)
 {
-	int irt, link;
+	int f, d;
 
 	/*
 	 * Validate requested pin number.
@@ -826,38 +763,21 @@ mips_pcib_route_interrupt(device_t bus, 
 
 	if (pci_get_bus(dev) == 0 &&
 	    pci_get_vendor(dev) == PCI_VENDOR_NETLOGIC) {
-		/* SoC devices */
-		uint64_t pcibase;
-		int f, n, d, num;
-
 		f = pci_get_function(dev);
-		n = pci_get_slot(dev) / 8;
 		d = pci_get_slot(dev) % 8;
 
 		/*
 		 * For PCIe links, return link IRT, for other SoC devices
 		 * get the IRT from its PCIe header
 		 */
-		if (d == 1) {
-			irt = xlp_pcie_link_irt(f);
-		} else {
-			pcibase = nlm_pcicfg_base(XLP_HDR_OFFSET(n, 0, d, f));
-			irt = nlm_irtstart(pcibase);
-			num = nlm_irtnum(pcibase);
-			if (num != 1)
-				device_printf(bus, "[%d:%d:%d] Error %d IRQs\n",
-				    n, d, f, num);
-		}
+		if (d == 1)
+			return (PIC_PCIE_IRQ(f));
+		else
+			return (255);	/* use intline, don't reroute */
 	} else {
 		/* Regular PCI devices */
-		link = xlp_pcie_link(bus, dev);
-		irt = xlp_pcie_link_irt(link);
+		return (PIC_PCIE_IRQ(xlp_pcie_link(bus, dev)));
 	}
-
-	if (irt != -1)
-		return (xlp_irt_to_irq(irt));
-
-	return (255);
 }
 
 static device_method_t xlp_pcib_methods[] = {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201502260222.t1Q2MmS2083006>