www.usr.com/support/gpl/USR9113_release1.0.tar.gz
[bcm963xx.git] / kernel / linux / arch / mips / pci / pci-hplj.c
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 Ralf Baechle
9  */
10 #include <linux/kernel.h>
11 #include <linux/init.h>
12 #include <linux/pci.h>
13 #include <linux/types.h>
14 #include <asm/byteorder.h>
15 #include <asm/pci_channel.h>
16 #include <asm/hp-lj/asic.h>
17
18 static volatile u32 *pci_config_address_reg = (volatile u32 *) 0xfdead000;
19 static volatile u32 *pci_config_data_reg = (volatile u32 *) 0xfdead000;
20
21
22
23 #define cfgaddr(dev, where) (((dev->bus->number & 0xff) << 0x10) |  \
24                              ((dev->devfn & 0xff) << 0x08) |        \
25                              (where & 0xfc))
26
27 /*
28  * We can't address 8 and 16 bit words directly.  Instead we have to
29  * read/write a 32bit word and mask/modify the data we actually want.
30  */
31 static int pcimt_read_config_byte(struct pci_dev *dev,
32                                   int where, unsigned char *val)
33 {
34         *pci_config_address_reg = cfgaddr(dev, where);
35         *val =
36             (le32_to_cpu(*pci_config_data_reg) >> ((where & 3) << 3)) &
37             0xff;
38         //printk("pci_read_byte 0x%x == 0x%x\n", where, *val);
39         return PCIBIOS_SUCCESSFUL;
40 }
41
42 static int pcimt_read_config_word(struct pci_dev *dev,
43                                   int where, unsigned short *val)
44 {
45         if (where & 1)
46                 return PCIBIOS_BAD_REGISTER_NUMBER;
47         *pci_config_address_reg = cfgaddr(dev, where);
48         *val =
49             (le32_to_cpu(*pci_config_data_reg) >> ((where & 3) << 3)) &
50             0xffff;
51         //printk("pci_read_word 0x%x == 0x%x\n", where, *val);
52         return PCIBIOS_SUCCESSFUL;
53 }
54
55 int pcimt_read_config_dword(struct pci_dev *dev,
56                             int where, unsigned int *val)
57 {
58         if (where & 3)
59                 return PCIBIOS_BAD_REGISTER_NUMBER;
60         *pci_config_address_reg = cfgaddr(dev, where);
61         *val = le32_to_cpu(*pci_config_data_reg);
62         //printk("pci_read_dword 0x%x == 0x%x\n", where, *val);
63         return PCIBIOS_SUCCESSFUL;
64 }
65
66 static int pcimt_write_config_byte(struct pci_dev *dev,
67                                    int where, unsigned char val)
68 {
69         *pci_config_address_reg = cfgaddr(dev, where);
70         *(volatile u8 *) (((int) pci_config_data_reg) + (where & 3)) = val;
71         //printk("pci_write_byte 0x%x = 0x%x\n", where, val);
72         return PCIBIOS_SUCCESSFUL;
73 }
74
75 static int pcimt_write_config_word(struct pci_dev *dev,
76                                    int where, unsigned short val)
77 {
78         if (where & 1)
79                 return PCIBIOS_BAD_REGISTER_NUMBER;
80         *pci_config_address_reg = cfgaddr(dev, where);
81         *(volatile u16 *) (((int) pci_config_data_reg) + (where & 2)) =
82             le16_to_cpu(val);
83         //printk("pci_write_word 0x%x = 0x%x\n", where, val);
84         return PCIBIOS_SUCCESSFUL;
85 }
86
87 int pcimt_write_config_dword(struct pci_dev *dev,
88                              int where, unsigned int val)
89 {
90         if (where & 3)
91                 return PCIBIOS_BAD_REGISTER_NUMBER;
92         *pci_config_address_reg = cfgaddr(dev, where);
93         *pci_config_data_reg = le32_to_cpu(val);
94         //printk("pci_write_dword 0x%x = 0x%x\n", where, val);
95         return PCIBIOS_SUCCESSFUL;
96 }
97
98
99
100 struct pci_ops hp_pci_ops = {
101         pcimt_read_config_byte,
102         pcimt_read_config_word,
103         pcimt_read_config_dword,
104         pcimt_write_config_byte,
105         pcimt_write_config_word,
106         pcimt_write_config_dword
107 };
108
109
110 struct pci_controller hp_controller = {
111         .pci_ops        = &hp_pci_ops,
112         .io_resource    = &ioport_resource,
113         .mem_resource   = &iomem_resource,
114 };
115
116 int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
117 {
118         switch (slot) {
119         case 2:
120                 return 3;
121                 break;
122         case 3:
123                 return 4;
124                 break;
125         case 4:
126                 return 5;
127                 break;
128         default:
129                 break;
130         }
131 }
132
133 #define IO_MEM_LOGICAL_START   0x3e000000
134 #define IO_MEM_LOGICAL_END     0x3fefffff
135
136 #define IO_PORT_LOGICAL_START  0x3ff00000
137 #define IO_PORT_LOGICAL_END    0x3fffffff
138
139
140 #define IO_MEM_VIRTUAL_OFFSET  0xb0000000
141 #define IO_PORT_VIRTUAL_OFFSET 0xb0000000
142
143 #define ONE_MEG   (1024 * 1024)
144
145 void __init pci_setup(void)
146 {
147         u32 pci_regs_base_offset = 0xfdead000;
148
149         switch (GetAsicId()) {
150         case AndrosAsic:
151                 pci_regs_base_offset = 0xbff80000;
152                 break;
153         case HarmonyAsic:
154                 pci_regs_base_offset = 0xbff70000;
155                 break;
156         default:
157                 printk("ERROR: PCI does not support %s Asic\n",
158                        GetAsicName());
159                 while (1);
160                 break;
161         }
162
163         // set bus stat/command reg
164         // REVIST this setting may need vary depending on the hardware
165         *((volatile unsigned int *) (pci_regs_base_offset | 0x0004)) =
166             0x38000007;
167
168
169         iomem_resource.start =
170             IO_MEM_LOGICAL_START + IO_MEM_VIRTUAL_OFFSET;
171         iomem_resource.end = IO_MEM_LOGICAL_END + IO_MEM_VIRTUAL_OFFSET;
172
173         ioport_resource.start =
174             IO_PORT_LOGICAL_START + IO_PORT_VIRTUAL_OFFSET;
175         ioport_resource.end = IO_PORT_LOGICAL_END + IO_PORT_VIRTUAL_OFFSET;
176
177         // KLUDGE (mips_io_port_base is screwed up, we've got to work around it here)
178         // by letting both low (illegal) and high (legal) addresses appear in pci io space
179         ioport_resource.start = 0x0;
180
181         set_io_port_base(IO_PORT_LOGICAL_START + IO_PORT_VIRTUAL_OFFSET);
182
183         // map the PCI address space
184         // global map - all levels & processes can access
185         // except that the range is outside user space
186         // parameters: lo0, lo1, hi, pagemask
187         // lo indicates physical page, hi indicates virtual address
188         add_wired_entry((IO_MEM_LOGICAL_START >> 6) | 0x17,
189                         ((IO_MEM_LOGICAL_START +
190                           (16 * ONE_MEG)) >> 6) | 0x17, 0xee000000,
191                         PM_16M);
192
193
194         // These are used in pci r/w routines so need to preceed bus scan
195         pci_config_data_reg = (u32 *) (((u32) mips_io_port_base) | 0xcfc);
196         pci_config_address_reg =
197             (u32 *) (((u32) pci_regs_base_offset) | 0xcf8);
198 }