11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds * This file is subject to the terms and conditions of the GNU General Public 31da177e4SLinus Torvalds * License. See the file "COPYING" in the main directory of this archive 41da177e4SLinus Torvalds * for more details. 51da177e4SLinus Torvalds * 61da177e4SLinus Torvalds * Copyright (C) 2000, 2001 Keith M Wesolowski 71da177e4SLinus Torvalds */ 81da177e4SLinus Torvalds #include <linux/kernel.h> 91da177e4SLinus Torvalds #include <linux/init.h> 101da177e4SLinus Torvalds #include <linux/pci.h> 111da177e4SLinus Torvalds #include <linux/types.h> 121da177e4SLinus Torvalds #include <asm/pci.h> 131da177e4SLinus Torvalds #include <asm/ip32/mace.h> 141da177e4SLinus Torvalds 151da177e4SLinus Torvalds #if 0 161da177e4SLinus Torvalds # define DPRINTK(args...) printk(args); 171da177e4SLinus Torvalds #else 181da177e4SLinus Torvalds # define DPRINTK(args...) 191da177e4SLinus Torvalds #endif 201da177e4SLinus Torvalds 211da177e4SLinus Torvalds /* 221da177e4SLinus Torvalds * O2 has up to 5 PCI devices connected into the MACE bridge. The device 231da177e4SLinus Torvalds * map looks like this: 241da177e4SLinus Torvalds * 251da177e4SLinus Torvalds * 0 aic7xxx 0 261da177e4SLinus Torvalds * 1 aic7xxx 1 271da177e4SLinus Torvalds * 2 expansion slot 281da177e4SLinus Torvalds * 3 N/C 291da177e4SLinus Torvalds * 4 N/C 301da177e4SLinus Torvalds */ 311da177e4SLinus Torvalds 328cfaf453SGiuseppe Sacco static inline int mkaddr(struct pci_bus *bus, unsigned int devfn, 338cfaf453SGiuseppe Sacco unsigned int reg) 348cfaf453SGiuseppe Sacco { 358cfaf453SGiuseppe Sacco return ((bus->number & 0xff) << 16) | 36*378a5459SGiuseppe Sacco ((devfn & 0xff) << 8) | 378cfaf453SGiuseppe Sacco (reg & 0xfc); 388cfaf453SGiuseppe Sacco } 391da177e4SLinus Torvalds 401da177e4SLinus Torvalds 411da177e4SLinus Torvalds static int 421da177e4SLinus Torvalds mace_pci_read_config(struct pci_bus *bus, unsigned int devfn, 431da177e4SLinus Torvalds int reg, int size, u32 *val) 441da177e4SLinus Torvalds { 458cfaf453SGiuseppe Sacco mace->pci.config_addr = mkaddr(bus, devfn, reg); 461da177e4SLinus Torvalds switch (size) { 471da177e4SLinus Torvalds case 1: 481da177e4SLinus Torvalds *val = mace->pci.config_data.b[(reg & 3) ^ 3]; 491da177e4SLinus Torvalds break; 501da177e4SLinus Torvalds case 2: 511da177e4SLinus Torvalds *val = mace->pci.config_data.w[((reg >> 1) & 1) ^ 1]; 521da177e4SLinus Torvalds break; 531da177e4SLinus Torvalds case 4: 541da177e4SLinus Torvalds *val = mace->pci.config_data.l; 551da177e4SLinus Torvalds break; 561da177e4SLinus Torvalds } 571da177e4SLinus Torvalds 581da177e4SLinus Torvalds DPRINTK("read%d: reg=%08x,val=%02x\n", size * 8, reg, *val); 591da177e4SLinus Torvalds 601da177e4SLinus Torvalds return PCIBIOS_SUCCESSFUL; 611da177e4SLinus Torvalds } 621da177e4SLinus Torvalds 631da177e4SLinus Torvalds static int 641da177e4SLinus Torvalds mace_pci_write_config(struct pci_bus *bus, unsigned int devfn, 651da177e4SLinus Torvalds int reg, int size, u32 val) 661da177e4SLinus Torvalds { 678cfaf453SGiuseppe Sacco mace->pci.config_addr = mkaddr(bus, devfn, reg); 681da177e4SLinus Torvalds switch (size) { 691da177e4SLinus Torvalds case 1: 701da177e4SLinus Torvalds mace->pci.config_data.b[(reg & 3) ^ 3] = val; 711da177e4SLinus Torvalds break; 721da177e4SLinus Torvalds case 2: 731da177e4SLinus Torvalds mace->pci.config_data.w[((reg >> 1) & 1) ^ 1] = val; 741da177e4SLinus Torvalds break; 751da177e4SLinus Torvalds case 4: 761da177e4SLinus Torvalds mace->pci.config_data.l = val; 771da177e4SLinus Torvalds break; 781da177e4SLinus Torvalds } 791da177e4SLinus Torvalds 801da177e4SLinus Torvalds DPRINTK("write%d: reg=%08x,val=%02x\n", size * 8, reg, val); 811da177e4SLinus Torvalds 821da177e4SLinus Torvalds return PCIBIOS_SUCCESSFUL; 831da177e4SLinus Torvalds } 841da177e4SLinus Torvalds 851da177e4SLinus Torvalds struct pci_ops mace_pci_ops = { 861da177e4SLinus Torvalds .read = mace_pci_read_config, 871da177e4SLinus Torvalds .write = mace_pci_write_config, 881da177e4SLinus Torvalds }; 89