patch-2.1.115 linux/arch/ppc/kernel/pmac_pci.c
Next file: linux/arch/ppc/kernel/pmac_setup.c
Previous file: linux/arch/ppc/kernel/pci.c
Back to the patch index
Back to the overall index
- Lines: 226
- Date:
Tue Aug 4 23:57:51 1998
- Orig file:
v2.1.114/linux/arch/ppc/kernel/pmac_pci.c
- Orig date:
Fri May 8 23:14:45 1998
diff -u --recursive --new-file v2.1.114/linux/arch/ppc/kernel/pmac_pci.c linux/arch/ppc/kernel/pmac_pci.c
@@ -12,7 +12,6 @@
* 2 of the License, or (at your option) any later version.
*/
-#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/delay.h>
@@ -33,6 +32,7 @@
*/
#define APPLE_VENDID 0x106b
#define BANDIT_DEVID 1
+#define BANDIT_DEVID_2 8
#define BANDIT_REVID 3
#define BANDIT_DEVNUM 11
@@ -96,8 +96,10 @@
struct bridge_data *bp;
*val = 0xffff;
- if (bus > max_bus || (bp = bridges[bus]) == 0 || (offset & 1) != 0)
+ if (bus > max_bus || (bp = bridges[bus]) == 0)
return PCIBIOS_DEVICE_NOT_FOUND;
+ if ((offset & 1) != 0)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
if (bus == bp->bus_number) {
if (dev_fn < (11 << 3))
return PCIBIOS_DEVICE_NOT_FOUND;
@@ -118,8 +120,10 @@
struct bridge_data *bp;
*val = 0xffffffff;
- if (bus > max_bus || (bp = bridges[bus]) == 0 || (offset & 3) != 0)
+ if (bus > max_bus || (bp = bridges[bus]) == 0)
return PCIBIOS_DEVICE_NOT_FOUND;
+ if ((offset & 3) != 0)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
if (bus == bp->bus_number) {
if (dev_fn < (11 << 3))
return PCIBIOS_DEVICE_NOT_FOUND;
@@ -160,8 +164,10 @@
{
struct bridge_data *bp;
- if (bus > max_bus || (bp = bridges[bus]) == 0 || (offset & 1) != 0)
+ if (bus > max_bus || (bp = bridges[bus]) == 0)
return PCIBIOS_DEVICE_NOT_FOUND;
+ if ((offset & 1) != 0)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
if (bus == bp->bus_number) {
if (dev_fn < (11 << 3))
return PCIBIOS_DEVICE_NOT_FOUND;
@@ -181,8 +187,10 @@
{
struct bridge_data *bp;
- if (bus > max_bus || (bp = bridges[bus]) == 0 || (offset & 3) != 0)
+ if (bus > max_bus || (bp = bridges[bus]) == 0)
return PCIBIOS_DEVICE_NOT_FOUND;
+ if ((offset & 3) != 0)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
if (bus == bp->bus_number) {
if (dev_fn < (11 << 3))
return PCIBIOS_DEVICE_NOT_FOUND;
@@ -197,6 +205,92 @@
return PCIBIOS_SUCCESSFUL;
}
+#define GRACKLE_CFA(b, d, o) (0x80 | ((b) << 8) | ((d) << 16) \
+ | (((o) & ~3) << 24))
+
+int grackle_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn,
+ unsigned char offset, unsigned char *val)
+{
+ struct bridge_data *bp;
+
+ *val = 0xff;
+ if (bus > max_bus || (bp = bridges[bus]) == 0)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ out_be32(bp->cfg_addr, GRACKLE_CFA(bus, dev_fn, offset));
+ *val = in_8(bp->cfg_data + (offset & 3));
+ return PCIBIOS_SUCCESSFUL;
+}
+
+int grackle_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn,
+ unsigned char offset, unsigned short *val)
+{
+ struct bridge_data *bp;
+
+ *val = 0xffff;
+ if (bus > max_bus || (bp = bridges[bus]) == 0)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ if ((offset & 1) != 0)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ out_be32(bp->cfg_addr, GRACKLE_CFA(bus, dev_fn, offset));
+ *val = in_le16((volatile unsigned short *)(bp->cfg_data + (offset&3)));
+ return PCIBIOS_SUCCESSFUL;
+}
+
+int grackle_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn,
+ unsigned char offset, unsigned int *val)
+{
+ struct bridge_data *bp;
+
+ *val = 0xffffffff;
+ if (bus > max_bus || (bp = bridges[bus]) == 0)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ if ((offset & 3) != 0)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ out_be32(bp->cfg_addr, GRACKLE_CFA(bus, dev_fn, offset));
+ *val = in_le32((volatile unsigned int *)bp->cfg_data);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+int grackle_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn,
+ unsigned char offset, unsigned char val)
+{
+ struct bridge_data *bp;
+
+ if (bus > max_bus || (bp = bridges[bus]) == 0)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ out_be32(bp->cfg_addr, GRACKLE_CFA(bus, dev_fn, offset));
+ out_8(bp->cfg_data + (offset & 3), val);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+int grackle_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn,
+ unsigned char offset, unsigned short val)
+{
+ struct bridge_data *bp;
+
+ if (bus > max_bus || (bp = bridges[bus]) == 0)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ if ((offset & 1) != 0)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ out_be32(bp->cfg_addr, GRACKLE_CFA(bus, dev_fn, offset));
+ out_le16((volatile unsigned short *)(bp->cfg_data + (offset&3)), val);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+int grackle_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn,
+ unsigned char offset, unsigned int val)
+{
+ struct bridge_data *bp;
+
+ if (bus > max_bus || (bp = bridges[bus]) == 0)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ if ((offset & 1) != 0)
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ out_be32(bp->cfg_addr, GRACKLE_CFA(bus, dev_fn, offset));
+ out_le32((volatile unsigned int *)bp->cfg_data, val);
+ return PCIBIOS_SUCCESSFUL;
+}
+
/*
* For a bandit bridge, turn on cache coherency if necessary.
* N.B. we can't use pcibios_*_config_* here because bridges[]
@@ -211,7 +305,17 @@
out_le32(bp->cfg_addr, (1UL << BANDIT_DEVNUM) + PCI_VENDOR_ID);
udelay(2);
vendev = in_le32((volatile unsigned int *)bp->cfg_data);
- if (vendev != (BANDIT_DEVID << 16) + APPLE_VENDID) {
+ if (vendev == (BANDIT_DEVID << 16) + APPLE_VENDID) {
+ /* read the revision id */
+ out_le32(bp->cfg_addr,
+ (1UL << BANDIT_DEVNUM) + PCI_REVISION_ID);
+ udelay(2);
+ rev = in_8(bp->cfg_data);
+ if (rev != BANDIT_REVID)
+ printk(KERN_WARNING
+ "Unknown revision %d for bandit at %p\n",
+ rev, bp->io_base);
+ } else if (vendev != (BANDIT_DEVID_2 << 16) + APPLE_VENDID) {
printk(KERN_WARNING "bandit isn't? (%x)\n", vendev);
return;
}
@@ -246,6 +350,7 @@
max_bus = 0;
add_bridges(find_devices("bandit"), &mem_start);
add_bridges(find_devices("chaos"), &mem_start);
+ add_bridges(find_devices("pci"), &mem_start);
bridges = (struct bridge_data **) mem_start;
mem_start += (max_bus + 1) * sizeof(struct bridge_data *);
memset(bridges, 0, (max_bus + 1) * sizeof(struct bridge_data *));
@@ -256,6 +361,11 @@
return mem_start;
}
+/*
+ * We assume that if we have a G3 powermac, we have one bridge called
+ * "pci" (a MPC106) and no bandit or chaos bridges, and contrariwise,
+ * if we have one or more bandit or chaos bridges, we don't have a MPC106.
+ */
__initfunc(static void add_bridges(struct device_node *dev, unsigned long *mem_ptr))
{
int *bus_range;
@@ -284,15 +394,22 @@
printk(" controlled by %s at %x\n", dev->name, addr->address);
bp = (struct bridge_data *) *mem_ptr;
*mem_ptr += sizeof(struct bridge_data);
- bp->cfg_addr = (volatile unsigned int *)
- ioremap(addr->address + 0x800000, 0x1000);
- bp->cfg_data = (volatile unsigned char *)
- ioremap(addr->address + 0xc00000, 0x1000);
- bp->io_base = (void *) ioremap(addr->address, 0x10000);
-#ifdef CONFIG_PMAC
+ if (strcmp(dev->name, "pci") != 0) {
+ bp->cfg_addr = (volatile unsigned int *)
+ ioremap(addr->address + 0x800000, 0x1000);
+ bp->cfg_data = (volatile unsigned char *)
+ ioremap(addr->address + 0xc00000, 0x1000);
+ bp->io_base = (void *) ioremap(addr->address, 0x10000);
+ } else {
+ /* XXX */
+ bp->cfg_addr = (volatile unsigned int *)
+ ioremap(0xfec00000, 0x1000);
+ bp->cfg_data = (volatile unsigned char *)
+ ioremap(0xfee00000, 0x1000);
+ bp->io_base = (void *) ioremap(0xfe000000, 0x10000);
+ }
if (isa_io_base == 0)
isa_io_base = (unsigned long) bp->io_base;
-#endif
bp->bus_number = bus_range[0];
bp->max_bus = bus_range[1];
bp->next = bridge_list;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov