1/* ASB2305 PCI support 2 * 3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. 4 * Written by David Howells (dhowells@redhat.com) 5 * Derived from arch/i386/kernel/pci-pc.c 6 * (c) 1999--2000 Martin Mares <mj@suse.cz> 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public Licence 10 * as published by the Free Software Foundation; either version 11 * 2 of the Licence, or (at your option) any later version. 12 */ 13#include <linux/types.h> 14#include <linux/kernel.h> 15#include <linux/sched.h> 16#include <linux/pci.h> 17#include <linux/init.h> 18#include <linux/ioport.h> 19#include <linux/delay.h> 20#include <asm/io.h> 21#include "pci-asb2305.h" 22 23unsigned int pci_probe = 1; 24 25int pcibios_last_bus = -1; 26struct pci_bus *pci_root_bus; 27struct pci_ops *pci_root_ops; 28 29/* 30 * The accessible PCI window does not cover the entire CPU address space, but 31 * there are devices we want to access outside of that window, so we need to 32 * insert specific PCI bus resources instead of using the platform-level bus 33 * resources directly for the PCI root bus. 34 * 35 * These are configured and inserted by pcibios_init() and are attached to the 36 * root bus by pcibios_fixup_bus(). 37 */ 38static struct resource pci_ioport_resource = { 39 .name = "PCI IO", 40 .start = 0xbe000000, 41 .end = 0xbe03ffff, 42 .flags = IORESOURCE_IO, 43}; 44 45static struct resource pci_iomem_resource = { 46 .name = "PCI mem", 47 .start = 0xb8000000, 48 .end = 0xbbffffff, 49 .flags = IORESOURCE_MEM, 50}; 51 52/* 53 * Functions for accessing PCI configuration space 54 */ 55 56#define CONFIG_CMD(bus, devfn, where) \ 57 (0x80000000 | (bus->number << 16) | (devfn << 8) | (where & ~3)) 58 59#define MEM_PAGING_REG (*(volatile __u32 *) 0xBFFFFFF4) 60#define CONFIG_ADDRESS (*(volatile __u32 *) 0xBFFFFFF8) 61#define CONFIG_DATAL(X) (*(volatile __u32 *) 0xBFFFFFFC) 62#define CONFIG_DATAW(X) (*(volatile __u16 *) (0xBFFFFFFC + ((X) & 2))) 63#define CONFIG_DATAB(X) (*(volatile __u8 *) (0xBFFFFFFC + ((X) & 3))) 64 65#define BRIDGEREGB(X) (*(volatile __u8 *) (0xBE040000 + (X))) 66#define BRIDGEREGW(X) (*(volatile __u16 *) (0xBE040000 + (X))) 67#define BRIDGEREGL(X) (*(volatile __u32 *) (0xBE040000 + (X))) 68 69static inline int __query(const struct pci_bus *bus, unsigned int devfn) 70{ 71 return 1; 72} 73 74/* 75 * translate Linuxcentric addresses to PCI bus addresses 76 */ 77void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, 78 struct resource *res) 79{ 80 if (res->flags & IORESOURCE_IO) { 81 region->start = (res->start & 0x00ffffff); 82 region->end = (res->end & 0x00ffffff); 83 } 84 85 if (res->flags & IORESOURCE_MEM) { 86 region->start = (res->start & 0x03ffffff) | MEM_PAGING_REG; 87 region->end = (res->end & 0x03ffffff) | MEM_PAGING_REG; 88 } 89 90} 91EXPORT_SYMBOL(pcibios_resource_to_bus); 92 93/* 94 * translate PCI bus addresses to Linuxcentric addresses 95 */ 96void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, 97 struct pci_bus_region *region) 98{ 99 if (res->flags & IORESOURCE_IO) { 100 res->start = (region->start & 0x00ffffff) | 0xbe000000; 101 res->end = (region->end & 0x00ffffff) | 0xbe000000; 102 } 103 104 if (res->flags & IORESOURCE_MEM) { 105 res->start = (region->start & 0x03ffffff) | 0xb8000000; 106 res->end = (region->end & 0x03ffffff) | 0xb8000000; 107 } 108 109} 110EXPORT_SYMBOL(pcibios_bus_to_resource); 111 112/* 113 * 114 */ 115static int pci_ampci_read_config_byte(struct pci_bus *bus, unsigned int devfn, 116 int where, u32 *_value) 117{ 118 u32 rawval, value; 119 120 if (bus->number == 0 && devfn == PCI_DEVFN(0, 0)) { 121 value = BRIDGEREGB(where); 122 __pcbdebug("=> %02hx", &BRIDGEREGL(where), value); 123 } else { 124 CONFIG_ADDRESS = CONFIG_CMD(bus, devfn, where); 125 rawval = CONFIG_ADDRESS; 126 value = CONFIG_DATAB(where); 127 if (__query(bus, devfn)) 128 __pcidebug("=> %02hx", bus, devfn, where, value); 129 } 130 131 *_value = value; 132 return PCIBIOS_SUCCESSFUL; 133} 134 135static int pci_ampci_read_config_word(struct pci_bus *bus, unsigned int devfn, 136 int where, u32 *_value) 137{ 138 u32 rawval, value; 139 140 if (bus->number == 0 && devfn == PCI_DEVFN(0, 0)) { 141 value = BRIDGEREGW(where); 142 __pcbdebug("=> %04hx", &BRIDGEREGL(where), value); 143 } else { 144 CONFIG_ADDRESS = CONFIG_CMD(bus, devfn, where); 145 rawval = CONFIG_ADDRESS; 146 value = CONFIG_DATAW(where); 147 if (__query(bus, devfn)) 148 __pcidebug("=> %04hx", bus, devfn, where, value); 149 } 150 151 *_value = value; 152 return PCIBIOS_SUCCESSFUL; 153} 154 155static int pci_ampci_read_config_dword(struct pci_bus *bus, unsigned int devfn, 156 int where, u32 *_value) 157{ 158 u32 rawval, value; 159 160 if (bus->number == 0 && devfn == PCI_DEVFN(0, 0)) { 161 value = BRIDGEREGL(where); 162 __pcbdebug("=> %08x", &BRIDGEREGL(where), value); 163 } else { 164 CONFIG_ADDRESS = CONFIG_CMD(bus, devfn, where); 165 rawval = CONFIG_ADDRESS; 166 value = CONFIG_DATAL(where); 167 if (__query(bus, devfn)) 168 __pcidebug("=> %08x", bus, devfn, where, value); 169 } 170 171 *_value = value; 172 return PCIBIOS_SUCCESSFUL; 173} 174 175static int pci_ampci_write_config_byte(struct pci_bus *bus, unsigned int devfn, 176 int where, u8 value) 177{ 178 u32 rawval; 179 180 if (bus->number == 0 && devfn == PCI_DEVFN(0, 0)) { 181 __pcbdebug("<= %02x", &BRIDGEREGB(where), value); 182 BRIDGEREGB(where) = value; 183 } else { 184 if (bus->number == 0 && 185 (devfn == PCI_DEVFN(2, 0) || devfn == PCI_DEVFN(3, 0)) 186 ) 187 __pcidebug("<= %02x", bus, devfn, where, value); 188 CONFIG_ADDRESS = CONFIG_CMD(bus, devfn, where); 189 rawval = CONFIG_ADDRESS; 190 CONFIG_DATAB(where) = value; 191 } 192 return PCIBIOS_SUCCESSFUL; 193} 194 195static int pci_ampci_write_config_word(struct pci_bus *bus, unsigned int devfn, 196 int where, u16 value) 197{ 198 u32 rawval; 199 200 if (bus->number == 0 && devfn == PCI_DEVFN(0, 0)) { 201 __pcbdebug("<= %04hx", &BRIDGEREGW(where), value); 202 BRIDGEREGW(where) = value; 203 } else { 204 if (__query(bus, devfn)) 205 __pcidebug("<= %04hx", bus, devfn, where, value); 206 CONFIG_ADDRESS = CONFIG_CMD(bus, devfn, where); 207 rawval = CONFIG_ADDRESS; 208 CONFIG_DATAW(where) = value; 209 } 210 return PCIBIOS_SUCCESSFUL; 211} 212 213static int pci_ampci_write_config_dword(struct pci_bus *bus, unsigned int devfn, 214 int where, u32 value) 215{ 216 u32 rawval; 217 218 if (bus->number == 0 && devfn == PCI_DEVFN(0, 0)) { 219 __pcbdebug("<= %08x", &BRIDGEREGL(where), value); 220 BRIDGEREGL(where) = value; 221 } else { 222 if (__query(bus, devfn)) 223 __pcidebug("<= %08x", bus, devfn, where, value); 224 CONFIG_ADDRESS = CONFIG_CMD(bus, devfn, where); 225 rawval = CONFIG_ADDRESS; 226 CONFIG_DATAL(where) = value; 227 } 228 return PCIBIOS_SUCCESSFUL; 229} 230 231static int pci_ampci_read_config(struct pci_bus *bus, unsigned int devfn, 232 int where, int size, u32 *val) 233{ 234 switch (size) { 235 case 1: 236 return pci_ampci_read_config_byte(bus, devfn, where, val); 237 case 2: 238 return pci_ampci_read_config_word(bus, devfn, where, val); 239 case 4: 240 return pci_ampci_read_config_dword(bus, devfn, where, val); 241 default: 242 BUG(); 243 return -EOPNOTSUPP; 244 } 245} 246 247static int pci_ampci_write_config(struct pci_bus *bus, unsigned int devfn, 248 int where, int size, u32 val) 249{ 250 switch (size) { 251 case 1: 252 return pci_ampci_write_config_byte(bus, devfn, where, val); 253 case 2: 254 return pci_ampci_write_config_word(bus, devfn, where, val); 255 case 4: 256 return pci_ampci_write_config_dword(bus, devfn, where, val); 257 default: 258 BUG(); 259 return -EOPNOTSUPP; 260 } 261} 262 263static struct pci_ops pci_direct_ampci = { 264 pci_ampci_read_config, 265 pci_ampci_write_config, 266}; 267 268/* 269 * Before we decide to use direct hardware access mechanisms, we try to do some 270 * trivial checks to ensure it at least _seems_ to be working -- we just test 271 * whether bus 00 contains a host bridge (this is similar to checking 272 * techniques used in XFree86, but ours should be more reliable since we 273 * attempt to make use of direct access hints provided by the PCI BIOS). 274 * 275 * This should be close to trivial, but it isn't, because there are buggy 276 * chipsets (yes, you guessed it, by Intel and Compaq) that have no class ID. 277 */ 278static int __init pci_sanity_check(struct pci_ops *o) 279{ 280 struct pci_bus bus; /* Fake bus and device */ 281 u32 x; 282 283 bus.number = 0; 284 285 if ((!o->read(&bus, 0, PCI_CLASS_DEVICE, 2, &x) && 286 (x == PCI_CLASS_BRIDGE_HOST || x == PCI_CLASS_DISPLAY_VGA)) || 287 (!o->read(&bus, 0, PCI_VENDOR_ID, 2, &x) && 288 (x == PCI_VENDOR_ID_INTEL || x == PCI_VENDOR_ID_COMPAQ))) 289 return 1; 290 291 printk(KERN_ERR "PCI: Sanity check failed\n"); 292 return 0; 293} 294 295static int __init pci_check_direct(void) 296{ 297 unsigned long flags; 298 299 local_irq_save(flags); 300 301 /* 302 * Check if access works. 303 */ 304 if (pci_sanity_check(&pci_direct_ampci)) { 305 local_irq_restore(flags); 306 printk(KERN_INFO "PCI: Using configuration ampci\n"); 307 request_mem_region(0xBE040000, 256, "AMPCI bridge"); 308 request_mem_region(0xBFFFFFF4, 12, "PCI ampci"); 309 request_mem_region(0xBC000000, 32 * 1024 * 1024, "PCI SRAM"); 310 return 0; 311 } 312 313 local_irq_restore(flags); 314 return -ENODEV; 315} 316 317static int __devinit is_valid_resource(struct pci_dev *dev, int idx) 318{ 319 unsigned int i, type_mask = IORESOURCE_IO | IORESOURCE_MEM; 320 struct resource *devr = &dev->resource[idx], *busr; 321 322 if (dev->bus) { 323 pci_bus_for_each_resource(dev->bus, busr, i) { 324 if (!busr || (busr->flags ^ devr->flags) & type_mask) 325 continue; 326 327 if (devr->start && 328 devr->start >= busr->start && 329 devr->end <= busr->end) 330 return 1; 331 } 332 } 333 334 return 0; 335} 336 337static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev) 338{ 339 struct pci_bus_region region; 340 int i; 341 int limit; 342 343 if (dev->bus->number != 0) 344 return; 345 346 limit = (dev->hdr_type == PCI_HEADER_TYPE_NORMAL) ? 347 PCI_BRIDGE_RESOURCES : PCI_NUM_RESOURCES; 348 349 for (i = 0; i < limit; i++) { 350 if (!dev->resource[i].flags) 351 continue; 352 353 region.start = dev->resource[i].start; 354 region.end = dev->resource[i].end; 355 pcibios_bus_to_resource(dev, &dev->resource[i], ®ion); 356 if (is_valid_resource(dev, i)) 357 pci_claim_resource(dev, i); 358 } 359} 360 361/* 362 * Called after each bus is probed, but before its children 363 * are examined. 364 */ 365void __devinit pcibios_fixup_bus(struct pci_bus *bus) 366{ 367 struct pci_dev *dev; 368 369 if (bus->number == 0) { 370 bus->resource[0] = &pci_ioport_resource; 371 bus->resource[1] = &pci_iomem_resource; 372 } 373 374 if (bus->self) { 375 pci_read_bridge_bases(bus); 376 pcibios_fixup_device_resources(bus->self); 377 } 378 379 list_for_each_entry(dev, &bus->devices, bus_list) 380 pcibios_fixup_device_resources(dev); 381} 382 383/* 384 * Initialization. Try all known PCI access methods. Note that we support 385 * using both PCI BIOS and direct access: in such cases, we use I/O ports 386 * to access config space, but we still keep BIOS order of cards to be 387 * compatible with 2.0.X. This should go away some day. 388 */ 389static int __init pcibios_init(void) 390{ 391 ioport_resource.start = 0xA0000000; 392 ioport_resource.end = 0xDFFFFFFF; 393 iomem_resource.start = 0xA0000000; 394 iomem_resource.end = 0xDFFFFFFF; 395 396 if (insert_resource(&iomem_resource, &pci_iomem_resource) < 0) 397 panic("Unable to insert PCI IOMEM resource\n"); 398 if (insert_resource(&ioport_resource, &pci_ioport_resource) < 0) 399 panic("Unable to insert PCI IOPORT resource\n"); 400 401 if (!pci_probe) 402 return 0; 403 404 if (pci_check_direct() < 0) { 405 printk(KERN_WARNING "PCI: No PCI bus detected\n"); 406 return 0; 407 } 408 409 printk(KERN_INFO "PCI: Probing PCI hardware [mempage %08x]\n", 410 MEM_PAGING_REG); 411 412 pci_root_bus = pci_scan_bus(0, &pci_direct_ampci, NULL); 413 414 pcibios_irq_init(); 415 pcibios_fixup_irqs(); 416 pcibios_resource_survey(); 417 return 0; 418} 419 420arch_initcall(pcibios_init); 421 422char *__init pcibios_setup(char *str) 423{ 424 if (!strcmp(str, "off")) { 425 pci_probe = 0; 426 return NULL; 427 428 } else if (!strncmp(str, "lastbus=", 8)) { 429 pcibios_last_bus = simple_strtol(str+8, NULL, 0); 430 return NULL; 431 } 432 433 return str; 434} 435 436int pcibios_enable_device(struct pci_dev *dev, int mask) 437{ 438 int err; 439 440 err = pci_enable_resources(dev, mask); 441 if (err == 0) 442 pcibios_enable_irq(dev); 443 return err; 444} 445 446/* 447 * disable the ethernet chipset 448 */ 449static void __init unit_disable_pcnet(struct pci_bus *bus, struct pci_ops *o) 450{ 451 u32 x; 452 453 bus->number = 0; 454 455 o->read (bus, PCI_DEVFN(2, 0), PCI_VENDOR_ID, 4, &x); 456 o->read (bus, PCI_DEVFN(2, 0), PCI_COMMAND, 2, &x); 457 x |= PCI_COMMAND_MASTER | 458 PCI_COMMAND_IO | PCI_COMMAND_MEMORY | 459 PCI_COMMAND_SERR | PCI_COMMAND_PARITY; 460 o->write(bus, PCI_DEVFN(2, 0), PCI_COMMAND, 2, x); 461 o->read (bus, PCI_DEVFN(2, 0), PCI_COMMAND, 2, &x); 462 o->write(bus, PCI_DEVFN(2, 0), PCI_BASE_ADDRESS_0, 4, 0x00030001); 463 o->read (bus, PCI_DEVFN(2, 0), PCI_BASE_ADDRESS_0, 4, &x); 464 465#define RDP (*(volatile u32 *) 0xBE030010) 466#define RAP (*(volatile u32 *) 0xBE030014) 467#define __set_RAP(X) do { RAP = (X); x = RAP; } while (0) 468#define __set_RDP(X) do { RDP = (X); x = RDP; } while (0) 469#define __get_RDP() ({ RDP & 0xffff; }) 470 471 __set_RAP(0); 472 __set_RDP(0x0004); /* CSR0 = STOP */ 473 474 __set_RAP(88); /* check CSR88 indicates an Am79C973 */ 475 BUG_ON(__get_RDP() != 0x5003); 476 477 for (x = 0; x < 100; x++) 478 asm volatile("nop"); 479 480 __set_RDP(0x0004); /* CSR0 = STOP */ 481} 482 483/* 484 * initialise the unit hardware 485 */ 486asmlinkage void __init unit_pci_init(void) 487{ 488 struct pci_bus bus; /* Fake bus and device */ 489 struct pci_ops *o = &pci_direct_ampci; 490 u32 x; 491 492 set_intr_level(XIRQ1, GxICR_LEVEL_3); 493 494 memset(&bus, 0, sizeof(bus)); 495 496 MEM_PAGING_REG = 0xE8000000; 497 498 /* we need to set up the bridge _now_ or we won't be able to access the 499 * PCI config registers 500 */ 501 BRIDGEREGW(PCI_COMMAND) |= 502 PCI_COMMAND_SERR | PCI_COMMAND_PARITY | 503 PCI_COMMAND_MEMORY | PCI_COMMAND_IO | PCI_COMMAND_MASTER; 504 BRIDGEREGW(PCI_STATUS) = 0xF800; 505 BRIDGEREGB(PCI_LATENCY_TIMER) = 0x10; 506 BRIDGEREGL(PCI_BASE_ADDRESS_0) = 0x80000000; 507 BRIDGEREGB(PCI_INTERRUPT_LINE) = 1; 508 BRIDGEREGL(0x48) = 0x98000000; /* AMPCI base addr */ 509 BRIDGEREGB(0x41) = 0x00; /* secondary bus 510 * number */ 511 BRIDGEREGB(0x42) = 0x01; /* subordinate bus 512 * number */ 513 BRIDGEREGB(0x44) = 0x01; 514 BRIDGEREGL(0x50) = 0x00000001; 515 BRIDGEREGL(0x58) = 0x00001002; 516 BRIDGEREGL(0x5C) = 0x00000011; 517 518 /* we also need to set up the PCI-PCI bridge */ 519 bus.number = 0; 520 521 /* IO: 0x00000000-0x00020000 */ 522 o->read (&bus, PCI_DEVFN(3, 0), PCI_COMMAND, 2, &x); 523 x |= PCI_COMMAND_MASTER | 524 PCI_COMMAND_IO | PCI_COMMAND_MEMORY | 525 PCI_COMMAND_SERR | PCI_COMMAND_PARITY; 526 o->write(&bus, PCI_DEVFN(3, 0), PCI_COMMAND, 2, x); 527 528 o->read (&bus, PCI_DEVFN(3, 0), PCI_IO_BASE, 1, &x); 529 o->read (&bus, PCI_DEVFN(3, 0), PCI_IO_BASE_UPPER16, 4, &x); 530 o->read (&bus, PCI_DEVFN(3, 0), PCI_MEMORY_BASE, 4, &x); 531 o->read (&bus, PCI_DEVFN(3, 0), PCI_PREF_MEMORY_BASE, 4, &x); 532 533 o->write(&bus, PCI_DEVFN(3, 0), PCI_IO_BASE, 1, 0x01); 534 o->read (&bus, PCI_DEVFN(3, 0), PCI_IO_BASE, 1, &x); 535 o->write(&bus, PCI_DEVFN(3, 0), PCI_IO_BASE_UPPER16, 4, 0x00020000); 536 o->read (&bus, PCI_DEVFN(3, 0), PCI_IO_BASE_UPPER16, 4, &x); 537 o->write(&bus, PCI_DEVFN(3, 0), PCI_MEMORY_BASE, 4, 0xEBB0EA00); 538 o->read (&bus, PCI_DEVFN(3, 0), PCI_MEMORY_BASE, 4, &x); 539 o->write(&bus, PCI_DEVFN(3, 0), PCI_PREF_MEMORY_BASE, 4, 0xE9F0E800); 540 o->read (&bus, PCI_DEVFN(3, 0), PCI_PREF_MEMORY_BASE, 4, &x); 541 542 unit_disable_pcnet(&bus, o); 543} 544