1/* 2 * Copyright 2003 PMC-Sierra 3 * Author: Manish Lachwani (lachwani@pmc-sierra.com) 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License as published by the 7 * Free Software Foundation; either version 2 of the License, or (at your 8 * option) any later version. 9 * 10 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 11 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 13 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 14 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 15 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 16 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 17 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 18 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 19 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 20 * 21 * You should have received a copy of the GNU General Public License along 22 * with this program; if not, write to the Free Software Foundation, Inc., 23 * 675 Mass Ave, Cambridge, MA 02139, USA. 24 */ 25 26#include <linux/types.h> 27#include <linux/pci.h> 28#include <linux/kernel.h> 29#include <asm/pci.h> 30#include <asm/io.h> 31 32#include <linux/init.h> 33#include <asm/titan_dep.h> 34 35#ifdef CONFIG_HYPERTRANSPORT 36 37 38/* 39 * This function check if the Hypertransport Link Initialization completed. If 40 * it did, then proceed further with scanning bus #2 41 */ 42static __inline__ int check_titan_htlink(void) 43{ 44 u32 val; 45 46 val = *(volatile uint32_t *)(RM9000x2_HTLINK_REG); 47 if (val & 0x00000020) 48 /* HT Link Initialization completed */ 49 return 1; 50 else 51 return 0; 52} 53 54static int titan_ht_config_read_dword(struct pci_dev *device, 55 int offset, u32* val) 56{ 57 int dev, bus, func; 58 uint32_t address_reg, data_reg; 59 uint32_t address; 60 61 bus = device->bus->number; 62 dev = PCI_SLOT(device->devfn); 63 func = PCI_FUNC(device->devfn); 64 65 if (bus > 2) 66 address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) | 67 0x80000000 | 0x1; 68 else 69 address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000; 70 71 address_reg = RM9000x2_OCD_HTCFGA; 72 data_reg = RM9000x2_OCD_HTCFGD; 73 74 RM9K_WRITE(address_reg, address); 75 RM9K_READ(data_reg, val); 76 77 return PCIBIOS_SUCCESSFUL; 78} 79 80 81static int titan_ht_config_read_word(struct pci_dev *device, 82 int offset, u16* val) 83{ 84 int dev, bus, func; 85 uint32_t address_reg, data_reg; 86 uint32_t address; 87 88 bus = device->bus->number; 89 dev = PCI_SLOT(device->devfn); 90 func = PCI_FUNC(device->devfn); 91 92 if (bus > 2) 93 address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) | 94 0x80000000 | 0x1; 95 else 96 address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000; 97 98 address_reg = RM9000x2_OCD_HTCFGA; 99 data_reg = RM9000x2_OCD_HTCFGD; 100 101 if ((offset & 0x3) == 0) 102 offset = 0x2; 103 else 104 offset = 0x0; 105 106 RM9K_WRITE(address_reg, address); 107 RM9K_READ_16(data_reg + offset, val); 108 109 return PCIBIOS_SUCCESSFUL; 110} 111 112 113u32 longswap(unsigned long l) 114{ 115 unsigned char b1, b2, b3, b4; 116 117 b1 = l&255; 118 b2 = (l>>8)&255; 119 b3 = (l>>16)&255; 120 b4 = (l>>24)&255; 121 122 return ((b1<<24) + (b2<<16) + (b3<<8) + b4); 123} 124 125 126static int titan_ht_config_read_byte(struct pci_dev *device, 127 int offset, u8* val) 128{ 129 int dev, bus, func; 130 uint32_t address_reg, data_reg; 131 uint32_t address; 132 int offset1; 133 134 bus = device->bus->number; 135 dev = PCI_SLOT(device->devfn); 136 func = PCI_FUNC(device->devfn); 137 138 if (bus > 2) 139 address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) | 140 0x80000000 | 0x1; 141 else 142 address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000; 143 144 address_reg = RM9000x2_OCD_HTCFGA; 145 data_reg = RM9000x2_OCD_HTCFGD; 146 147 RM9K_WRITE(address_reg, address); 148 149 if ((offset & 0x3) == 0) { 150 offset1 = 0x3; 151 } 152 if ((offset & 0x3) == 1) { 153 offset1 = 0x2; 154 } 155 if ((offset & 0x3) == 2) { 156 offset1 = 0x1; 157 } 158 if ((offset & 0x3) == 3) { 159 offset1 = 0x0; 160 } 161 RM9K_READ_8(data_reg + offset1, val); 162 163 return PCIBIOS_SUCCESSFUL; 164} 165 166 167static int titan_ht_config_write_dword(struct pci_dev *device, 168 int offset, u8 val) 169{ 170 int dev, bus, func; 171 uint32_t address_reg, data_reg; 172 uint32_t address; 173 174 bus = device->bus->number; 175 dev = PCI_SLOT(device->devfn); 176 func = PCI_FUNC(device->devfn); 177 178 if (bus > 2) 179 address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) | 180 0x80000000 | 0x1; 181 else 182 address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000; 183 184 address_reg = RM9000x2_OCD_HTCFGA; 185 data_reg = RM9000x2_OCD_HTCFGD; 186 187 RM9K_WRITE(address_reg, address); 188 RM9K_WRITE(data_reg, val); 189 190 return PCIBIOS_SUCCESSFUL; 191} 192 193static int titan_ht_config_write_word(struct pci_dev *device, 194 int offset, u8 val) 195{ 196 int dev, bus, func; 197 uint32_t address_reg, data_reg; 198 uint32_t address; 199 200 bus = device->bus->number; 201 dev = PCI_SLOT(device->devfn); 202 func = PCI_FUNC(device->devfn); 203 204 if (bus > 2) 205 address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) | 206 0x80000000 | 0x1; 207 else 208 address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000; 209 210 address_reg = RM9000x2_OCD_HTCFGA; 211 data_reg = RM9000x2_OCD_HTCFGD; 212 213 if ((offset & 0x3) == 0) 214 offset = 0x2; 215 else 216 offset = 0x0; 217 218 RM9K_WRITE(address_reg, address); 219 RM9K_WRITE_16(data_reg + offset, val); 220 221 return PCIBIOS_SUCCESSFUL; 222} 223 224static int titan_ht_config_write_byte(struct pci_dev *device, 225 int offset, u8 val) 226{ 227 int dev, bus, func; 228 uint32_t address_reg, data_reg; 229 uint32_t address; 230 int offset1; 231 232 bus = device->bus->number; 233 dev = PCI_SLOT(device->devfn); 234 func = PCI_FUNC(device->devfn); 235 236 if (bus > 2) 237 address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) | 238 0x80000000 | 0x1; 239 else 240 address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000; 241 242 address_reg = RM9000x2_OCD_HTCFGA; 243 data_reg = RM9000x2_OCD_HTCFGD; 244 245 RM9K_WRITE(address_reg, address); 246 247 if ((offset & 0x3) == 0) { 248 offset1 = 0x3; 249 } 250 if ((offset & 0x3) == 1) { 251 offset1 = 0x2; 252 } 253 if ((offset & 0x3) == 2) { 254 offset1 = 0x1; 255 } 256 if ((offset & 0x3) == 3) { 257 offset1 = 0x0; 258 } 259 260 RM9K_WRITE_8(data_reg + offset1, val); 261 return PCIBIOS_SUCCESSFUL; 262} 263 264 265static void titan_pcibios_set_master(struct pci_dev *dev) 266{ 267 u16 cmd; 268 int bus = dev->bus->number; 269 270 if (check_titan_htlink()) 271 titan_ht_config_read_word(dev, PCI_COMMAND, &cmd); 272 273 cmd |= PCI_COMMAND_MASTER; 274 275 if (check_titan_htlink()) 276 titan_ht_config_write_word(dev, PCI_COMMAND, cmd); 277} 278 279 280int pcibios_enable_resources(struct pci_dev *dev) 281{ 282 u16 cmd, old_cmd; 283 u8 tmp1; 284 int idx; 285 struct resource *r; 286 int bus = dev->bus->number; 287 288 if (check_titan_htlink()) 289 titan_ht_config_read_word(dev, PCI_COMMAND, &cmd); 290 291 old_cmd = cmd; 292 for (idx = 0; idx < 6; idx++) { 293 r = &dev->resource[idx]; 294 if (!r->start && r->end) { 295 printk(KERN_ERR 296 "PCI: Device %s not available because of " 297 "resource collisions\n", pci_name(dev)); 298 return -EINVAL; 299 } 300 if (r->flags & IORESOURCE_IO) 301 cmd |= PCI_COMMAND_IO; 302 if (r->flags & IORESOURCE_MEM) 303 cmd |= PCI_COMMAND_MEMORY; 304 } 305 if (cmd != old_cmd) { 306 if (check_titan_htlink()) 307 titan_ht_config_write_word(dev, PCI_COMMAND, cmd); 308 } 309 310 if (check_titan_htlink()) 311 titan_ht_config_read_byte(dev, PCI_CACHE_LINE_SIZE, &tmp1); 312 313 if (tmp1 != 8) { 314 printk(KERN_WARNING "PCI setting cache line size to 8 from " 315 "%d\n", tmp1); 316 } 317 318 if (check_titan_htlink()) 319 titan_ht_config_write_byte(dev, PCI_CACHE_LINE_SIZE, 8); 320 321 if (check_titan_htlink()) 322 titan_ht_config_read_byte(dev, PCI_LATENCY_TIMER, &tmp1); 323 324 if (tmp1 < 32 || tmp1 == 0xff) { 325 printk(KERN_WARNING "PCI setting latency timer to 32 from %d\n", 326 tmp1); 327 } 328 329 if (check_titan_htlink()) 330 titan_ht_config_write_byte(dev, PCI_LATENCY_TIMER, 32); 331 332 return 0; 333} 334 335 336int pcibios_enable_device(struct pci_dev *dev, int mask) 337{ 338 return pcibios_enable_resources(dev); 339} 340 341resource_size_t pcibios_align_resource(void *data, const struct resource *res, 342 resource_size_t size, resource_size_t align) 343{ 344 struct pci_dev *dev = data; 345 resource_size_t start = res->start; 346 347 if (res->flags & IORESOURCE_IO) { 348 /* We need to avoid collisions with `mirrored' VGA ports 349 and other strange ISA hardware, so we always want the 350 addresses kilobyte aligned. */ 351 if (size > 0x100) { 352 printk(KERN_ERR "PCI: I/O Region %s/%d too large" 353 " (%ld bytes)\n", pci_name(dev), 354 dev->resource - res, size); 355 } 356 357 start = (start + 1024 - 1) & ~(1024 - 1); 358 } 359 360 return start; 361} 362 363struct pci_ops titan_pci_ops = { 364 titan_ht_config_read_byte, 365 titan_ht_config_read_word, 366 titan_ht_config_read_dword, 367 titan_ht_config_write_byte, 368 titan_ht_config_write_word, 369 titan_ht_config_write_dword 370}; 371 372void __init pcibios_fixup_bus(struct pci_bus *c) 373{ 374 titan_ht_pcibios_fixup_bus(c); 375} 376 377void __init pcibios_init(void) 378{ 379 380 /* Reset PCI I/O and PCI MEM values */ 381 ioport_resource.start = 0xe0000000; 382 ioport_resource.end = 0xe0000000 + 0x20000000 - 1; 383 iomem_resource.start = 0xc0000000; 384 iomem_resource.end = 0xc0000000 + 0x20000000 - 1; 385 386 pci_scan_bus(2, &titan_pci_ops, NULL); 387 pci_scan_bus(3, &titan_pci_ops, NULL); 388} 389 390/* 391 * for parsing "pci=" kernel boot arguments. 392 */ 393char *pcibios_setup(char *str) 394{ 395 printk(KERN_INFO "rr: pcibios_setup\n"); 396 /* Nothing to do for now. */ 397 398 return str; 399} 400 401unsigned __init int pcibios_assign_all_busses(void) 402{ 403 /* We want to use the PCI bus detection done by PMON */ 404 return 0; 405} 406 407#endif /* CONFIG_HYPERTRANSPORT */ 408