1/* 2 * $Id: pcibios.c,v 1.1.1.1 2007/08/03 18:52:17 Exp $ 3 * 4 * arch/sh/kernel/pcibios.c 5 * 6 * Copyright (C) 2002 STMicroelectronics Limited 7 * Author : David J. McKay 8 * 9 * Copyright (C) 2004 Richard Curnow, SuperH UK Limited 10 * 11 * This file is subject to the terms and conditions of the GNU General Public 12 * License. See the file "COPYING" in the main directory of this archive 13 * for more details. 14 * This is GPL'd. 15 * 16 * Provided here are generic versions of: 17 * pcibios_update_resource() 18 * pcibios_align_resource() 19 * pcibios_enable_device() 20 * pcibios_set_master() 21 * pcibios_update_irq() 22 * 23 * These functions are collected here to reduce duplication of common 24 * code amongst the many platform-specific PCI support code files. 25 * 26 * Platform-specific files are expected to provide: 27 * pcibios_fixup_bus() 28 * pcibios_init() 29 * pcibios_setup() 30 * pcibios_fixup_pbus_ranges() 31 */ 32 33#include <linux/kernel.h> 34#include <linux/pci.h> 35#include <linux/init.h> 36 37void 38pcibios_update_resource(struct pci_dev *dev, struct resource *root, 39 struct resource *res, int resource) 40{ 41 u32 new, check; 42 int reg; 43 44 new = res->start | (res->flags & PCI_REGION_FLAG_MASK); 45 if (resource < 6) { 46 reg = PCI_BASE_ADDRESS_0 + 4*resource; 47 } else if (resource == PCI_ROM_RESOURCE) { 48 res->flags |= IORESOURCE_ROM_ENABLE; 49 new |= PCI_ROM_ADDRESS_ENABLE; 50 reg = dev->rom_base_reg; 51 } else { 52 /* Somebody might have asked allocation of a non-standard resource */ 53 return; 54 } 55 56 pci_write_config_dword(dev, reg, new); 57 pci_read_config_dword(dev, reg, &check); 58 if ((new ^ check) & ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)) { 59 printk(KERN_ERR "PCI: Error while updating region " 60 "%s/%d (%08x != %08x)\n", pci_name(dev), resource, 61 new, check); 62 } 63} 64 65/* 66 * We need to avoid collisions with `mirrored' VGA ports 67 * and other strange ISA hardware, so we always want the 68 * addresses to be allocated in the 0x000-0x0ff region 69 * modulo 0x400. 70 */ 71void pcibios_align_resource(void *data, struct resource *res, 72 resource_size_t size, resource_size_t align) 73{ 74 if (res->flags & IORESOURCE_IO) { 75 resource_size_t start = res->start; 76 77 if (start & 0x300) { 78 start = (start + 0x3ff) & ~0x3ff; 79 res->start = start; 80 } 81 } 82} 83 84static void pcibios_enable_bridge(struct pci_dev *dev) 85{ 86 struct pci_bus *bus = dev->subordinate; 87 u16 cmd, old_cmd; 88 89 pci_read_config_word(dev, PCI_COMMAND, &cmd); 90 old_cmd = cmd; 91 92 if (bus->resource[0]->flags & IORESOURCE_IO) { 93 cmd |= PCI_COMMAND_IO; 94 } 95 if ((bus->resource[1]->flags & IORESOURCE_MEM) || 96 (bus->resource[2]->flags & IORESOURCE_PREFETCH)) { 97 cmd |= PCI_COMMAND_MEMORY; 98 } 99 100 if (cmd != old_cmd) { 101 pci_write_config_word(dev, PCI_COMMAND, cmd); 102 } 103 104 printk("PCI bridge %s, command register -> %04x\n", 105 pci_name(dev), cmd); 106 107} 108 109 110 111int pcibios_enable_device(struct pci_dev *dev, int mask) 112{ 113 u16 cmd, old_cmd; 114 int idx; 115 struct resource *r; 116 117 if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { 118 pcibios_enable_bridge(dev); 119 } 120 121 pci_read_config_word(dev, PCI_COMMAND, &cmd); 122 old_cmd = cmd; 123 for(idx=0; idx<6; idx++) { 124 if (!(mask & (1 << idx))) 125 continue; 126 r = &dev->resource[idx]; 127 if (!r->start && r->end) { 128 printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", pci_name(dev)); 129 return -EINVAL; 130 } 131 if (r->flags & IORESOURCE_IO) 132 cmd |= PCI_COMMAND_IO; 133 if (r->flags & IORESOURCE_MEM) 134 cmd |= PCI_COMMAND_MEMORY; 135 } 136 if (dev->resource[PCI_ROM_RESOURCE].start) 137 cmd |= PCI_COMMAND_MEMORY; 138 if (cmd != old_cmd) { 139 printk(KERN_INFO "PCI: Enabling device %s (%04x -> %04x)\n", pci_name(dev), old_cmd, cmd); 140 pci_write_config_word(dev, PCI_COMMAND, cmd); 141 } 142 return 0; 143} 144 145/* 146 * If we set up a device for bus mastering, we need to check and set 147 * the latency timer as it may not be properly set. 148 */ 149unsigned int pcibios_max_latency = 255; 150 151void pcibios_set_master(struct pci_dev *dev) 152{ 153 u8 lat; 154 pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); 155 if (lat < 16) 156 lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency; 157 else if (lat > pcibios_max_latency) 158 lat = pcibios_max_latency; 159 else 160 return; 161 printk(KERN_INFO "PCI: Setting latency timer of device %s to %d\n", pci_name(dev), lat); 162 pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat); 163} 164 165void __init pcibios_update_irq(struct pci_dev *dev, int irq) 166{ 167 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); 168} 169