Merge branch 'master' of /home/sam/kernel/linux-2.6/
[pandora-kernel.git] / arch / m68k / atari / hades-pci.c
1 /*
2  * hades-pci.c - Hardware specific PCI BIOS functions the Hades Atari clone.
3  *
4  * Written by Wout Klaren.
5  */
6
7 #include <linux/init.h>
8 #include <linux/kernel.h>
9 #include <asm/io.h>
10
11 #if 0
12 # define DBG_DEVS(args)         printk args
13 #else
14 # define DBG_DEVS(args)
15 #endif
16
17 #if defined(CONFIG_PCI) && defined(CONFIG_HADES)
18
19 #include <linux/slab.h>
20 #include <linux/mm.h>
21 #include <linux/pci.h>
22
23 #include <asm/atarihw.h>
24 #include <asm/atariints.h>
25 #include <asm/byteorder.h>
26 #include <asm/pci.h>
27
28 #define HADES_MEM_BASE          0x80000000
29 #define HADES_MEM_SIZE          0x20000000
30 #define HADES_CONFIG_BASE       0xA0000000
31 #define HADES_CONFIG_SIZE       0x10000000
32 #define HADES_IO_BASE           0xB0000000
33 #define HADES_IO_SIZE           0x10000000
34 #define HADES_VIRT_IO_SIZE      0x00010000      /* Only 64k is remapped and actually used. */
35
36 #define N_SLOTS                         4                       /* Number of PCI slots. */
37
38 static const char pci_mem_name[] = "PCI memory space";
39 static const char pci_io_name[] = "PCI I/O space";
40 static const char pci_config_name[] = "PCI config space";
41
42 static struct resource config_space = {
43     .name = pci_config_name,
44     .start = HADES_CONFIG_BASE,
45     .end = HADES_CONFIG_BASE + HADES_CONFIG_SIZE - 1
46 };
47 static struct resource io_space = {
48     .name = pci_io_name,
49     .start = HADES_IO_BASE,
50     .end = HADES_IO_BASE + HADES_IO_SIZE - 1
51 };
52
53 static const unsigned long pci_conf_base_phys[] = {
54     0xA0080000, 0xA0040000, 0xA0020000, 0xA0010000
55 };
56 static unsigned long pci_conf_base_virt[N_SLOTS];
57 static unsigned long pci_io_base_virt;
58
59 /*
60  * static void *mk_conf_addr(unsigned char bus, unsigned char device_fn,
61  *                           unsigned char where)
62  *
63  * Calculate the address of the PCI configuration area of the given
64  * device.
65  *
66  * BUG: boards with multiple functions are probably not correctly
67  * supported.
68  */
69
70 static void *mk_conf_addr(struct pci_dev *dev, int where)
71 {
72         int device = dev->devfn >> 3, function = dev->devfn & 7;
73         void *result;
74
75         DBG_DEVS(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x, pci_addr=0x%p)\n",
76                   dev->bus->number, dev->devfn, where, pci_addr));
77
78         if (device > 3)
79         {
80                 DBG_DEVS(("mk_conf_addr: device (%d) > 3, returning NULL\n", device));
81                 return NULL;
82         }
83
84         if (dev->bus->number != 0)
85         {
86                 DBG_DEVS(("mk_conf_addr: bus (%d) > 0, returning NULL\n", device));
87                 return NULL;
88         }
89
90         result = (void *) (pci_conf_base_virt[device] | (function << 8) | (where));
91         DBG_DEVS(("mk_conf_addr: returning pci_addr 0x%lx\n", (unsigned long) result));
92         return result;
93 }
94
95 static int hades_read_config_byte(struct pci_dev *dev, int where, u8 *value)
96 {
97         volatile unsigned char *pci_addr;
98
99         *value = 0xff;
100
101         if ((pci_addr = (unsigned char *) mk_conf_addr(dev, where)) == NULL)
102                 return PCIBIOS_DEVICE_NOT_FOUND;
103
104         *value = *pci_addr;
105
106         return PCIBIOS_SUCCESSFUL;
107 }
108
109 static int hades_read_config_word(struct pci_dev *dev, int where, u16 *value)
110 {
111         volatile unsigned short *pci_addr;
112
113         *value = 0xffff;
114
115         if (where & 0x1)
116                 return PCIBIOS_BAD_REGISTER_NUMBER;
117
118         if ((pci_addr = (unsigned short *) mk_conf_addr(dev, where)) == NULL)
119                 return PCIBIOS_DEVICE_NOT_FOUND;
120
121         *value = le16_to_cpu(*pci_addr);
122
123         return PCIBIOS_SUCCESSFUL;
124 }
125
126 static int hades_read_config_dword(struct pci_dev *dev, int where, u32 *value)
127 {
128         volatile unsigned int *pci_addr;
129         unsigned char header_type;
130         int result;
131
132         *value = 0xffffffff;
133
134         if (where & 0x3)
135                 return PCIBIOS_BAD_REGISTER_NUMBER;
136
137         if ((pci_addr = (unsigned int *) mk_conf_addr(dev, where)) == NULL)
138                 return PCIBIOS_DEVICE_NOT_FOUND;
139
140         *value = le32_to_cpu(*pci_addr);
141
142         /*
143          * Check if the value is an address on the bus. If true, add the
144          * base address of the PCI memory or PCI I/O area on the Hades.
145          */
146
147         if ((result = hades_read_config_byte(dev, PCI_HEADER_TYPE,
148                                              &header_type)) != PCIBIOS_SUCCESSFUL)
149                 return result;
150
151         if (((where >= PCI_BASE_ADDRESS_0) && (where <= PCI_BASE_ADDRESS_1)) ||
152             ((header_type != PCI_HEADER_TYPE_BRIDGE) && ((where >= PCI_BASE_ADDRESS_2) &&
153                                                          (where <= PCI_BASE_ADDRESS_5))))
154         {
155                 if ((*value & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO)
156                 {
157                         /*
158                          * Base address register that contains an I/O address. If the
159                          * address is valid on the Hades (0 <= *value < HADES_VIRT_IO_SIZE),
160                          * add 'pci_io_base_virt' to the value.
161                          */
162
163                         if (*value < HADES_VIRT_IO_SIZE)
164                                 *value += pci_io_base_virt;
165                 }
166                 else
167                 {
168                         /*
169                          * Base address register that contains an memory address. If the
170                          * address is valid on the Hades (0 <= *value < HADES_MEM_SIZE),
171                          * add HADES_MEM_BASE to the value.
172                          */
173
174                         if (*value == 0)
175                         {
176                                 /*
177                                  * Base address is 0. Test if this base
178                                  * address register is used.
179                                  */
180
181                                 *pci_addr = 0xffffffff;
182                                 if (*pci_addr != 0)
183                                 {
184                                         *pci_addr = *value;
185                                         if (*value < HADES_MEM_SIZE)
186                                                 *value += HADES_MEM_BASE;
187                                 }
188                         }
189                         else
190                         {
191                                 if (*value < HADES_MEM_SIZE)
192                                         *value += HADES_MEM_BASE;
193                         }
194                 }
195         }
196
197         return PCIBIOS_SUCCESSFUL;
198 }
199
200 static int hades_write_config_byte(struct pci_dev *dev, int where, u8 value)
201 {
202         volatile unsigned char *pci_addr;
203
204         if ((pci_addr = (unsigned char *) mk_conf_addr(dev, where)) == NULL)
205                 return PCIBIOS_DEVICE_NOT_FOUND;
206
207         *pci_addr = value;
208
209         return PCIBIOS_SUCCESSFUL;
210 }
211
212 static int hades_write_config_word(struct pci_dev *dev, int where, u16 value)
213 {
214         volatile unsigned short *pci_addr;
215
216         if ((pci_addr = (unsigned short *) mk_conf_addr(dev, where)) == NULL)
217                 return PCIBIOS_DEVICE_NOT_FOUND;
218
219         *pci_addr = cpu_to_le16(value);
220
221         return PCIBIOS_SUCCESSFUL;
222 }
223
224 static int hades_write_config_dword(struct pci_dev *dev, int where, u32 value)
225 {
226         volatile unsigned int *pci_addr;
227         unsigned char header_type;
228         int result;
229
230         if ((pci_addr = (unsigned int *) mk_conf_addr(dev, where)) == NULL)
231                 return PCIBIOS_DEVICE_NOT_FOUND;
232
233         /*
234          * Check if the value is an address on the bus. If true, subtract the
235          * base address of the PCI memory or PCI I/O area on the Hades.
236          */
237
238         if ((result = hades_read_config_byte(dev, PCI_HEADER_TYPE,
239                                              &header_type)) != PCIBIOS_SUCCESSFUL)
240                 return result;
241
242         if (((where >= PCI_BASE_ADDRESS_0) && (where <= PCI_BASE_ADDRESS_1)) ||
243             ((header_type != PCI_HEADER_TYPE_BRIDGE) && ((where >= PCI_BASE_ADDRESS_2) &&
244                                                          (where <= PCI_BASE_ADDRESS_5))))
245         {
246                 if ((value & PCI_BASE_ADDRESS_SPACE) ==
247                     PCI_BASE_ADDRESS_SPACE_IO)
248                 {
249                         /*
250                          * I/O address. Check if the address is valid address on
251                          * the Hades (pci_io_base_virt <= value < pci_io_base_virt +
252                          * HADES_VIRT_IO_SIZE) or if the value is 0xffffffff. If not
253                          * true do not write the base address register. If it is a
254                          * valid base address subtract 'pci_io_base_virt' from the value.
255                          */
256
257                         if ((value >= pci_io_base_virt) && (value < (pci_io_base_virt +
258                                                                                                                  HADES_VIRT_IO_SIZE)))
259                                 value -= pci_io_base_virt;
260                         else
261                         {
262                                 if (value != 0xffffffff)
263                                         return PCIBIOS_SET_FAILED;
264                         }
265                 }
266                 else
267                 {
268                         /*
269                          * Memory address. Check if the address is valid address on
270                          * the Hades (HADES_MEM_BASE <= value < HADES_MEM_BASE + HADES_MEM_SIZE) or
271                          * if the value is 0xffffffff. If not true do not write
272                          * the base address register. If it is a valid base address
273                          * subtract HADES_MEM_BASE from the value.
274                          */
275
276                         if ((value >= HADES_MEM_BASE) && (value < (HADES_MEM_BASE + HADES_MEM_SIZE)))
277                                 value -= HADES_MEM_BASE;
278                         else
279                         {
280                                 if (value != 0xffffffff)
281                                         return PCIBIOS_SET_FAILED;
282                         }
283                 }
284         }
285
286         *pci_addr = cpu_to_le32(value);
287
288         return PCIBIOS_SUCCESSFUL;
289 }
290
291 /*
292  * static inline void hades_fixup(void)
293  *
294  * Assign IRQ numbers as used by Linux to the interrupt pins
295  * of the PCI cards.
296  */
297
298 static void __init hades_fixup(int pci_modify)
299 {
300         char irq_tab[4] = {
301                 [0] = IRQ_TT_MFP_IO0,           /* Slot 0. */
302                 [1] = IRQ_TT_MFP_IO1,           /* Slot 1. */
303                 [2] = IRQ_TT_MFP_SCC,           /* Slot 2. */
304                 [3] = IRQ_TT_MFP_SCSIDMA        /* Slot 3. */
305         };
306         struct pci_dev *dev = NULL;
307         unsigned char slot;
308
309         /*
310          * Go through all devices, fixing up irqs as we see fit:
311          */
312
313         while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL)
314         {
315                 if (dev->class >> 16 != PCI_BASE_CLASS_BRIDGE)
316                 {
317                         slot = PCI_SLOT(dev->devfn);    /* Determine slot number. */
318                         dev->irq = irq_tab[slot];
319                         if (pci_modify)
320                                 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
321                 }
322         }
323 }
324
325 /*
326  * static void hades_conf_device(struct pci_dev *dev)
327  *
328  * Machine dependent Configure the given device.
329  *
330  * Parameters:
331  *
332  * dev          - the pci device.
333  */
334
335 static void __init hades_conf_device(struct pci_dev *dev)
336 {
337         pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 0);
338 }
339
340 static struct pci_ops hades_pci_ops = {
341         .read_byte =    hades_read_config_byte,
342         .read_word =    hades_read_config_word,
343         .read_dword =   hades_read_config_dword,
344         .write_byte =   hades_write_config_byte,
345         .write_word =   hades_write_config_word,
346         .write_dword =  hades_write_config_dword
347 };
348
349 /*
350  * struct pci_bus_info *init_hades_pci(void)
351  *
352  * Machine specific initialisation:
353  *
354  * - Allocate and initialise a 'pci_bus_info' structure
355  * - Initialise hardware
356  *
357  * Result: pointer to 'pci_bus_info' structure.
358  */
359
360 struct pci_bus_info * __init init_hades_pci(void)
361 {
362         struct pci_bus_info *bus;
363         int i;
364
365         /*
366          * Remap I/O and configuration space.
367          */
368
369         pci_io_base_virt = (unsigned long) ioremap(HADES_IO_BASE, HADES_VIRT_IO_SIZE);
370
371         for (i = 0; i < N_SLOTS; i++)
372                 pci_conf_base_virt[i] = (unsigned long) ioremap(pci_conf_base_phys[i], 0x10000);
373
374         /*
375          * Allocate memory for bus info structure.
376          */
377
378         bus = kmalloc(sizeof(struct pci_bus_info), GFP_KERNEL);
379         if (!bus)
380                 return NULL;
381         memset(bus, 0, sizeof(struct pci_bus_info));
382
383         /*
384          * Claim resources. The m68k has no separate I/O space, both
385          * PCI memory space and PCI I/O space are in memory space. Therefore
386          * the I/O resources are requested in memory space as well.
387          */
388
389         if (request_resource(&iomem_resource, &config_space) != 0)
390         {
391                 kfree(bus);
392                 return NULL;
393         }
394
395         if (request_resource(&iomem_resource, &io_space) != 0)
396         {
397                 release_resource(&config_space);
398                 kfree(bus);
399                 return NULL;
400         }
401
402         bus->mem_space.start = HADES_MEM_BASE;
403         bus->mem_space.end = HADES_MEM_BASE + HADES_MEM_SIZE - 1;
404         bus->mem_space.name = pci_mem_name;
405 #if 1
406         if (request_resource(&iomem_resource, &bus->mem_space) != 0)
407         {
408                 release_resource(&io_space);
409                 release_resource(&config_space);
410                 kfree(bus);
411                 return NULL;
412         }
413 #endif
414         bus->io_space.start = pci_io_base_virt;
415         bus->io_space.end = pci_io_base_virt + HADES_VIRT_IO_SIZE - 1;
416         bus->io_space.name = pci_io_name;
417 #if 1
418         if (request_resource(&ioport_resource, &bus->io_space) != 0)
419         {
420                 release_resource(&bus->mem_space);
421                 release_resource(&io_space);
422                 release_resource(&config_space);
423                 kfree(bus);
424                 return NULL;
425         }
426 #endif
427         /*
428          * Set hardware dependent functions.
429          */
430
431         bus->m68k_pci_ops = &hades_pci_ops;
432         bus->fixup = hades_fixup;
433         bus->conf_device = hades_conf_device;
434
435         /*
436          * Select high to low edge for PCI interrupts.
437          */
438
439         tt_mfp.active_edge &= ~0x27;
440
441         return bus;
442 }
443 #endif