GNU Linux-libre 4.19.286-gnu1
[releases.git] / arch / mips / pci / ops-rc32434.c
1 /*
2  *  BRIEF MODULE DESCRIPTION
3  *     pci_ops for IDT EB434 board
4  *
5  *  Copyright 2004 IDT Inc. (rischelp@idt.com)
6  *  Copyright 2006 Felix Fietkau <nbd@openwrt.org>
7  *
8  *  This program is free software; you can redistribute  it and/or modify it
9  *  under  the terms of  the GNU General  Public License as published by the
10  *  Free Software Foundation;  either version 2 of the  License, or (at your
11  *  option) any later version.
12  *
13  *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
14  *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
15  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
16  *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
17  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18  *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
19  *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20  *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
21  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  *
24  *  You should have received a copy of the  GNU General Public License along
25  *  with this program; if not, write  to the Free Software Foundation, Inc.,
26  *  675 Mass Ave, Cambridge, MA 02139, USA.
27  */
28 #include <linux/delay.h>
29 #include <linux/io.h>
30 #include <linux/pci.h>
31 #include <linux/types.h>
32
33 #include <asm/cpu.h>
34 #include <asm/mach-rc32434/rc32434.h>
35 #include <asm/mach-rc32434/pci.h>
36
37 #define PCI_ACCESS_READ  0
38 #define PCI_ACCESS_WRITE 1
39
40
41 #define PCI_CFG_SET(bus, slot, func, off) \
42         (rc32434_pci->pcicfga = (0x80000000 | \
43                                 ((bus) << 16) | ((slot)<<11) | \
44                                 ((func)<<8) | (off)))
45
46 static inline int config_access(unsigned char access_type,
47                                 struct pci_bus *bus, unsigned int devfn,
48                                 unsigned char where, u32 *data)
49 {
50         unsigned int slot = PCI_SLOT(devfn);
51         u8 func = PCI_FUNC(devfn);
52
53         /* Setup address */
54         PCI_CFG_SET(bus->number, slot, func, where);
55         rc32434_sync();
56
57         if (access_type == PCI_ACCESS_WRITE)
58                 rc32434_pci->pcicfgd = *data;
59         else
60                 *data = rc32434_pci->pcicfgd;
61
62         rc32434_sync();
63
64         return 0;
65 }
66
67
68 /*
69  * We can't address 8 and 16 bit words directly.  Instead we have to
70  * read/write a 32bit word and mask/modify the data we actually want.
71  */
72 static int read_config_byte(struct pci_bus *bus, unsigned int devfn,
73                             int where, u8 *val)
74 {
75         u32 data;
76         int ret;
77
78         ret = config_access(PCI_ACCESS_READ, bus, devfn, where, &data);
79         *val = (data >> ((where & 3) << 3)) & 0xff;
80         return ret;
81 }
82
83 static int read_config_word(struct pci_bus *bus, unsigned int devfn,
84                             int where, u16 *val)
85 {
86         u32 data;
87         int ret;
88
89         ret = config_access(PCI_ACCESS_READ, bus, devfn, where, &data);
90         *val = (data >> ((where & 3) << 3)) & 0xffff;
91         return ret;
92 }
93
94 static int read_config_dword(struct pci_bus *bus, unsigned int devfn,
95                              int where, u32 *val)
96 {
97         int ret;
98         int delay = 1;
99
100         /*
101          * Don't scan too far, else there will be errors with plugged in
102          * daughterboard (rb564).
103          */
104         if (bus->number == 0 && PCI_SLOT(devfn) > 21)
105                 return 0;
106
107 retry:
108         ret = config_access(PCI_ACCESS_READ, bus, devfn, where, val);
109
110         /*
111          * Certain devices react delayed at device scan time, this
112          * gives them time to settle
113          */
114         if (where == PCI_VENDOR_ID) {
115                 if (ret == 0xffffffff || ret == 0x00000000 ||
116                     ret == 0x0000ffff || ret == 0xffff0000) {
117                         if (delay > 4)
118                                 return 0;
119                         delay *= 2;
120                         msleep(delay);
121                         goto retry;
122                 }
123         }
124
125         return ret;
126 }
127
128 static int
129 write_config_byte(struct pci_bus *bus, unsigned int devfn, int where,
130                   u8 val)
131 {
132         u32 data = 0;
133
134         if (config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
135                 return -1;
136
137         data = (data & ~(0xff << ((where & 3) << 3))) |
138             (val << ((where & 3) << 3));
139
140         if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data))
141                 return -1;
142
143         return PCIBIOS_SUCCESSFUL;
144 }
145
146
147 static int
148 write_config_word(struct pci_bus *bus, unsigned int devfn, int where,
149                   u16 val)
150 {
151         u32 data = 0;
152
153         if (config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
154                 return -1;
155
156         data = (data & ~(0xffff << ((where & 3) << 3))) |
157             (val << ((where & 3) << 3));
158
159         if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data))
160                 return -1;
161
162
163         return PCIBIOS_SUCCESSFUL;
164 }
165
166
167 static int
168 write_config_dword(struct pci_bus *bus, unsigned int devfn, int where,
169                    u32 val)
170 {
171         if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &val))
172                 return -1;
173
174         return PCIBIOS_SUCCESSFUL;
175 }
176
177 static int pci_config_read(struct pci_bus *bus, unsigned int devfn,
178                            int where, int size, u32 *val)
179 {
180         switch (size) {
181         case 1:
182                 return read_config_byte(bus, devfn, where, (u8 *) val);
183         case 2:
184                 return read_config_word(bus, devfn, where, (u16 *) val);
185         default:
186                 return read_config_dword(bus, devfn, where, val);
187         }
188 }
189
190 static int pci_config_write(struct pci_bus *bus, unsigned int devfn,
191                             int where, int size, u32 val)
192 {
193         switch (size) {
194         case 1:
195                 return write_config_byte(bus, devfn, where, (u8) val);
196         case 2:
197                 return write_config_word(bus, devfn, where, (u16) val);
198         default:
199                 return write_config_dword(bus, devfn, where, val);
200         }
201 }
202
203 struct pci_ops rc32434_pci_ops = {
204         .read = pci_config_read,
205         .write = pci_config_write,
206 };