1/* 2 * Copyright (C) 2001 Dave Engebretsen, IBM Corporation 3 * Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM 4 * 5 * pSeries specific routines for PCI. 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 */ 21 22#include <linux/init.h> 23#include <linux/ioport.h> 24#include <linux/kernel.h> 25#include <linux/pci.h> 26#include <linux/string.h> 27 28#include <asm/eeh.h> 29#include <asm/pci-bridge.h> 30#include <asm/prom.h> 31#include <asm/ppc-pci.h> 32#include "pseries.h" 33 34#if 0 35void pcibios_name_device(struct pci_dev *dev) 36{ 37 struct device_node *dn; 38 39 /* 40 * Add IBM loc code (slot) as a prefix to the device names for service 41 */ 42 dn = pci_device_to_OF_node(dev); 43 if (dn) { 44 const char *loc_code = of_get_property(dn, "ibm,loc-code", 45 NULL); 46 if (loc_code) { 47 int loc_len = strlen(loc_code); 48 if (loc_len < sizeof(dev->dev.name)) { 49 memmove(dev->dev.name+loc_len+1, dev->dev.name, 50 sizeof(dev->dev.name)-loc_len-1); 51 memcpy(dev->dev.name, loc_code, loc_len); 52 dev->dev.name[loc_len] = ' '; 53 dev->dev.name[sizeof(dev->dev.name)-1] = '\0'; 54 } 55 } 56 } 57} 58DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_name_device); 59#endif 60 61static void __init pSeries_request_regions(void) 62{ 63 if (!isa_io_base) 64 return; 65 66 request_region(0x20,0x20,"pic1"); 67 request_region(0xa0,0x20,"pic2"); 68 request_region(0x00,0x20,"dma1"); 69 request_region(0x40,0x20,"timer"); 70 request_region(0x80,0x10,"dma page reg"); 71 request_region(0xc0,0x20,"dma2"); 72} 73 74void __init pSeries_final_fixup(void) 75{ 76 pSeries_request_regions(); 77 78 eeh_addr_cache_build(); 79} 80 81/* 82 * Assume the winbond 82c105 is the IDE controller on a 83 * p610/p615/p630. We should probably be more careful in case 84 * someone tries to plug in a similar adapter. 85 */ 86static void fixup_winbond_82c105(struct pci_dev* dev) 87{ 88 int i; 89 unsigned int reg; 90 91 if (!machine_is(pseries)) 92 return; 93 94 printk("Using INTC for W82c105 IDE controller.\n"); 95 pci_read_config_dword(dev, 0x40, ®); 96 /* Enable LEGIRQ to use INTC instead of ISA interrupts */ 97 pci_write_config_dword(dev, 0x40, reg | (1<<11)); 98 99 for (i = 0; i < DEVICE_COUNT_RESOURCE; ++i) { 100 /* zap the 2nd function of the winbond chip */ 101 if (dev->resource[i].flags & IORESOURCE_IO 102 && dev->bus->number == 0 && dev->devfn == 0x81) 103 dev->resource[i].flags &= ~IORESOURCE_IO; 104 if (dev->resource[i].start == 0 && dev->resource[i].end) { 105 dev->resource[i].flags = 0; 106 dev->resource[i].end = 0; 107 } 108 } 109} 110DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105, 111 fixup_winbond_82c105); 112 113int pseries_root_bridge_prepare(struct pci_host_bridge *bridge) 114{ 115 struct device_node *dn, *pdn; 116 struct pci_bus *bus; 117 u32 pcie_link_speed_stats[2]; 118 int rc; 119 120 bus = bridge->bus; 121 122 dn = pcibios_get_phb_of_node(bus); 123 if (!dn) 124 return 0; 125 126 for (pdn = dn; pdn != NULL; pdn = of_get_next_parent(pdn)) { 127 rc = of_property_read_u32_array(pdn, 128 "ibm,pcie-link-speed-stats", 129 &pcie_link_speed_stats[0], 2); 130 if (!rc) 131 break; 132 } 133 134 of_node_put(pdn); 135 136 if (rc) { 137 pr_err("no ibm,pcie-link-speed-stats property\n"); 138 return 0; 139 } 140 141 switch (pcie_link_speed_stats[0]) { 142 case 0x01: 143 bus->max_bus_speed = PCIE_SPEED_2_5GT; 144 break; 145 case 0x02: 146 bus->max_bus_speed = PCIE_SPEED_5_0GT; 147 break; 148 case 0x04: 149 bus->max_bus_speed = PCIE_SPEED_8_0GT; 150 break; 151 default: 152 bus->max_bus_speed = PCI_SPEED_UNKNOWN; 153 break; 154 } 155 156 switch (pcie_link_speed_stats[1]) { 157 case 0x01: 158 bus->cur_bus_speed = PCIE_SPEED_2_5GT; 159 break; 160 case 0x02: 161 bus->cur_bus_speed = PCIE_SPEED_5_0GT; 162 break; 163 case 0x04: 164 bus->cur_bus_speed = PCIE_SPEED_8_0GT; 165 break; 166 default: 167 bus->cur_bus_speed = PCI_SPEED_UNKNOWN; 168 break; 169 } 170 171 return 0; 172} 173