ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / 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 void __init pcibios_fixup_irqs(void)
117 {
118         struct pci_dev *dev = NULL;
119         int slot_num;
120
121         while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
122                 slot_num = PCI_SLOT(dev->devfn);
123                 switch (slot_num) {
124                 case 2:
125                         dev->irq = 3;
126                         break;
127                 case 3:
128                         dev->irq = 4;
129                         break;
130                 case 4:
131                         dev->irq = 5;
132                         break;
133                 default:
134                         break;
135                 }
136         }
137 }
138
139 #define IO_MEM_LOGICAL_START   0x3e000000
140 #define IO_MEM_LOGICAL_END     0x3fefffff
141
142 #define IO_PORT_LOGICAL_START  0x3ff00000
143 #define IO_PORT_LOGICAL_END    0x3fffffff
144
145
146 #define IO_MEM_VIRTUAL_OFFSET  0xb0000000
147 #define IO_PORT_VIRTUAL_OFFSET 0xb0000000
148
149 #define ONE_MEG   (1024 * 1024)
150
151 void __init pci_setup(void)
152 {
153         u32 pci_regs_base_offset = 0xfdead000;
154
155         switch (GetAsicId()) {
156         case AndrosAsic:
157                 pci_regs_base_offset = 0xbff80000;
158                 break;
159         case HarmonyAsic:
160                 pci_regs_base_offset = 0xbff70000;
161                 break;
162         default:
163                 printk("ERROR: PCI does not support %s Asic\n",
164                        GetAsicName());
165                 while (1);
166                 break;
167         }
168
169         // set bus stat/command reg
170         // REVIST this setting may need vary depending on the hardware
171         *((volatile unsigned int *) (pci_regs_base_offset | 0x0004)) =
172             0x38000007;
173
174
175         iomem_resource.start =
176             IO_MEM_LOGICAL_START + IO_MEM_VIRTUAL_OFFSET;
177         iomem_resource.end = IO_MEM_LOGICAL_END + IO_MEM_VIRTUAL_OFFSET;
178
179         ioport_resource.start =
180             IO_PORT_LOGICAL_START + IO_PORT_VIRTUAL_OFFSET;
181         ioport_resource.end = IO_PORT_LOGICAL_END + IO_PORT_VIRTUAL_OFFSET;
182
183         // KLUDGE (mips_io_port_base is screwed up, we've got to work around it here)
184         // by letting both low (illegal) and high (legal) addresses appear in pci io space
185         ioport_resource.start = 0x0;
186
187         set_io_port_base(IO_PORT_LOGICAL_START + IO_PORT_VIRTUAL_OFFSET);
188
189         // map the PCI address space
190         // global map - all levels & processes can access
191         // except that the range is outside user space
192         // parameters: lo0, lo1, hi, pagemask
193         // lo indicates physical page, hi indicates virtual address
194         add_wired_entry((IO_MEM_LOGICAL_START >> 6) | 0x17,
195                         ((IO_MEM_LOGICAL_START +
196                           (16 * ONE_MEG)) >> 6) | 0x17, 0xee000000,
197                         PM_16M);
198
199
200         // These are used in pci r/w routines so need to preceed bus scan
201         pci_config_data_reg = (u32 *) (((u32) mips_io_port_base) | 0xcfc);
202         pci_config_address_reg =
203             (u32 *) (((u32) pci_regs_base_offset) | 0xcf8);
204 }