^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * This file is subject to the terms and conditions of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * License. See the file "COPYING" in the main directory of this archive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2000, 2001 Keith M Wesolowski
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <asm/ip32/mace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) # define DPRINTK(args...) printk(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) # define DPRINTK(args...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * O2 has up to 5 PCI devices connected into the MACE bridge. The device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * map looks like this:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * 0 aic7xxx 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * 1 aic7xxx 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * 2 expansion slot
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * 3 N/C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * 4 N/C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) static inline int mkaddr(struct pci_bus *bus, unsigned int devfn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) return ((bus->number & 0xff) << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) ((devfn & 0xff) << 8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) (reg & 0xfc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) mace_pci_read_config(struct pci_bus *bus, unsigned int devfn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) int reg, int size, u32 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) u32 control = mace->pci.control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) /* disable master aborts interrupts during config read */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) mace->pci.control = control & ~MACEPCI_CONTROL_MAR_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) mace->pci.config_addr = mkaddr(bus, devfn, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) switch (size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) *val = mace->pci.config_data.b[(reg & 3) ^ 3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) *val = mace->pci.config_data.w[((reg >> 1) & 1) ^ 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) *val = mace->pci.config_data.l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) /* ack possible master abort */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) mace->pci.error &= ~MACEPCI_ERROR_MASTER_ABORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) mace->pci.control = control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * someone forgot to set the ultra bit for the onboard
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * scsi chips; we fake it here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) if (bus->number == 0 && reg == 0x40 && size == 4 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) (devfn == (1 << 3) || devfn == (2 << 3)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) *val |= 0x1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) DPRINTK("read%d: reg=%08x,val=%02x\n", size * 8, reg, *val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) return PCIBIOS_SUCCESSFUL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) mace_pci_write_config(struct pci_bus *bus, unsigned int devfn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) int reg, int size, u32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) mace->pci.config_addr = mkaddr(bus, devfn, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) switch (size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) mace->pci.config_data.b[(reg & 3) ^ 3] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) mace->pci.config_data.w[((reg >> 1) & 1) ^ 1] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) mace->pci.config_data.l = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) DPRINTK("write%d: reg=%08x,val=%02x\n", size * 8, reg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) return PCIBIOS_SUCCESSFUL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) struct pci_ops mace_pci_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) .read = mace_pci_read_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) .write = mace_pci_write_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) };