patch-2.2.4 linux/arch/ppc/kernel/prep_pci.c
Next file: linux/arch/ppc/kernel/prep_setup.c
Previous file: linux/arch/ppc/kernel/ppc_ksyms.c
Back to the patch index
Back to the overall index
- Lines: 186
- Date:
Fri Mar 19 10:50:03 1999
- Orig file:
v2.2.3/linux/arch/ppc/kernel/prep_pci.c
- Orig date:
Tue Dec 22 14:16:54 1998
diff -u --recursive --new-file v2.2.3/linux/arch/ppc/kernel/prep_pci.c linux/arch/ppc/kernel/prep_pci.c
@@ -1,5 +1,5 @@
/*
- * $Id: prep_pci.c,v 1.24 1998/12/10 02:39:51 cort Exp $
+ * $Id: prep_pci.c,v 1.25 1999/03/03 15:09:45 cort Exp $
* PReP pci functions.
* Originally by Gary Thomas
* rewritten and updated by Cort Dougan (cort@cs.nmt.edu)
@@ -312,6 +312,106 @@
#define CAROLINA_IRQ_EDGE_MASK_LO 0x00 /* IRQ's 0-7 */
#define CAROLINA_IRQ_EDGE_MASK_HI 0xA4 /* IRQ's 8-15 [10,13,15] */
+/*
+ * 8259 edge/level control definitions
+ */
+#define ISA8259_M_ELCR 0x4d0
+#define ISA8259_S_ELCR 0x4d1
+
+#define ELCRS_INT15_LVL 0x80
+#define ELCRS_INT14_LVL 0x40
+#define ELCRS_INT12_LVL 0x10
+#define ELCRS_INT11_LVL 0x08
+#define ELCRS_INT10_LVL 0x04
+#define ELCRS_INT9_LVL 0x02
+#define ELCRS_INT8_LVL 0x01
+#define ELCRM_INT7_LVL 0x80
+#define ELCRM_INT5_LVL 0x20
+
+/*
+ * Mechanism 1 configuration space access as defined in the PCI spec.
+ */
+#define CFG_ADDR (volatile u_int *)0x80000cf8
+#define CFG_DATA 0x80000cfc
+
+#define CFG_DEV_ADDR(b, d, o) (0x80000000 | \
+ ((b) << 16) | \
+ ((d) << 8) | \
+ ((o) & ~3))
+
+unsigned char max_bus=255;
+
+int mech1_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn,
+ unsigned char offset, unsigned char *val)
+{
+ *val = 0xff;
+ if (bus > max_bus)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ out_le32(CFG_ADDR, CFG_DEV_ADDR(bus, dev_fn, offset));
+ *val = in_8((unsigned char *)CFG_DATA + (offset & 3));
+ return PCIBIOS_SUCCESSFUL;
+}
+
+int mech1_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn,
+ unsigned char offset, unsigned short *val)
+{
+ *val = 0xffff;
+ if (bus > max_bus)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ if ((offset & 1) != 0)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ out_le32(CFG_ADDR, CFG_DEV_ADDR(bus, dev_fn, offset));
+ *val = in_le16((volatile unsigned short *)(CFG_DATA + (offset&3)));
+ return PCIBIOS_SUCCESSFUL;
+}
+
+int mech1_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn,
+ unsigned char offset, unsigned int *val)
+{
+ *val = 0xffffffff;
+ if (bus > max_bus)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ if ((offset & 3) != 0)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ out_le32(CFG_ADDR, CFG_DEV_ADDR(bus, dev_fn, offset));
+ *val = in_le32((volatile unsigned int *)CFG_DATA);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+int mech1_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn,
+ unsigned char offset, unsigned char val)
+{
+ if (bus > max_bus)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ out_le32(CFG_ADDR, CFG_DEV_ADDR(bus, dev_fn, offset));
+ out_8((unsigned char *)CFG_DATA + (offset & 3), val);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+int mech1_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn,
+ unsigned char offset, unsigned short val)
+{
+ if (bus > max_bus)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ if ((offset & 1) != 0)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ out_le32(CFG_ADDR, CFG_DEV_ADDR(bus, dev_fn, offset));
+ out_le16((volatile unsigned short *)(CFG_DATA + (offset&3)), val);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+int mech1_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn,
+ unsigned char offset, unsigned int val)
+{
+ if (bus > max_bus)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ if ((offset & 1) != 0)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ out_le32(CFG_ADDR, CFG_DEV_ADDR(bus, dev_fn, offset));
+ out_le32((volatile unsigned int *)CFG_DATA, val);
+ return PCIBIOS_SUCCESSFUL;
+}
+
__prep
int
prep_pcibios_read_config_dword (unsigned char bus,
@@ -526,6 +626,71 @@
outb(pl_id|CAROLINA_IRQ_EDGE_MASK_HI, 0x04d1);
pl_id=inb(0x04d1);
/*printk("Hi mask now %#0x\n", pl_id);*/
+ } else if ( _prep_type == _PREP_Radstone )
+ {
+ unsigned char ucElcrM, ucElcrS;
+
+ /*
+ * Set up edge/level
+ */
+ switch(ucSystemType)
+ {
+ case RS_SYS_TYPE_PPC1:
+ {
+ if(ucBoardRevMaj<5)
+ {
+ ucElcrS=ELCRS_INT15_LVL;
+ }
+ else
+ {
+ ucElcrS=ELCRS_INT9_LVL |
+ ELCRS_INT11_LVL |
+ ELCRS_INT14_LVL |
+ ELCRS_INT15_LVL;
+ }
+ ucElcrM=ELCRM_INT5_LVL | ELCRM_INT7_LVL;
+ break;
+ }
+
+ case RS_SYS_TYPE_PPC1a:
+ {
+ ucElcrS=ELCRS_INT9_LVL |
+ ELCRS_INT11_LVL |
+ ELCRS_INT14_LVL |
+ ELCRS_INT15_LVL;
+ ucElcrM=ELCRM_INT5_LVL;
+ break;
+ }
+
+ case RS_SYS_TYPE_PPC2:
+ case RS_SYS_TYPE_PPC2a:
+ case RS_SYS_TYPE_PPC2ep:
+ case RS_SYS_TYPE_PPC4:
+ case RS_SYS_TYPE_PPC4a:
+ default:
+ {
+ ucElcrS=ELCRS_INT9_LVL |
+ ELCRS_INT10_LVL |
+ ELCRS_INT11_LVL |
+ ELCRS_INT14_LVL |
+ ELCRS_INT15_LVL;
+ ucElcrM=ELCRM_INT5_LVL |
+ ELCRM_INT7_LVL;
+ break;
+ }
+ }
+
+ /*
+ * Write edge/level selection
+ */
+ outb(ucElcrS, ISA8259_S_ELCR);
+ outb(ucElcrM, ISA8259_M_ELCR);
+
+ /*
+ * Radstone boards have PCI interrupts all set up
+ * so leave well alone
+ */
+ return 0;
} else
{
printk("No known machine pci routing!\n");
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)