more changes on original files
[linux-2.4.git] / arch / ppc64 / kernel / pSeries_pci.c
1 /*
2  * pSeries_pci.c
3  *
4  * Copyright (C) 2001 Dave Engebretsen, IBM Corporation
5  *
6  * pSeries specific routines for PCI.
7  * 
8  * Based on code from pci.c and chrp_pci.c
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *    
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  * 
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
23  */
24
25 #include <linux/kernel.h>
26 #include <linux/pci.h>
27 #include <linux/delay.h>
28 #include <linux/string.h>
29 #include <linux/init.h>
30 #include <linux/bootmem.h>
31
32 #include <asm/io.h>
33 #include <asm/pgtable.h>
34 #include <asm/irq.h>
35 #include <asm/prom.h>
36 #include <asm/machdep.h>
37 #include <asm/init.h>
38 #include <asm/pci-bridge.h>
39 #include <asm/ppcdebug.h>
40 #include <asm/naca.h>
41 #include <asm/pci_dma.h>
42
43 #include "xics.h"
44 #include "open_pic.h"
45 #include "pci.h"
46
47 extern struct device_node *allnodes;
48
49 /*******************************************************************
50  * Forward declares of prototypes. 
51  *******************************************************************/
52 unsigned long find_and_init_phbs(void);
53 struct pci_controller* alloc_phb(struct device_node *dev, char *model, unsigned int addr_size_words) ;
54 void pSeries_pcibios_fixup(void);
55 static int rtas_fake_read(struct device_node *dn, int offset, int nbytes, unsigned long *returnval);
56
57 /* RTAS tokens */
58 static int read_pci_config;
59 static int write_pci_config;
60 static int ibm_read_pci_config;
61 static int ibm_write_pci_config;
62
63 static int s7a_workaround;
64
65 /******************************************************************************
66  *
67  * pSeries I/O Operations to access the PCI configuration space.
68  *
69  *****************************************************************************/
70 #define RTAS_PCI_READ_OP(size, type, nbytes) \
71 int __chrp \
72 rtas_read_config_##size(struct device_node *dn, int offset, type val) {  \
73         unsigned long returnval = ~0L; \
74         unsigned long buid; \
75         unsigned int addr; \
76         int ret; \
77          \
78         if (dn == NULL) { \
79                 ret = -2; \
80         } else if (dn->status) { \
81                 ret = -1; \
82         } else { \
83                 addr = (dn->busno << 16) | (dn->devfn << 8) | offset; \
84                 buid = dn->phb->buid; \
85                 if (buid) { \
86                         ret = rtas_call(ibm_read_pci_config, 4, 2, &returnval, addr, buid >> 32, buid & 0xffffffff, nbytes); \
87                         if (ret < 0 || (returnval == 0xffffffff)) \
88                                ret = rtas_fake_read(dn, offset, nbytes, &returnval); \
89                 } else { \
90                         ret = rtas_call(read_pci_config, 2, 2, &returnval, addr, nbytes); \
91                 } \
92         } \
93         *val = returnval; \
94         return ret; \
95 } \
96 int __chrp \
97 rtas_pci_read_config_##size(struct pci_dev *dev, int offset, type val) {  \
98         struct device_node *dn = pci_device_to_OF_node(dev); \
99         int ret = rtas_read_config_##size(dn, offset, val); \
100         /* udbg_printf("read bus=%x, devfn=%x, ret=%d phb=%lx, dn=%lx\n", dev->bus->number, dev->devfn, ret, dn ? dn->phb : 0, dn); */ \
101         return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; \
102 }
103
104 #define RTAS_PCI_WRITE_OP(size, type, nbytes) \
105 int __chrp \
106 rtas_write_config_##size(struct device_node *dn, int offset, type val) { \
107         unsigned long buid; \
108         unsigned int addr; \
109         int ret; \
110          \
111         if (dn == NULL) { \
112                 ret = -2; \
113         } else if (dn->status) { \
114                 ret = -1; \
115         } else { \
116                 buid = dn->phb->buid; \
117                 addr = (dn->busno << 16) | (dn->devfn << 8) | offset; \
118                 if (buid) { \
119                         ret = rtas_call(ibm_write_pci_config, 5, 1, NULL, addr, buid >> 32, buid & 0xffffffff, nbytes, (ulong) val); \
120                 } else { \
121                         ret = rtas_call(write_pci_config, 3, 1, NULL, addr, nbytes, (ulong)val); \
122                 } \
123         } \
124         return ret; \
125 } \
126 int __chrp \
127 rtas_pci_write_config_##size(struct pci_dev *dev, int offset, type val) { \
128         struct device_node*  dn = pci_device_to_OF_node(dev); \
129         int  ret = rtas_write_config_##size(dn, offset, val); \
130         /* udbg_printf("write bus=%x, devfn=%x, ret=%d phb=%lx, dn=%lx\n", dev->bus->number, dev->devfn, ret, dn ? dn->phb : 0, dn); */ \
131         return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; \
132 }
133
134 RTAS_PCI_READ_OP(byte, u8 *, 1)
135 RTAS_PCI_READ_OP(word, u16 *, 2)
136 RTAS_PCI_READ_OP(dword, u32 *, 4)
137 RTAS_PCI_WRITE_OP(byte, u8, 1)
138 RTAS_PCI_WRITE_OP(word, u16, 2)
139 RTAS_PCI_WRITE_OP(dword, u32, 4)
140
141 struct pci_ops rtas_pci_ops = {
142         rtas_pci_read_config_byte,
143         rtas_pci_read_config_word,
144         rtas_pci_read_config_dword,
145         rtas_pci_write_config_byte,
146         rtas_pci_write_config_word,
147         rtas_pci_write_config_dword,
148 };
149
150 /*
151  * Handle the case where rtas refuses to do a pci config read.
152  * This currently only happens with some PHBs in which case we totally fake
153  * out the values (and call it a speedwagaon -- something we could look up
154  * in the device tree).
155  */
156 static int
157 rtas_fake_read(struct device_node *dn, int offset, int nbytes, unsigned long *returnval)
158 {
159         char *device_type = (char *)get_property(dn, "device_type", 0);
160         u32 *class_code = (u32 *)get_property(dn, "class-code", 0);
161
162         *returnval = ~0;        /* float by default */
163
164         /* udbg_printf("rtas_fake_read dn=%p, offset=0x%02x, nbytes=%d, device_type=%s\n", dn, offset, nbytes, device_type ? device_type : "<none>"); */
165         if (device_type && strcmp(device_type, "pci") != 0)
166                 return -3;      /* Not a phb or bridge */
167
168         /* NOTE: class_code != NULL => EADS pci bridge.  Else a PHB */
169         if (nbytes == 1) {
170                 if (offset == PCI_HEADER_TYPE)
171                         *returnval = 0x80;      /* multifunction */
172                 else if (offset == PCI_INTERRUPT_PIN || offset == PCI_INTERRUPT_LINE)
173                         *returnval = 0;
174         } else if (nbytes == 2) {
175                 if (offset == PCI_SUBSYSTEM_VENDOR_ID || offset == PCI_SUBSYSTEM_ID)
176                         *returnval = 0;
177                 else if (offset == PCI_COMMAND)
178                         *returnval = PCI_COMMAND_PARITY|PCI_COMMAND_MASTER|PCI_COMMAND_MEMORY;
179         } else if (nbytes == 4) {
180                 if (offset == PCI_VENDOR_ID)
181                         *returnval = 0x1014 | ((class_code ? 0x8b : 0x102) << 16); /* a phb */
182                 else if (offset == PCI_REVISION_ID)
183                         *returnval = (class_code ? PCI_CLASS_BRIDGE_PCI : PCI_CLASS_BRIDGE_HOST) << 16; /* revs are zero */
184                 else if ((offset >= PCI_BASE_ADDRESS_0 && offset <= PCI_BASE_ADDRESS_5) || offset == PCI_ROM_ADDRESS)
185                         *returnval = 0;
186         }
187
188         /* printk("fake: %s nbytes=%d, offset=%lx ret=%lx\n", class_code ? "EADS" : "PHB", nbytes, offset, *returnval); */
189         return 0;
190 }
191
192 /******************************************************************
193  * pci_read_irq_line
194  *
195  * Reads the Interrupt Pin to determine if interrupt is use by card.
196  * If the interrupt is used, then gets the interrupt line from the 
197  * openfirmware and sets it in the pci_dev and pci_config line.
198  *
199  ******************************************************************/
200 int 
201 pci_read_irq_line(struct pci_dev *Pci_Dev)
202 {
203         u8 InterruptPin;
204         struct device_node *Node;
205
206         pci_read_config_byte(Pci_Dev, PCI_INTERRUPT_PIN, &InterruptPin);
207         if (InterruptPin == 0) {
208                 PPCDBG(PPCDBG_BUSWALK,"\tDevice: %s No Interrupt used by device.\n",Pci_Dev->slot_name);
209                 return 0;       
210         }
211
212         Node = pci_device_to_OF_node(Pci_Dev);
213         if ( Node == NULL) { 
214                 PPCDBG(PPCDBG_BUSWALK,"\tDevice: %s Device Node not found.\n",Pci_Dev->slot_name);
215                 return -1;      
216         }
217         if (Node->n_intrs == 0)         {
218                 PPCDBG(PPCDBG_BUSWALK,"\tDevice: %s No Device OF interrupts defined.\n",Pci_Dev->slot_name);
219                 return -1;      
220         }
221         Pci_Dev->irq = Node->intrs[0].line;
222
223         if (s7a_workaround) {
224                 if (Pci_Dev->irq > 16)
225                         Pci_Dev->irq -= 3;
226         }
227
228         pci_write_config_byte(Pci_Dev, PCI_INTERRUPT_LINE, Pci_Dev->irq);
229         
230         PPCDBG(PPCDBG_BUSWALK,"\tDevice: %s pci_dev->irq = 0x%02X\n",Pci_Dev->slot_name,Pci_Dev->irq);
231         return 0;
232 }
233
234 /******************************************************************
235  * Find all PHBs in the system and initialize a set of data 
236  * structures to represent them.
237  ******************************************************************/
238 unsigned long __init
239 find_and_init_phbs(void)
240 {
241         struct device_node *Pci_Node;
242         struct pci_controller *phb;
243         unsigned int root_addr_size_words = 0, this_addr_size_words = 0;
244         unsigned int this_addr_count = 0, range_stride;
245         unsigned int *ui_ptr = NULL, *ranges;
246         char *model;
247         struct pci_range64 range;
248         struct resource *res;
249         unsigned int memno, rlen, i, index;
250         unsigned int *opprop;
251         int has_isa = 0;
252         PPCDBG(PPCDBG_PHBINIT, "find_and_init_phbs\n"); 
253
254         read_pci_config = rtas_token("read-pci-config");
255         write_pci_config = rtas_token("write-pci-config");
256         ibm_read_pci_config = rtas_token("ibm,read-pci-config");
257         ibm_write_pci_config = rtas_token("ibm,write-pci-config");
258
259         if (naca->interrupt_controller == IC_OPEN_PIC) {
260                 opprop = (unsigned int *)get_property(find_path_device("/"),
261                                 "platform-open-pic", NULL);
262         }
263
264         /* Get the root address word size. */
265         ui_ptr = (unsigned int *) get_property(find_path_device("/"), 
266                                                "#size-cells", NULL);
267         if (ui_ptr) {
268                 root_addr_size_words = *ui_ptr;
269         } else {
270                 PPCDBG(PPCDBG_PHBINIT, "\tget #size-cells failed.\n"); 
271                 return(-1);
272         }
273
274         if (find_type_devices("isa")) {
275                 has_isa = 1;
276                 PPCDBG(PPCDBG_PHBINIT, "\tFound an ISA bus.\n"); 
277         }
278
279         index = 0;
280
281         /******************************************************************
282         * Find all PHB devices and create an object for them.
283         ******************************************************************/
284         for (Pci_Node = find_devices("pci"); Pci_Node != NULL; Pci_Node = Pci_Node->next) {
285                 model = (char *) get_property(Pci_Node, "model", NULL);
286                 if (model != NULL)  {
287                         phb = alloc_phb(Pci_Node, model, root_addr_size_words);
288                         if (phb == NULL) return(-1);
289                 }
290                 else {
291                         continue;
292                 }
293                 
294                 /* Get this node's address word size. */
295                 ui_ptr = (unsigned int *) get_property(Pci_Node, "#size-cells", NULL);
296                 if (ui_ptr)
297                         this_addr_size_words = *ui_ptr;
298                 else
299                         this_addr_size_words = 1;
300                 /* Get this node's address word count. */
301                 ui_ptr = (unsigned int *) get_property(Pci_Node, "#address-cells", NULL);
302                 if (ui_ptr)
303                         this_addr_count = *ui_ptr;
304                 else
305                         this_addr_count = 3;
306                 
307                 range_stride = this_addr_count + root_addr_size_words + this_addr_size_words;
308               
309                 memno = 0;
310                 phb->io_base_phys = 0;
311          
312                 ranges = (unsigned int *) get_property(Pci_Node, "ranges", &rlen);
313                 PPCDBG(PPCDBG_PHBINIT, "\trange_stride = 0x%lx, rlen = 0x%x\n", range_stride, rlen);
314                 
315                 for (i = 0; i < (rlen/sizeof(*ranges)); i+=range_stride) {
316                         /* Put the PCI addr part of the current element into a 
317                          * '64' struct. 
318                          */
319                         range = *((struct pci_range64 *)(ranges + i));
320
321                         /* If this is a '32' element, map into a 64 struct. */
322                         if ((range_stride * sizeof(int)) == 
323                            sizeof(struct pci_range32)) {
324                                 range.parent_addr = 
325                                         (unsigned long)(*(ranges + i + 3));
326                                 range.size = 
327                                         (((unsigned long)(*(ranges + i + 4)))<<32) | 
328                                         (*(ranges + i + 5));
329                         } else {
330                                 range.parent_addr = 
331                                         (((unsigned long)(*(ranges + i + 3)))<<32) | 
332                                         (*(ranges + i + 4));
333                                 range.size = 
334                                         (((unsigned long)(*(ranges + i + 5)))<<32) | 
335                                         (*(ranges + i + 6));
336                         }
337                         
338                         PPCDBG(PPCDBG_PHBINIT, "\trange.parent_addr    = 0x%lx\n", 
339                                range.parent_addr);
340                         PPCDBG(PPCDBG_PHBINIT, "\trange.child_addr.hi  = 0x%lx\n", 
341                                range.child_addr.a_hi);
342                         PPCDBG(PPCDBG_PHBINIT, "\trange.child_addr.mid = 0x%lx\n", 
343                                range.child_addr.a_mid);
344                         PPCDBG(PPCDBG_PHBINIT, "\trange.child_addr.lo  = 0x%lx\n", 
345                                range.child_addr.a_lo);
346                         PPCDBG(PPCDBG_PHBINIT, "\trange.size           = 0x%lx\n", 
347                                range.size);
348
349                         res = NULL;
350                         switch ((range.child_addr.a_hi >> 24) & 0x3) {
351                         case 1:         /* I/O space */
352                                 PPCDBG(PPCDBG_PHBINIT, "\tIO Space\n");
353                                 phb->io_base_phys = range.parent_addr;
354                                 res = &phb->io_resource;
355                                 res->name = Pci_Node->full_name;
356                                 res->flags = IORESOURCE_IO;
357                                 phb->io_base_virt = __ioremap(phb->io_base_phys, range.size, _PAGE_NO_CACHE);
358                                 if (!pci_io_base) {
359                                         pci_io_base = (unsigned long)phb->io_base_virt;
360                                         if (has_isa)
361                                                 isa_io_base = pci_io_base;
362                                 }
363                                 res->start = ((((unsigned long) range.child_addr.a_mid) << 32) | (range.child_addr.a_lo));
364                                 res->start += (unsigned long)phb->io_base_virt - pci_io_base;
365                                 res->end =   res->start + range.size - 1;
366                                 res->parent = NULL;
367                                 res->sibling = NULL;
368                                 res->child = NULL;
369                                 phb->pci_io_offset = range.parent_addr - 
370                                         ((((unsigned long)
371                                            range.child_addr.a_mid) << 32) | 
372                                          (range.child_addr.a_lo));
373                                 PPCDBG(PPCDBG_PHBINIT, "\tpci_io_offset  = 0x%lx\n", 
374                                        phb->pci_io_offset);
375                                 break;
376                         case 2:         /* mem space */
377                                 PPCDBG(PPCDBG_PHBINIT, "\tMem Space\n");
378                                 phb->pci_mem_offset = range.parent_addr - 
379                                         ((((unsigned long)
380                                            range.child_addr.a_mid) << 32) | 
381                                          (range.child_addr.a_lo));
382                                 PPCDBG(PPCDBG_PHBINIT, "\tpci_mem_offset = 0x%lx\n", 
383                                        phb->pci_mem_offset);
384                                 if (memno < sizeof(phb->mem_resources)/sizeof(phb->mem_resources[0])) {
385                                         res = &(phb->mem_resources[memno]);
386                                         ++memno;
387                                         res->name = Pci_Node->full_name;
388                                         res->flags = IORESOURCE_MEM;
389                                         res->start = range.parent_addr;
390                                         res->end =   range.parent_addr + range.size - 1;
391                                         res->parent = NULL;
392                                         res->sibling = NULL;
393                                         res->child = NULL;
394                                 }
395                                 break;
396                         }
397                 }
398                 PPCDBG(PPCDBG_PHBINIT, "\tphb->io_base_phys   = 0x%lx\n", 
399                        phb->io_base_phys); 
400                 PPCDBG(PPCDBG_PHBINIT, "\tphb->pci_mem_offset = 0x%lx\n", 
401                        phb->pci_mem_offset); 
402
403                 if (naca->interrupt_controller == IC_OPEN_PIC) {
404                         int addr = root_addr_size_words * (index + 2) - 1;
405                         openpic_setup_ISU(index, opprop[addr]); 
406                 }
407                 index++;
408         }
409         pci_devs_phb_init();
410         return 0;        /*Success */
411 }
412
413 /******************************************************************
414  *
415  * Allocate and partially initialize a structure to represent a PHB.
416  *
417  ******************************************************************/
418 struct pci_controller *
419 alloc_phb(struct device_node *dev, char *model, unsigned int addr_size_words)
420 {
421         struct pci_controller *phb;
422         unsigned int *ui_ptr = NULL, len;
423         struct reg_property64 reg_struct;
424         struct property *of_prop;
425         int *bus_range;
426         int *buid_vals;
427
428         PPCDBG(PPCDBG_PHBINIT, "alloc_phb: %s\n", dev->full_name); 
429         PPCDBG(PPCDBG_PHBINIT, "\tdev             = 0x%lx\n", dev); 
430         PPCDBG(PPCDBG_PHBINIT, "\tmodel           = 0x%lx\n", model); 
431         PPCDBG(PPCDBG_PHBINIT, "\taddr_size_words = 0x%lx\n", addr_size_words); 
432   
433         /* Found a PHB, now figure out where his registers are mapped. */
434         ui_ptr = (unsigned int *) get_property(dev, "reg", &len);
435         if (ui_ptr == NULL) {
436                 PPCDBG(PPCDBG_PHBINIT, "\tget reg failed.\n"); 
437                 return(NULL);
438         }
439
440         if (addr_size_words == 1) {
441                 reg_struct.address = ((struct reg_property32 *)ui_ptr)->address;
442                 reg_struct.size    = ((struct reg_property32 *)ui_ptr)->size;
443         } else {
444                 reg_struct = *((struct reg_property64 *)ui_ptr);
445         }
446
447         PPCDBG(PPCDBG_PHBINIT, "\treg_struct.address = 0x%lx\n", reg_struct.address);
448         PPCDBG(PPCDBG_PHBINIT, "\treg_struct.size    = 0x%lx\n", reg_struct.size); 
449
450         /***************************************************************
451         * Set chip specific data in the phb, including types & 
452         * register pointers.
453         ***************************************************************/
454
455         /****************************************************************
456         * Python
457         ***************************************************************/
458         if (strstr(model, "Python")) {
459                 PPCDBG(PPCDBG_PHBINIT, "\tCreate python\n");
460                 phb = pci_alloc_pci_controller("PHB PY",phb_type_python);
461                 if (phb == NULL) return NULL;
462         
463                 phb->cfg_addr = (volatile unsigned long *) 
464                         ioremap(reg_struct.address + 0xf8000, PAGE_SIZE);
465                 PPCDBG(PPCDBG_PHBINIT, "\tcfg_addr_r = 0x%lx\n", 
466                        reg_struct.address + 0xf8000);
467                 PPCDBG(PPCDBG_PHBINIT, "\tcfg_addr_v = 0x%lx\n", 
468                        phb->cfg_addr);
469                 phb->cfg_data = (char*)(phb->cfg_addr + 0x02);
470                 phb->phb_regs = (volatile unsigned long *) 
471                         ioremap(reg_struct.address + 0xf7000, PAGE_SIZE);
472                 /* Python's register file is 1 MB in size. */
473                 phb->chip_regs = ioremap(reg_struct.address & ~(0xfffffUL), 
474                                          0x100000); 
475
476                 /* 
477                  * Firmware doesn't always clear this bit which is critical
478                  * for good performance - Anton
479                  */
480                 {
481                         volatile u32 *tmp, i;
482
483 #define PRG_CL_RESET_VALID 0x00010000
484
485                         tmp = (u32 *)((unsigned long)phb->chip_regs + 0xf6030);
486
487                         if (*tmp & PRG_CL_RESET_VALID) {
488                                 printk("Python workaround: ");
489                                 *tmp &= ~PRG_CL_RESET_VALID;
490                                 /*
491                                  * We must read it back for changes to
492                                  * take effect
493                                  */
494                                 i = *tmp;
495                                 printk("reg0: %x\n", i);
496                         }
497                 }
498
499         /***************************************************************
500         * Speedwagon
501         *   include Winnipeg as well for the time being.
502         ***************************************************************/
503         } else if ((strstr(model, "Speedwagon")) || 
504                    (strstr(model, "Winnipeg"))) {
505                 PPCDBG(PPCDBG_PHBINIT, "\tCreate speedwagon\n");
506                 phb = pci_alloc_pci_controller("PHB SW",phb_type_speedwagon);
507                 if (phb == NULL) return NULL;
508
509                 if (systemcfg->platform == PLATFORM_PSERIES) {
510                         phb->cfg_addr = (volatile unsigned long *) 
511                           ioremap(reg_struct.address + 0x140, PAGE_SIZE);
512                         phb->cfg_data = (char*)(phb->cfg_addr - 0x02); /* minus is correct */
513                         phb->phb_regs = (volatile unsigned long *) 
514                           ioremap(reg_struct.address, PAGE_SIZE);
515                         /* Speedwagon's register file is 1 MB in size. */
516                         phb->chip_regs = ioremap(reg_struct.address & ~(0xfffffUL),
517                                                  0x100000); 
518                         PPCDBG(PPCDBG_PHBINIT, "\tmapping chip_regs from 0x%lx -> 0x%lx\n", 
519                                reg_struct.address & 0xfffff, phb->chip_regs);
520                 } else {
521                         phb->cfg_addr = NULL;
522                         phb->cfg_data = NULL; 
523                         phb->phb_regs = NULL;
524                         phb->chip_regs = NULL;
525                 }
526
527                 phb->local_number = ((reg_struct.address >> 12) & 0xf) - 0x8;
528         } else {
529                 PPCDBG(PPCDBG_PHBINIT, "\tUnknown PHB Type!\n");
530
531                 if (systemcfg->platform == PLATFORM_PSERIES_LPAR) {
532
533                         phb=pci_alloc_pci_controller("PHB UK",phb_type_unknown);
534                         if (phb == NULL) return NULL;
535
536                         phb->cfg_addr = NULL;
537                         phb->cfg_data = NULL;
538                         phb->phb_regs = NULL;
539                         phb->chip_regs = NULL;
540                 } else {
541                         printk("PCI: Unknown Phb Type!\n");
542                         return NULL;
543                 }
544         }
545
546         /* Add a linux,phbnum property to the device tree so user code
547          * can translate bus numbers.
548          */
549         of_prop = (struct property *) alloc_bootmem(sizeof(struct property) +
550                                                     sizeof(phb->global_number));
551         if (of_prop) {
552                 memset(of_prop, 0, sizeof(struct property));
553                 of_prop->name = "linux,phbnum";
554                 of_prop->length = sizeof(phb->global_number);
555                 of_prop->value = (unsigned char *)&of_prop[1];
556                 memcpy(of_prop->value, &phb->global_number,
557                        sizeof(phb->global_number));
558                 prom_add_property(dev, of_prop);
559         }
560
561         bus_range = (int *) get_property(dev, "bus-range", &len);
562         if (bus_range == NULL || len < 2 * sizeof(int)) {
563                 PPCDBG(PPCDBG_PHBINIT, "Can't get bus-range for %s\n", dev->full_name);
564                 kfree(phb);
565                 return(NULL);
566         }
567
568         /***************************************************************
569         * Finished with the initialization
570         ***************************************************************/
571         phb->first_busno =  bus_range[0];
572         phb->last_busno  =  bus_range[1];
573
574         phb->arch_data   = dev;
575         phb->ops = &rtas_pci_ops;
576
577         buid_vals = (int *) get_property(dev, "ibm,fw-phb-id", &len);
578         
579   if (buid_vals == NULL) {
580                 phb->buid = 0;
581         } 
582   else {
583                 struct pci_bus check;
584                 if (sizeof(check.number) == 1 || sizeof(check.primary) == 1 ||
585                     sizeof(check.secondary) == 1 || sizeof(check.subordinate) == 1) {
586                         udbg_printf("pSeries_pci:  this system has large bus numbers and the kernel was not\n"
587                               "built with the patch that fixes include/linux/pci.h struct pci_bus so\n"
588                               "number, primary, secondary and subordinate are ints.\n");
589                         panic("pSeries_pci:  this system has large bus numbers and the kernel was not\n"
590                               "built with the patch that fixes include/linux/pci.h struct pci_bus so\n"
591                               "number, primary, secondary and subordinate are ints.\n");
592     }
593     
594     if (len < 2 * sizeof(int))
595       phb->buid = (unsigned long)buid_vals[0];  // Support for new OF that only has 1 integer for buid.
596     else
597       phb->buid = (((unsigned long)buid_vals[0]) << 32UL) |
598                   (((unsigned long)buid_vals[1]) & 0xffffffff);
599         
600                 phb->first_busno += (phb->global_number << 8);
601                 phb->last_busno += (phb->global_number << 8);
602         }
603
604         /* Dump PHB information for Debug */
605         PPCDBGCALL(PPCDBG_PHBINIT,dumpPci_Controller(phb) );
606
607         return phb;
608 }
609
610 void 
611 fixup_resources(struct pci_dev *dev)
612 {
613         int i;
614         struct pci_controller *phb = PCI_GET_PHB_PTR(dev);
615         struct device_node *dn;
616
617         /* Add IBM loc code (slot) as a prefix to the device names for service */
618         dn = pci_device_to_OF_node(dev);
619         if (dn) {
620                 char *loc_code = get_property(dn, "ibm,loc-code", 0);
621                 if (loc_code) {
622                         int loc_len = strlen(loc_code);
623                         if (loc_len < sizeof(dev->name)) {
624                                 memmove(dev->name+loc_len+1, dev->name, sizeof(dev->name)-loc_len-1);
625                                 memcpy(dev->name, loc_code, loc_len);
626                                 dev->name[loc_len] = ' ';
627                                 dev->name[sizeof(dev->name)-1] = '\0';
628                         }
629                 }
630         }
631
632         PPCDBG(PPCDBG_PHBINIT, "fixup_resources:\n"); 
633         PPCDBG(PPCDBG_PHBINIT, "\tphb                 = 0x%016LX\n", phb); 
634         PPCDBG(PPCDBG_PHBINIT, "\tphb->pci_io_offset  = 0x%016LX\n", phb->pci_io_offset); 
635         PPCDBG(PPCDBG_PHBINIT, "\tphb->pci_mem_offset = 0x%016LX\n", phb->pci_mem_offset); 
636
637         PPCDBG(PPCDBG_PHBINIT, "\tdev->name   = %s\n", dev->name);
638         PPCDBG(PPCDBG_PHBINIT, "\tdev->vendor:device = 0x%04X : 0x%04X\n", dev->vendor, dev->device);
639
640         if (phb == NULL)
641                 return;
642
643         for (i = 0; i <  DEVICE_COUNT_RESOURCE; ++i) {
644                 PPCDBG(PPCDBG_PHBINIT, "\tdevice %x.%x[%d] (flags %x) [%lx..%lx]\n",
645                             dev->bus->number, dev->devfn, i,
646                             dev->resource[i].flags,
647                             dev->resource[i].start,
648                             dev->resource[i].end);
649
650                 if ((dev->resource[i].start == 0) && (dev->resource[i].end == 0)) {
651                         continue;
652                 }
653
654                 if (dev->resource[i].start > dev->resource[i].end) {
655                         /* Bogus resource.  Just clear it out. */
656                         dev->resource[i].start = dev->resource[i].end = 0;
657                         continue;
658                 }
659
660
661                 if (dev->resource[i].flags & IORESOURCE_IO) {
662                         unsigned long offset = (unsigned long)phb->io_base_virt - pci_io_base;
663                         dev->resource[i].start += offset;
664                         dev->resource[i].end += offset;
665                         PPCDBG(PPCDBG_PHBINIT, "\t\t-> now [%lx .. %lx]\n",
666                                dev->resource[i].start, dev->resource[i].end);
667                 } else if (dev->resource[i].flags & IORESOURCE_MEM) {
668                         if (dev->resource[i].start == 0) {
669                                 /* Bogus.  Probably an unused bridge. */
670                                 dev->resource[i].end = 0;
671                         } else {
672                                 dev->resource[i].start += phb->pci_mem_offset;
673                                 dev->resource[i].end += phb->pci_mem_offset;
674                         }
675                         PPCDBG(PPCDBG_PHBINIT, "\t\t-> now [%lx..%lx]\n",
676                                dev->resource[i].start, dev->resource[i].end);
677
678                 } else {
679                         continue;
680                 }
681
682                 /* zap the 2nd function of the winbond chip */
683                 if (dev->resource[i].flags & IORESOURCE_IO
684                     && dev->bus->number == 0 && dev->devfn == 0x81)
685                         dev->resource[i].flags &= ~IORESOURCE_IO;
686         }
687 }   
688
689 static void check_s7a(void)
690 {
691         struct device_node *root;
692         char *model;
693
694         root = find_path_device("/");
695         if (root) {
696                 model = get_property(root, "model", NULL);
697                 if (model && !strcmp(model, "IBM,7013-S7A"))
698                         s7a_workaround = 1;
699         }
700 }
701
702 void __init
703 pSeries_pcibios_fixup(void)
704 {
705         struct pci_dev *dev;
706
707         PPCDBG(PPCDBG_PHBINIT, "pSeries_pcibios_fixup: start\n");
708         pci_assign_all_busses = 0;
709
710         check_s7a();
711         
712         pci_for_each_dev(dev) {
713                 pci_read_irq_line(dev);
714                 PPCDBGCALL(PPCDBG_PHBINIT, dumpPci_Dev(dev) );
715         }
716 }
717
718 /*********************************************************************** 
719  * pci_find_hose_for_OF_device
720  *
721  * This function finds the PHB that matching device_node in the 
722  * OpenFirmware by scanning all the pci_controllers.
723  * 
724  ***********************************************************************/
725 struct pci_controller*
726 pci_find_hose_for_OF_device(struct device_node *node)
727 {
728         while (node) {
729                 struct pci_controller *hose;
730                 for (hose=hose_head;hose;hose=hose->next)
731                         if (hose->arch_data == node)
732                                 return hose;
733                 node=node->parent;
734         }
735         return NULL;
736 }
737
738 /*********************************************************************** 
739  * ppc64_pcibios_init
740  *  
741  * Chance to initialize and structures or variable before PCI Bus walk.
742  *  
743  ***********************************************************************/
744 void 
745 pSeries_pcibios_init(void)
746 {
747         PPCDBG(PPCDBG_PHBINIT, "\tppc64_pcibios_init Entry.\n"); 
748
749         if (get_property(find_path_device("/rtas"),"ibm,fw-phb-id",NULL) != NULL) {
750                 PPCDBG(PPCDBG_PHBINIT, "\tFound: ibm,fw-phb-id\n"); 
751                 Pci_Large_Bus_System = 1;
752         }
753 }
754
755 /*
756  * This is called very early before the page table is setup.
757  */
758 void 
759 pSeries_pcibios_init_early(void)
760 {
761         ppc_md.pcibios_read_config_byte = rtas_read_config_byte;
762         ppc_md.pcibios_read_config_word = rtas_read_config_word;
763         ppc_md.pcibios_read_config_dword = rtas_read_config_dword;
764         ppc_md.pcibios_write_config_byte = rtas_write_config_byte;
765         ppc_md.pcibios_write_config_word = rtas_write_config_word;
766         ppc_md.pcibios_write_config_dword = rtas_write_config_dword;
767 }
768 /************************************************************************/
769 /* Get a char* of the device physical location(U0.3-P1-I8)              */
770 /* See the Product Topology in the RS/6000 Architecture.                */
771 /************************************************************************/
772 int device_Location(struct pci_dev *PciDev, char *BufPtr)
773 {
774         struct device_node *DevNode = (struct device_node *)PciDev->sysdata;
775         return sprintf(BufPtr,"PCI: Bus%3d, Device%3d, Vendor %04X, Location %-12s",
776                        PciDev->bus->number,
777                        PCI_SLOT(PciDev->devfn),
778                        PciDev->vendor,
779                        (char*)get_property(DevNode,"ibm,loc-code",0));
780 }
781 /************************************************************************/
782 /* Set the slot reset line to the state passed in.                      */
783 /* This is the platform specific for code for the pci_reset_device      */
784 /* function.                                                            */
785 /************************************************************************/
786 int pci_set_reset(struct pci_dev *PciDev, int state)
787 {
788         return -1;
789 }