Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  *  BRIEF MODULE DESCRIPTION
0003  *     pci_ops for IDT EB434 board
0004  *
0005  *  Copyright 2004 IDT Inc. (rischelp@idt.com)
0006  *  Copyright 2006 Felix Fietkau <nbd@openwrt.org>
0007  *
0008  *  This program is free software; you can redistribute  it and/or modify it
0009  *  under  the terms of  the GNU General  Public License as published by the
0010  *  Free Software Foundation;  either version 2 of the  License, or (at your
0011  *  option) any later version.
0012  *
0013  *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
0014  *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
0015  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
0016  *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
0017  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
0018  *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
0019  *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
0020  *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
0021  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
0022  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0023  *
0024  *  You should have received a copy of the  GNU General Public License along
0025  *  with this program; if not, write  to the Free Software Foundation, Inc.,
0026  *  675 Mass Ave, Cambridge, MA 02139, USA.
0027  */
0028 #include <linux/delay.h>
0029 #include <linux/io.h>
0030 #include <linux/pci.h>
0031 #include <linux/types.h>
0032 
0033 #include <asm/cpu.h>
0034 #include <asm/mach-rc32434/rc32434.h>
0035 #include <asm/mach-rc32434/pci.h>
0036 
0037 #define PCI_ACCESS_READ  0
0038 #define PCI_ACCESS_WRITE 1
0039 
0040 
0041 #define PCI_CFG_SET(bus, slot, func, off) \
0042     (rc32434_pci->pcicfga = (0x80000000 | \
0043                 ((bus) << 16) | ((slot)<<11) | \
0044                 ((func)<<8) | (off)))
0045 
0046 static inline int config_access(unsigned char access_type,
0047                 struct pci_bus *bus, unsigned int devfn,
0048                 unsigned char where, u32 *data)
0049 {
0050     unsigned int slot = PCI_SLOT(devfn);
0051     u8 func = PCI_FUNC(devfn);
0052 
0053     /* Setup address */
0054     PCI_CFG_SET(bus->number, slot, func, where);
0055     rc32434_sync();
0056 
0057     if (access_type == PCI_ACCESS_WRITE)
0058         rc32434_pci->pcicfgd = *data;
0059     else
0060         *data = rc32434_pci->pcicfgd;
0061 
0062     rc32434_sync();
0063 
0064     return 0;
0065 }
0066 
0067 
0068 /*
0069  * We can't address 8 and 16 bit words directly.  Instead we have to
0070  * read/write a 32bit word and mask/modify the data we actually want.
0071  */
0072 static int read_config_byte(struct pci_bus *bus, unsigned int devfn,
0073                 int where, u8 *val)
0074 {
0075     u32 data;
0076     int ret;
0077 
0078     ret = config_access(PCI_ACCESS_READ, bus, devfn, where, &data);
0079     *val = (data >> ((where & 3) << 3)) & 0xff;
0080     return ret;
0081 }
0082 
0083 static int read_config_word(struct pci_bus *bus, unsigned int devfn,
0084                 int where, u16 *val)
0085 {
0086     u32 data;
0087     int ret;
0088 
0089     ret = config_access(PCI_ACCESS_READ, bus, devfn, where, &data);
0090     *val = (data >> ((where & 3) << 3)) & 0xffff;
0091     return ret;
0092 }
0093 
0094 static int read_config_dword(struct pci_bus *bus, unsigned int devfn,
0095                  int where, u32 *val)
0096 {
0097     int ret;
0098     int delay = 1;
0099 
0100     /*
0101      * Don't scan too far, else there will be errors with plugged in
0102      * daughterboard (rb564).
0103      */
0104     if (bus->number == 0 && PCI_SLOT(devfn) > 21)
0105         return 0;
0106 
0107 retry:
0108     ret = config_access(PCI_ACCESS_READ, bus, devfn, where, val);
0109 
0110     /*
0111      * Certain devices react delayed at device scan time, this
0112      * gives them time to settle
0113      */
0114     if (where == PCI_VENDOR_ID) {
0115         if (ret == 0xffffffff || ret == 0x00000000 ||
0116             ret == 0x0000ffff || ret == 0xffff0000) {
0117             if (delay > 4)
0118                 return 0;
0119             delay *= 2;
0120             msleep(delay);
0121             goto retry;
0122         }
0123     }
0124 
0125     return ret;
0126 }
0127 
0128 static int
0129 write_config_byte(struct pci_bus *bus, unsigned int devfn, int where,
0130           u8 val)
0131 {
0132     u32 data = 0;
0133 
0134     if (config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
0135         return -1;
0136 
0137     data = (data & ~(0xff << ((where & 3) << 3))) |
0138         (val << ((where & 3) << 3));
0139 
0140     if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data))
0141         return -1;
0142 
0143     return PCIBIOS_SUCCESSFUL;
0144 }
0145 
0146 
0147 static int
0148 write_config_word(struct pci_bus *bus, unsigned int devfn, int where,
0149           u16 val)
0150 {
0151     u32 data = 0;
0152 
0153     if (config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
0154         return -1;
0155 
0156     data = (data & ~(0xffff << ((where & 3) << 3))) |
0157         (val << ((where & 3) << 3));
0158 
0159     if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data))
0160         return -1;
0161 
0162 
0163     return PCIBIOS_SUCCESSFUL;
0164 }
0165 
0166 
0167 static int
0168 write_config_dword(struct pci_bus *bus, unsigned int devfn, int where,
0169            u32 val)
0170 {
0171     if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &val))
0172         return -1;
0173 
0174     return PCIBIOS_SUCCESSFUL;
0175 }
0176 
0177 static int pci_config_read(struct pci_bus *bus, unsigned int devfn,
0178                int where, int size, u32 *val)
0179 {
0180     switch (size) {
0181     case 1:
0182         return read_config_byte(bus, devfn, where, (u8 *) val);
0183     case 2:
0184         return read_config_word(bus, devfn, where, (u16 *) val);
0185     default:
0186         return read_config_dword(bus, devfn, where, val);
0187     }
0188 }
0189 
0190 static int pci_config_write(struct pci_bus *bus, unsigned int devfn,
0191                 int where, int size, u32 val)
0192 {
0193     switch (size) {
0194     case 1:
0195         return write_config_byte(bus, devfn, where, (u8) val);
0196     case 2:
0197         return write_config_word(bus, devfn, where, (u16) val);
0198     default:
0199         return write_config_dword(bus, devfn, where, val);
0200     }
0201 }
0202 
0203 struct pci_ops rc32434_pci_ops = {
0204     .read = pci_config_read,
0205     .write = pci_config_write,
0206 };