patch-2.4.21 linux-2.4.21/arch/ppc/platforms/prep_pci.c

Next file: linux-2.4.21/arch/ppc/platforms/prep_setup.c
Previous file: linux-2.4.21/arch/ppc/platforms/pmac_time.c
Back to the patch index
Back to the overall index

diff -urN linux-2.4.20/arch/ppc/platforms/prep_pci.c linux-2.4.21/arch/ppc/platforms/prep_pci.c
@@ -1,7 +1,4 @@
 /*
- * BK Id: SCCS/s.prep_pci.c 1.33 12/20/01 15:36:12 trini
- */
-/*
  * PReP pci functions.
  * Originally by Gary Thomas
  * rewritten and updated by Cort Dougan (cort@cs.nmt.edu)
@@ -29,6 +26,8 @@
 
 #define MAX_DEVNR 22
 
+extern void (*setup_ibm_pci)(char *irq_lo, char *irq_hi);
+
 /* Which PCI interrupt line does a given device [slot] use? */
 /* Note: This really should be two dimensional based in slot/pin used */
 static unsigned char *Motherboard_map;
@@ -665,22 +664,22 @@
 #define	MPIC_HAWK_ID		0x48030000
 #define	MOT_PROC2_BIT		0x800
 
-static u_char mvme2600_openpic_initsenses[] __initdata = {
-    1,	/* MVME2600_INT_SIO */
-    0,	/* MVME2600_INT_FALCN_ECC_ERR */
-    1,	/* MVME2600_INT_PCI_ETHERNET */
-    1,	/* MVME2600_INT_PCI_SCSI */
-    1,	/* MVME2600_INT_PCI_GRAPHICS */
-    1,	/* MVME2600_INT_PCI_VME0 */
-    1,	/* MVME2600_INT_PCI_VME1 */
-    1,	/* MVME2600_INT_PCI_VME2 */
-    1,	/* MVME2600_INT_PCI_VME3 */
-    1,	/* MVME2600_INT_PCI_INTA */
-    1,	/* MVME2600_INT_PCI_INTB */
-    1,	/* MVME2600_INT_PCI_INTC */
-    1,	/* MVME2600_INT_PCI_INTD */
-    1,	/* MVME2600_INT_LM_SIG0 */
-    1,	/* MVME2600_INT_LM_SIG1 */
+static u_char prep_openpic_initsenses[] __initdata = {
+    (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* MVME2600_INT_SIO */
+    (IRQ_SENSE_EDGE  | IRQ_POLARITY_NEGATIVE), /* MVME2600_INT_FALCN_ECC_ERR */
+    (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* MVME2600_INT_PCI_ETHERNET */
+    (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* MVME2600_INT_PCI_SCSI */
+    (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* MVME2600_INT_PCI_GRAPHICS */
+    (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* MVME2600_INT_PCI_VME0 */
+    (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* MVME2600_INT_PCI_VME1 */
+    (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* MVME2600_INT_PCI_VME2 */
+    (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* MVME2600_INT_PCI_VME3 */
+    (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* MVME2600_INT_PCI_INTA */
+    (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* MVME2600_INT_PCI_INTB */
+    (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* MVME2600_INT_PCI_INTC */
+    (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* MVME2600_INT_PCI_INTD */
+    (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* MVME2600_INT_LM_SIG0 */
+    (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* MVME2600_INT_LM_SIG1 */
 };
 
 #define MOT_RAVEN_PRESENT	0x1
@@ -737,8 +736,8 @@
 	/* Map the Raven MPIC registers to virtual memory. */
 	OpenPIC_Addr = ioremap(pci_membase+0xC0000000, 0x22000);
 
-	OpenPIC_InitSenses = mvme2600_openpic_initsenses;
-	OpenPIC_NumInitSenses = sizeof(mvme2600_openpic_initsenses);
+	OpenPIC_InitSenses = prep_openpic_initsenses;
+	OpenPIC_NumInitSenses = sizeof(prep_openpic_initsenses);
 
 	ppc_md.get_irq = openpic_get_irq;
 	
@@ -806,29 +805,51 @@
 void __init
 ibm_prep_init(void)
 {
-	u32 addr;
 #ifdef CONFIG_PREP_RESIDUAL
+	u32 addr, real_addr, len;
 	PPC_DEVICE *mpic;
-#endif
-
-	if (inb(0x0852) == 0xd5) {
-		/* This is for the 43p-140 */
-		early_read_config_dword(0, 0, PCI_DEVFN(13, 0),
-					PCI_BASE_ADDRESS_0, &addr);
-		if (addr != 0xffffffff
-		    && !(addr & PCI_BASE_ADDRESS_SPACE_IO)
-		    && (addr &= PCI_BASE_ADDRESS_MEM_MASK) != 0) {
-			addr += PREP_ISA_MEM_BASE;
-			OpenPIC_Addr = ioremap(addr, 0x40000);
-			ppc_md.get_irq = openpic_get_irq;
-		}
-	}
+	PnP_TAG_PACKET *pkt;
 
-#ifdef CONFIG_PREP_RESIDUAL
+	/* Use the PReP residual data to determine if an OpenPIC is
+	 * present.  If so, get the large vendor packet which will
+	 * tell us the base address and length in memory.
+	 * If we are successful, ioremap the memory area and set
+	 * OpenPIC_Addr (this indicates that the OpenPIC was found).
+	 */
 	mpic = residual_find_device(-1, NULL, SystemPeripheral,
-				    ProgrammableInterruptController, MPIC, 0);
-	if (mpic != NULL)
-		printk("mpic = %p\n", mpic);
+			    ProgrammableInterruptController, MPIC, 0);
+	if (!mpic)
+		return;
+
+	pkt = PnP_find_large_vendor_packet(res->DevicePnPHeap +
+			mpic->AllocatedOffset, 9, 0);
+
+	if (!pkt)
+		return;
+
+#define p pkt->L4_Pack.L4_Data.L4_PPCPack
+	if (!((p.PPCData[0] == 2) && (p.PPCData[1] == 32)))
+		return; /* not a 32-bit memory address */
+
+	real_addr = ld_le32((unsigned int *) (p.PPCData + 4));
+	if (real_addr == 0xffffffff)
+		return;
+
+	/* Adjust address to be as seen by CPU */
+	addr = real_addr + PREP_ISA_MEM_BASE;
+
+	len = ld_le32((unsigned int *) (p.PPCData + 12));
+	if (!len)
+		return;
+#undef p
+	OpenPIC_Addr = ioremap(addr, len);
+	ppc_md.get_irq = openpic_get_irq;
+
+	OpenPIC_InitSenses = prep_openpic_initsenses;
+	OpenPIC_NumInitSenses = sizeof(prep_openpic_initsenses);
+
+	printk(KERN_INFO "MPIC at 0x%08x (0x%08x), length 0x%08x "
+	       "mapped to 0x%p\n", addr, real_addr, len, OpenPIC_Addr);
 #endif
 }
 
@@ -849,6 +870,47 @@
 }
 
 void __init
+prep_sandalfoot_setup_pci(char *irq_edge_mask_lo, char *irq_edge_mask_hi)
+{
+	Motherboard_map_name = "IBM 6015/7020 (Sandalfoot/Sandalbow)";
+	Motherboard_map = ibm6015_pci_IRQ_map;
+	Motherboard_routes = ibm6015_pci_IRQ_routes;
+	*irq_edge_mask_lo = 0x00; /* irq's 0-7 all edge-triggered */
+	*irq_edge_mask_hi = 0xA0; /* irq's 13, 15 level-triggered */
+}
+
+void __init
+prep_thinkpad_setup_pci(char *irq_edge_mask_lo, char *irq_edge_mask_hi)
+{
+	Motherboard_map_name = "IBM Thinkpad 850/860";
+	Motherboard_map = Nobis_pci_IRQ_map;
+	Motherboard_routes = Nobis_pci_IRQ_routes;
+	*irq_edge_mask_lo = 0x00; /* irq's 0-7 all edge-triggered */
+	*irq_edge_mask_hi = 0xA0; /* irq's 13, 15 level-triggered */
+}
+
+void __init
+prep_carolina_setup_pci(char *irq_edge_mask_lo, char *irq_edge_mask_hi)
+{
+	Motherboard_map_name = "IBM 7248, PowerSeries 830/850 (Carolina)";
+	Motherboard_map = ibm8xx_pci_IRQ_map;
+	Motherboard_routes = ibm8xx_pci_IRQ_routes;
+	*irq_edge_mask_lo = 0x00; /* irq's 0-7 all edge-triggered */
+	*irq_edge_mask_hi = 0xA4; /* irq's 10, 13, 15 level-triggered */
+}
+
+void __init
+prep_tiger1_setup_pci(char *irq_edge_mask_lo, char *irq_edge_mask_hi)
+{
+	Motherboard_map_name = "IBM 43P-140 (Tiger1)";
+	Motherboard_map = ibm43p_pci_IRQ_map;
+	Motherboard_routes = ibm43p_pci_IRQ_routes;
+	Motherboard_non0 = ibm43p_pci_map_non0;
+	*irq_edge_mask_lo = 0x00; /* irq's 0-7 all edge-triggered */
+	*irq_edge_mask_hi = 0xA0; /* irq's 13, 15 level-triggered */
+}
+
+void __init
 prep_route_pci_interrupts(void)
 {
 	unsigned char *ibc_pirq = (unsigned char *)0x80800860;
@@ -917,52 +979,12 @@
 			outb( (irq_mode >> 8) & 0xff, 0x4d1 );
 		}
 	} else if ( _prep_type == _PREP_IBM ) {
-		unsigned char planar_id = inb(0x0852);
 		unsigned char irq_edge_mask_lo, irq_edge_mask_hi;
 
-		printk("IBM ID: %08x\n", planar_id);
-		switch(planar_id) {
-		case 0xff:
-			Motherboard_map_name = "IBM Thinkpad 850/860";
-			Motherboard_map = Nobis_pci_IRQ_map;
-			Motherboard_routes = Nobis_pci_IRQ_routes;
-			irq_edge_mask_lo = 0x00; /* irq's 0-7 all edge-triggered */
-			irq_edge_mask_hi = 0xA0; /* irq's 13, 15 level-triggered */
-			break;
-		case 0xfc:
-			Motherboard_map_name = "IBM 6015/7020 (Sandalfoot/Sandalbow)";
-			Motherboard_map = ibm6015_pci_IRQ_map;
-			Motherboard_routes = ibm6015_pci_IRQ_routes;
-			irq_edge_mask_lo = 0x00; /* irq's 0-7 all edge-triggered */
-			irq_edge_mask_hi = 0xA0; /* irq's 13, 15 level-triggered */
-			break;
-		case 0xd5:
-			Motherboard_map_name = "IBM 43P-140 (Tiger1)";
-			Motherboard_map = ibm43p_pci_IRQ_map;
-			Motherboard_routes = ibm43p_pci_IRQ_routes;
-			Motherboard_non0 = ibm43p_pci_map_non0;
-			irq_edge_mask_lo = 0x00; /* irq's 0-7 all edge-triggered */
-			irq_edge_mask_hi = 0xA0; /* irq's 13, 15 level-triggered */
-			break;
-		default:
-			printk(KERN_ERR "Unknown IBM motherboard! Defaulting to Carolina.\n");
-		case 0xf0: /* PowerSeries 830/850 */
-		case 0xf1: /* PowerSeries 830/850 */
-		case 0xf2: /* PowerSeries 830/850 */
-		case 0xf4: /* 7248-43P */
-		case 0xf5: /* 7248-43P */
-		case 0xf6: /* 7248-43P */
-		case 0xf7: /* 7248-43P (missing from Carolina Tech Spec) */
-			Motherboard_map_name = "IBM PS830/PS850/7248 (Carolina)";
-			Motherboard_map = ibm8xx_pci_IRQ_map;
-			Motherboard_routes = ibm8xx_pci_IRQ_routes;
-			irq_edge_mask_lo = 0x00; /* irq's 0-7 all edge-triggered */
-			irq_edge_mask_hi = 0xA4; /* irq's 10, 13, 15 level-triggered */
-			break;
-		}
+		setup_ibm_pci(&irq_edge_mask_lo, &irq_edge_mask_hi);
 
-		outb(inb(0x04d0)|irq_edge_mask_lo, 0x04d0); /* primary 8259 */
-		outb(inb(0x04d1)|irq_edge_mask_hi, 0x04d1); /* cascaded 8259 */
+		outb(inb(0x04d0)|irq_edge_mask_lo, 0x4d0); /* primary 8259 */
+		outb(inb(0x04d1)|irq_edge_mask_hi, 0x4d1); /* cascaded 8259 */
 	} else {
 		printk("No known machine pci routing!\n");
 		return;
@@ -1121,7 +1143,6 @@
         struct pci_dev *dev;
         extern unsigned char *Motherboard_map;
         extern unsigned char *Motherboard_routes;
-        unsigned char i;
 
 	prep_route_pci_interrupts();
 
@@ -1152,7 +1173,7 @@
 		 */
 		unsigned char d = PCI_SLOT(dev->devfn);
 		dev->irq = Motherboard_routes[Motherboard_map[d]];
-
+#if 0
 		for ( i = 0 ; i <= 5 ; i++ ) {
 			/*
 			 * Relocate PCI I/O resources if necessary so the
@@ -1175,6 +1196,7 @@
 					| 0x01000000;
 		        }
 		}
+#endif
 #if 0
 		/*
 		 * If we have residual data and if it knows about this
@@ -1235,13 +1257,14 @@
 	hose->pci_mem_offset = PREP_ISA_MEM_BASE;
 	hose->io_base_phys = PREP_ISA_IO_BASE;
 	hose->io_base_virt = (void *)0x80000000; /* see prep_map_io() */
-	prep_init_resource(&hose->io_resource, 0, 0x0fffffff, IORESOURCE_IO);
+	prep_init_resource(&hose->io_resource, 0, 0x007fffff, IORESOURCE_IO);
 	prep_init_resource(&hose->mem_resources[0], 0xc0000000, 0xfeffffff,
 			   IORESOURCE_MEM);
-	
+	hose->ops = &prep_pci_ops;
+
 	printk("PReP architecture\n");
-	{
 #ifdef CONFIG_PREP_RESIDUAL	  
+	{
 		PPC_DEVICE *hostbridge;
 
 		hostbridge = residual_find_device(PROCESSORDEVICE, NULL,
@@ -1257,12 +1280,12 @@
 				setup_indirect_pci(hose, 
 					ld_le32((unsigned *) (p.PPCData)),
 					ld_le32((unsigned *) (p.PPCData+8)));
+#undef p
 			} else
 				setup_indirect_pci(hose, 0x80000cf8, 0x80000cfc);
-		} else
-#endif /* CONFIG_PREP_RESIDUAL */
-			hose->ops = &prep_pci_ops;
+		}
 	}
+#endif /* CONFIG_PREP_RESIDUAL */
 
 	ppc_md.pcibios_fixup = prep_pcibios_fixup;
 	ppc_md.pcibios_after_init = prep_pcibios_after_init;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)