• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/arch/mips/pmc-sierra/yosemite/
1/*
2 * Copyright 2003 PMC-Sierra
3 * Author: Manish Lachwani (lachwani@pmc-sierra.com)
4 *
5 *  This program is free software; you can redistribute  it and/or modify it
6 *  under  the terms of  the GNU General  Public License as published by the
7 *  Free Software Foundation;  either version 2 of the  License, or (at your
8 *  option) any later version.
9 *
10 *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
11 *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
12 *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
13 *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
14 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
15 *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
16 *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
17 *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
18 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
19 *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20 *
21 *  You should have received a copy of the  GNU General Public License along
22 *  with this program; if not, write  to the Free Software Foundation, Inc.,
23 *  675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26#include <linux/types.h>
27#include <linux/pci.h>
28#include <linux/kernel.h>
29#include <asm/pci.h>
30#include <asm/io.h>
31
32#include <linux/init.h>
33#include <asm/titan_dep.h>
34
35#ifdef CONFIG_HYPERTRANSPORT
36
37
38/*
39 * This function check if the Hypertransport Link Initialization completed. If
40 * it did, then proceed further with scanning bus #2
41 */
42static __inline__ int check_titan_htlink(void)
43{
44        u32 val;
45
46        val = *(volatile uint32_t *)(RM9000x2_HTLINK_REG);
47        if (val & 0x00000020)
48                /* HT Link Initialization completed */
49                return 1;
50        else
51                return 0;
52}
53
54static int titan_ht_config_read_dword(struct pci_dev *device,
55                                             int offset, u32* val)
56{
57        int dev, bus, func;
58        uint32_t address_reg, data_reg;
59        uint32_t address;
60
61        bus = device->bus->number;
62        dev = PCI_SLOT(device->devfn);
63        func = PCI_FUNC(device->devfn);
64
65        if (bus > 2)
66                address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) |
67                                                        0x80000000 | 0x1;
68        else
69                address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000;
70
71        address_reg = RM9000x2_OCD_HTCFGA;
72        data_reg =  RM9000x2_OCD_HTCFGD;
73
74        RM9K_WRITE(address_reg, address);
75        RM9K_READ(data_reg, val);
76
77        return PCIBIOS_SUCCESSFUL;
78}
79
80
81static int titan_ht_config_read_word(struct pci_dev *device,
82                                             int offset, u16* val)
83{
84        int dev, bus, func;
85        uint32_t address_reg, data_reg;
86        uint32_t address;
87
88        bus = device->bus->number;
89        dev = PCI_SLOT(device->devfn);
90        func = PCI_FUNC(device->devfn);
91
92        if (bus > 2)
93                address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) |
94                                                0x80000000 | 0x1;
95        else
96                address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000;
97
98        address_reg = RM9000x2_OCD_HTCFGA;
99        data_reg =  RM9000x2_OCD_HTCFGD;
100
101        if ((offset & 0x3) == 0)
102                offset = 0x2;
103        else
104                offset = 0x0;
105
106        RM9K_WRITE(address_reg, address);
107        RM9K_READ_16(data_reg + offset, val);
108
109        return PCIBIOS_SUCCESSFUL;
110}
111
112
113u32 longswap(unsigned long l)
114{
115        unsigned char b1, b2, b3, b4;
116
117        b1 = l&255;
118        b2 = (l>>8)&255;
119        b3 = (l>>16)&255;
120        b4 = (l>>24)&255;
121
122        return ((b1<<24) + (b2<<16) + (b3<<8) + b4);
123}
124
125
126static int titan_ht_config_read_byte(struct pci_dev *device,
127                                             int offset, u8* val)
128{
129        int dev, bus, func;
130        uint32_t address_reg, data_reg;
131        uint32_t address;
132        int offset1;
133
134        bus = device->bus->number;
135        dev = PCI_SLOT(device->devfn);
136        func = PCI_FUNC(device->devfn);
137
138        if (bus > 2)
139                address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) |
140                                                        0x80000000 | 0x1;
141        else
142                address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000;
143
144        address_reg = RM9000x2_OCD_HTCFGA;
145        data_reg =  RM9000x2_OCD_HTCFGD;
146
147        RM9K_WRITE(address_reg, address);
148
149        if ((offset & 0x3) == 0) {
150                offset1 = 0x3;
151        }
152        if ((offset & 0x3) == 1) {
153                offset1 = 0x2;
154        }
155        if ((offset & 0x3) == 2) {
156                offset1 = 0x1;
157        }
158        if ((offset & 0x3) == 3) {
159                offset1 = 0x0;
160        }
161        RM9K_READ_8(data_reg + offset1, val);
162
163        return PCIBIOS_SUCCESSFUL;
164}
165
166
167static int titan_ht_config_write_dword(struct pci_dev *device,
168                                             int offset, u8 val)
169{
170        int dev, bus, func;
171        uint32_t address_reg, data_reg;
172        uint32_t address;
173
174        bus = device->bus->number;
175        dev = PCI_SLOT(device->devfn);
176        func = PCI_FUNC(device->devfn);
177
178        if (bus > 2)
179                address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) |
180                                                        0x80000000 | 0x1;
181        else
182              address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000;
183
184        address_reg = RM9000x2_OCD_HTCFGA;
185        data_reg =  RM9000x2_OCD_HTCFGD;
186
187        RM9K_WRITE(address_reg, address);
188        RM9K_WRITE(data_reg, val);
189
190        return PCIBIOS_SUCCESSFUL;
191}
192
193static int titan_ht_config_write_word(struct pci_dev *device,
194                                             int offset, u8 val)
195{
196        int dev, bus, func;
197        uint32_t address_reg, data_reg;
198        uint32_t address;
199
200        bus = device->bus->number;
201        dev = PCI_SLOT(device->devfn);
202        func = PCI_FUNC(device->devfn);
203
204        if (bus > 2)
205                address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) |
206                                0x80000000 | 0x1;
207        else
208                address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000;
209
210        address_reg = RM9000x2_OCD_HTCFGA;
211        data_reg =  RM9000x2_OCD_HTCFGD;
212
213        if ((offset & 0x3) == 0)
214                offset = 0x2;
215        else
216                offset = 0x0;
217
218        RM9K_WRITE(address_reg, address);
219        RM9K_WRITE_16(data_reg + offset, val);
220
221        return PCIBIOS_SUCCESSFUL;
222}
223
224static int titan_ht_config_write_byte(struct pci_dev *device,
225                                             int offset, u8 val)
226{
227        int dev, bus, func;
228        uint32_t address_reg, data_reg;
229        uint32_t address;
230        int offset1;
231
232        bus = device->bus->number;
233        dev = PCI_SLOT(device->devfn);
234        func = PCI_FUNC(device->devfn);
235
236        if (bus > 2)
237                address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) |
238                                0x80000000 | 0x1;
239        else
240                address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000;
241
242        address_reg = RM9000x2_OCD_HTCFGA;
243        data_reg =  RM9000x2_OCD_HTCFGD;
244
245        RM9K_WRITE(address_reg, address);
246
247        if ((offset & 0x3) == 0) {
248             offset1 = 0x3;
249        }
250        if ((offset & 0x3) == 1) {
251             offset1 = 0x2;
252        }
253        if ((offset & 0x3) == 2) {
254             offset1 = 0x1;
255        }
256        if ((offset & 0x3) == 3) {
257            offset1 = 0x0;
258        }
259
260        RM9K_WRITE_8(data_reg + offset1, val);
261        return PCIBIOS_SUCCESSFUL;
262}
263
264
265static void titan_pcibios_set_master(struct pci_dev *dev)
266{
267        u16 cmd;
268        int bus = dev->bus->number;
269
270	if (check_titan_htlink())
271            titan_ht_config_read_word(dev, PCI_COMMAND, &cmd);
272
273	cmd |= PCI_COMMAND_MASTER;
274
275	if (check_titan_htlink())
276            titan_ht_config_write_word(dev, PCI_COMMAND, cmd);
277}
278
279
280int pcibios_enable_resources(struct pci_dev *dev)
281{
282        u16 cmd, old_cmd;
283        u8 tmp1;
284        int idx;
285        struct resource *r;
286        int bus = dev->bus->number;
287
288	if (check_titan_htlink())
289            titan_ht_config_read_word(dev, PCI_COMMAND, &cmd);
290
291	old_cmd = cmd;
292        for (idx = 0; idx < 6; idx++) {
293                r = &dev->resource[idx];
294                if (!r->start && r->end) {
295                        printk(KERN_ERR
296                               "PCI: Device %s not available because of "
297                               "resource collisions\n", pci_name(dev));
298                        return -EINVAL;
299                }
300                if (r->flags & IORESOURCE_IO)
301                        cmd |= PCI_COMMAND_IO;
302                if (r->flags & IORESOURCE_MEM)
303                        cmd |= PCI_COMMAND_MEMORY;
304        }
305        if (cmd != old_cmd) {
306		if (check_titan_htlink())
307                   titan_ht_config_write_word(dev, PCI_COMMAND, cmd);
308	}
309
310	if (check_titan_htlink())
311		titan_ht_config_read_byte(dev, PCI_CACHE_LINE_SIZE, &tmp1);
312
313	if (tmp1 != 8) {
314                printk(KERN_WARNING "PCI setting cache line size to 8 from "
315                       "%d\n", tmp1);
316	}
317
318	if (check_titan_htlink())
319		titan_ht_config_write_byte(dev, PCI_CACHE_LINE_SIZE, 8);
320
321	if (check_titan_htlink())
322		titan_ht_config_read_byte(dev, PCI_LATENCY_TIMER, &tmp1);
323
324	if (tmp1 < 32 || tmp1 == 0xff) {
325                printk(KERN_WARNING "PCI setting latency timer to 32 from %d\n",
326                       tmp1);
327	}
328
329	if (check_titan_htlink())
330		titan_ht_config_write_byte(dev, PCI_LATENCY_TIMER, 32);
331
332	return 0;
333}
334
335
336int pcibios_enable_device(struct pci_dev *dev, int mask)
337{
338        return pcibios_enable_resources(dev);
339}
340
341resource_size_t pcibios_align_resource(void *data, const struct resource *res,
342				resource_size_t size, resource_size_t align)
343{
344        struct pci_dev *dev = data;
345	resource_size_t start = res->start;
346
347        if (res->flags & IORESOURCE_IO) {
348                /* We need to avoid collisions with `mirrored' VGA ports
349                   and other strange ISA hardware, so we always want the
350                   addresses kilobyte aligned.  */
351                if (size > 0x100) {
352                        printk(KERN_ERR "PCI: I/O Region %s/%d too large"
353                               " (%ld bytes)\n", pci_name(dev),
354                                dev->resource - res, size);
355                }
356
357                start = (start + 1024 - 1) & ~(1024 - 1);
358        }
359
360	return start;
361}
362
363struct pci_ops titan_pci_ops = {
364        titan_ht_config_read_byte,
365        titan_ht_config_read_word,
366        titan_ht_config_read_dword,
367        titan_ht_config_write_byte,
368        titan_ht_config_write_word,
369        titan_ht_config_write_dword
370};
371
372void __init pcibios_fixup_bus(struct pci_bus *c)
373{
374        titan_ht_pcibios_fixup_bus(c);
375}
376
377void __init pcibios_init(void)
378{
379
380        /* Reset PCI I/O and PCI MEM values */
381        ioport_resource.start = 0xe0000000;
382        ioport_resource.end   = 0xe0000000 + 0x20000000 - 1;
383        iomem_resource.start  = 0xc0000000;
384        iomem_resource.end    = 0xc0000000 + 0x20000000 - 1;
385
386        pci_scan_bus(2, &titan_pci_ops, NULL);
387        pci_scan_bus(3, &titan_pci_ops, NULL);
388}
389
390/*
391 * for parsing "pci=" kernel boot arguments.
392 */
393char *pcibios_setup(char *str)
394{
395        printk(KERN_INFO "rr: pcibios_setup\n");
396        /* Nothing to do for now.  */
397
398        return str;
399}
400
401unsigned __init int pcibios_assign_all_busses(void)
402{
403        /* We want to use the PCI bus detection done by PMON */
404        return 0;
405}
406
407#endif /* CONFIG_HYPERTRANSPORT */
408