root/arch/mips/pci/ops-sni.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. set_config_address
  2. pcimt_read
  3. pcimt_write
  4. pcit_set_config_address
  5. pcit_read
  6. pcit_write

   1 /*
   2  * This file is subject to the terms and conditions of the GNU General Public
   3  * License.  See the file "COPYING" in the main directory of this archive
   4  * for more details.
   5  *
   6  * SNI specific PCI support for RM200/RM300.
   7  *
   8  * Copyright (C) 1997 - 2000, 2003 Ralf Baechle <ralf@linux-mips.org>
   9  */
  10 #include <linux/kernel.h>
  11 #include <linux/pci.h>
  12 #include <linux/types.h>
  13 #include <asm/sni.h>
  14 
  15 /*
  16  * It seems that on the RM200 only lower 3 bits of the 5 bit PCI device
  17  * address are decoded.  We therefore manually have to reject attempts at
  18  * reading outside this range.  Being on the paranoid side we only do this
  19  * test for bus 0 and hope forwarding and decoding work properly for any
  20  * subordinated busses.
  21  *
  22  * ASIC PCI only supports type 1 config cycles.
  23  */
  24 static int set_config_address(unsigned int busno, unsigned int devfn, int reg)
  25 {
  26         if ((devfn > 255) || (reg > 255))
  27                 return PCIBIOS_BAD_REGISTER_NUMBER;
  28 
  29         if (busno == 0 && devfn >= PCI_DEVFN(8, 0))
  30                 return PCIBIOS_DEVICE_NOT_FOUND;
  31 
  32         *(volatile u32 *)PCIMT_CONFIG_ADDRESS =
  33                  ((busno    & 0xff) << 16) |
  34                  ((devfn    & 0xff) <<  8) |
  35                   (reg      & 0xfc);
  36 
  37         return PCIBIOS_SUCCESSFUL;
  38 }
  39 
  40 static int pcimt_read(struct pci_bus *bus, unsigned int devfn, int reg,
  41                       int size, u32 * val)
  42 {
  43         int res;
  44 
  45         if ((res = set_config_address(bus->number, devfn, reg)))
  46                 return res;
  47 
  48         switch (size) {
  49         case 1:
  50                 *val = inb(PCIMT_CONFIG_DATA + (reg & 3));
  51                 break;
  52         case 2:
  53                 *val = inw(PCIMT_CONFIG_DATA + (reg & 2));
  54                 break;
  55         case 4:
  56                 *val = inl(PCIMT_CONFIG_DATA);
  57                 break;
  58         }
  59 
  60         return 0;
  61 }
  62 
  63 static int pcimt_write(struct pci_bus *bus, unsigned int devfn, int reg,
  64                        int size, u32 val)
  65 {
  66         int res;
  67 
  68         if ((res = set_config_address(bus->number, devfn, reg)))
  69                 return res;
  70 
  71         switch (size) {
  72         case 1:
  73                 outb(val, PCIMT_CONFIG_DATA + (reg & 3));
  74                 break;
  75         case 2:
  76                 outw(val, PCIMT_CONFIG_DATA + (reg & 2));
  77                 break;
  78         case 4:
  79                 outl(val, PCIMT_CONFIG_DATA);
  80                 break;
  81         }
  82 
  83         return 0;
  84 }
  85 
  86 struct pci_ops sni_pcimt_ops = {
  87         .read = pcimt_read,
  88         .write = pcimt_write,
  89 };
  90 
  91 static int pcit_set_config_address(unsigned int busno, unsigned int devfn, int reg)
  92 {
  93         if ((devfn > 255) || (reg > 255) || (busno > 255))
  94                 return PCIBIOS_BAD_REGISTER_NUMBER;
  95 
  96         outl((1 << 31) | ((busno & 0xff) << 16) | ((devfn & 0xff) << 8) | (reg & 0xfc), 0xcf8);
  97         return PCIBIOS_SUCCESSFUL;
  98 }
  99 
 100 static int pcit_read(struct pci_bus *bus, unsigned int devfn, int reg,
 101                       int size, u32 * val)
 102 {
 103         int res;
 104 
 105         /*
 106          * on bus 0 we need to check, whether there is a device answering
 107          * for the devfn by doing a config write and checking the result. If
 108          * we don't do it, we will get a data bus error
 109          */
 110         if (bus->number == 0) {
 111                 pcit_set_config_address(0, 0, 0x68);
 112                 outl(inl(0xcfc) | 0xc0000000, 0xcfc);
 113                 if ((res = pcit_set_config_address(0, devfn, 0)))
 114                         return res;
 115                 outl(0xffffffff, 0xcfc);
 116                 pcit_set_config_address(0, 0, 0x68);
 117                 if (inl(0xcfc) & 0x100000)
 118                         return PCIBIOS_DEVICE_NOT_FOUND;
 119         }
 120         if ((res = pcit_set_config_address(bus->number, devfn, reg)))
 121                 return res;
 122 
 123         switch (size) {
 124         case 1:
 125                 *val = inb(PCIMT_CONFIG_DATA + (reg & 3));
 126                 break;
 127         case 2:
 128                 *val = inw(PCIMT_CONFIG_DATA + (reg & 2));
 129                 break;
 130         case 4:
 131                 *val = inl(PCIMT_CONFIG_DATA);
 132                 break;
 133         }
 134         return 0;
 135 }
 136 
 137 static int pcit_write(struct pci_bus *bus, unsigned int devfn, int reg,
 138                        int size, u32 val)
 139 {
 140         int res;
 141 
 142         if ((res = pcit_set_config_address(bus->number, devfn, reg)))
 143                 return res;
 144 
 145         switch (size) {
 146         case 1:
 147                 outb(val, PCIMT_CONFIG_DATA + (reg & 3));
 148                 break;
 149         case 2:
 150                 outw(val, PCIMT_CONFIG_DATA + (reg & 2));
 151                 break;
 152         case 4:
 153                 outl(val, PCIMT_CONFIG_DATA);
 154                 break;
 155         }
 156 
 157         return 0;
 158 }
 159 
 160 
 161 struct pci_ops sni_pcit_ops = {
 162         .read = pcit_read,
 163         .write = pcit_write,
 164 };

/* [<][>][^][v][top][bottom][index][help] */