Changeset 17130
- Timestamp:
- 05/25/11 15:48:31 (2 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/linux/laguna/linux-2.6.31.14/arch/arm/mach-cns3xxx/pcie.c
r17097 r17130 22 22 ******************************************************************************/ 23 23 24 //#include <linux/config.h>25 24 #include <linux/kernel.h> 26 25 #include <linux/pci.h> … … 42 41 #include <asm/uaccess.h> 43 42 #include <mach/pm.h> 44 #ifdef CONFIG_DEBUG_FS 45 #include <linux/debugfs.h> 46 #include <linux/seq_file.h> 47 #endif 48 49 50 #define CONFIG_CMD(bus, device_fn, where) (0x80000000 | ((bus) << 16) | ((device_fn) << 8) | ((where) & ~3)) 51 #define PCIE_ID(bus, device_fn, where) (((bus&0xf)<<20)| (device_fn<<12) | (where)) 52 53 #define CNS3XXX_PCIE_DEBUG 54 // #undef CNS3XXX_PCIE_DEBUG 55 #define CNS3XXX_PCIE_RESET 56 57 58 static struct pci_dev *pcie0_bridge = NULL; 59 static struct pci_dev *pcie1_bridge = NULL; 60 static volatile u32 port0_cfg; 61 static int pcie_linked[2]; 43 44 DEFINE_SPINLOCK(pci_config_lock); 45 46 static int pcie_linked[2] = {0, 0}; // if 1, mean link ok. 62 47 63 48 u32 cns3xxx_pcie0_irqs[2] = { IRQ_CNS3XXX_PCIE0_RC, IRQ_CNS3XXX_PCIE0_DEVICE, }; 64 49 u32 cns3xxx_pcie1_irqs[2] = { IRQ_CNS3XXX_PCIE1_RC, IRQ_CNS3XXX_PCIE1_DEVICE, }; 65 extern struct proc_dir_entry *cns3xxx_proc_dir; 66 67 #ifdef CNS3XXX_PCIE_DEBUG 68 struct proc_dir_entry *pcie_proc_entry; 69 extern struct pci_dev *pdev_tmp; 70 extern void e1000_shutdown(struct pci_dev *); 71 extern int e1000_resume(struct pci_dev *); 72 73 DEFINE_SPINLOCK(pci_config_lock); 74 75 /* 76 Read String into Buffer, Max String buffer is 100 77 */ 78 static ssize_t readstring(char *buff, const char *buf, size_t count) 79 { 80 int i = 0; 81 if (count) { 82 char c; 83 84 for (i = 0; i < count && i < 100; i++) { 85 if (get_user(c, buf + i)) 86 return -EFAULT; 87 buff[i] = c; 88 } 89 buff[i] = 0; 90 } 91 return count; 92 } 93 94 static int cns3xxx_pcie_read_proc(char *page, char **start, off_t off, 95 int count, int *eof, void *data) 96 { 97 int num = 0; 98 // int i; 99 100 // num += sprintf(page+num, "=== Config Type 0 ==="); 101 // for (i=0; i<0x3f; i+=4) { 102 // if (i%16 == 0) num += sprintf(page+num, "\n%x: ", i); 103 // num += sprintf(page+num, "%4x ", __raw_readl(CNS3XXX_PCIE0_HOST_BASE_VIRT + i)); 104 // if (i%4 == 0) num += sprintf(page+num, " "); 105 // } 106 107 return num; 108 109 } 110 111 //#define PCIE_E1000_DEVICE_ID 0x107D /* Intel(R) PRO/1000 PT server adapter */ 112 #define PCIE_E1000_DEVICE_ID 0x10B9 113 //#define PCIE_E1000_DEVICE_ID 0x10D3 /* Intel(R) Gigabit CT desktop adapter */ 114 static int cns3xxx_pcie_write_proc(struct file *file, const char *buffer, 115 unsigned long count, void *data) 116 { 117 char read_buff[100], buf_cmd[100], buf_param1[100]; 118 u16 pos, aspm_sp, aspm_ctl, link_ctl; 119 u16 reg16; 120 u32 reg32, i = 0, lc = 1000; 121 struct pci_dev *prc = NULL, *pdev = NULL; 122 readstring((char *)read_buff, (const char *)buffer, count); 123 sscanf(read_buff, "%s %s\n", (char *)&buf_cmd, (char *)&buf_param1); 124 125 prc = pci_get_device(PCIB_VENDOR_ID, PCIB_DEVICE_ID, NULL); 126 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, PCIE_E1000_DEVICE_ID, NULL); 127 printk("prc:%x pdev:%x \n", (u32) prc, (u32) pdev); 128 129 if (pdev == NULL) { 130 printk("PCIe Device is not e1000 NIC\n"); 131 return -EINVAL; 132 } 133 134 if (strcmp(buf_cmd, "pm") == 0) { 135 if (strcmp(buf_param1, "suspend") == 0) { 136 pdev->driver->shutdown(pdev); 137 } else if (strcmp(buf_param1, "resume") == 0) { 138 //printk("resume:%x \n", (u32)pdev->driver->resume); 139 pdev->driver->resume(pdev); 140 } else 141 printk("syntax: pm suspend/resume\n"); 142 return count; 143 } 144 145 if (strcmp(buf_cmd, "aspm") == 0) { 146 if (strcmp(buf_param1, "L0") == 0) { 147 /* RC */ 148 pos = pci_find_capability(prc, PCI_CAP_ID_EXP); 149 pci_read_config_word(prc, pos + PCI_EXP_LNKCTL, 150 &aspm_ctl); 151 aspm_ctl &= ~0x3; 152 pci_write_config_word(prc, pos + PCI_EXP_LNKCTL, 153 aspm_ctl); 154 /* Device */ 155 pos = pci_find_capability(pdev, PCI_CAP_ID_EXP); 156 pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, 157 &aspm_ctl); 158 aspm_ctl &= ~0x3; 159 pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, 160 aspm_ctl); 161 /* Verify Reg only */ 162 pci_read_config_word(prc, pos + PCI_EXP_LNKCTL, 163 &aspm_ctl); 164 printk("RC ASPM Control: 0x%x\n", (aspm_ctl & 0x3)); 165 pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, 166 &aspm_ctl); 167 printk("Device ASPM Control: 0x%x\n", (aspm_ctl & 0x3)); 168 } else if (strcmp(buf_param1, "L0sL1") == 0) { 169 /* Device */ 170 pos = pci_find_capability(pdev, PCI_CAP_ID_EXP); 171 pci_read_config_word(pdev, pos + PCI_EXP_LNKCAP, 172 &aspm_sp); 173 printk("aspm_sp of device: 0x%x\n", aspm_sp); 174 aspm_sp = (aspm_sp >> 10) & 0x3; 175 pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, 176 &aspm_ctl); 177 aspm_ctl &= ~0x3; 178 aspm_ctl |= aspm_sp; 179 pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, 180 aspm_ctl); 181 /* RC */ 182 pos = pci_find_capability(prc, PCI_CAP_ID_EXP); 183 pci_read_config_word(prc, pos + PCI_EXP_LNKCAP, 184 &aspm_sp); 185 aspm_sp = (aspm_sp >> 10) & 0x3; 186 pci_read_config_word(prc, pos + PCI_EXP_LNKCTL, 187 &aspm_ctl); 188 aspm_ctl &= ~0x3; 189 aspm_ctl |= aspm_sp; 190 pci_write_config_word(prc, pos + PCI_EXP_LNKCTL, 191 aspm_ctl); 192 /* Verify Reg only */ 193 pci_read_config_word(prc, pos + PCI_EXP_LNKCTL, 194 &aspm_ctl); 195 printk("RC ASPM Control: 0x%x\n", (aspm_ctl & 0x3)); 196 pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, 197 &aspm_ctl); 198 printk("Device ASPM Control: 0x%x\n", (aspm_ctl & 0x3)); 199 } else 200 printk("syntax: aspm L0/L0sL1\n"); 201 return count; 202 } 203 #define PCI_EXP_LNKCTL_LBMIE 0x0400 /* Link Bandwidth Management Interrupt Enable */ 204 #define PCI_EXP_LNKCTL_LABIE 0x0800 /* Lnk Autonomous Bandwidth Interrupt Enable */ 205 206 if (strcmp(buf_cmd, "relinkintc") == 0) { 207 u32 *ptr; 208 printk("Relink Interrupt Test \n"); 209 210 ptr = (u32 *) 0xFFF07978; 211 *ptr = 0; 212 213 pos = pci_find_capability(prc, PCI_CAP_ID_EXP); 214 pci_read_config_word(prc, pos + PCI_EXP_LNKCTL, ®16); 215 reg16 |= PCI_EXP_LNKCTL_LBMIE; /* Link Bandwidth Management Interrupt Enable */ 216 reg16 |= PCI_EXP_LNKCTL_LABIE; /* Lnk Autonomous Bandwidth Interrupt Enable */ 217 reg16 |= PCI_EXP_LNKCTL_RL; /* Retrain Link */ 218 printk("Addr:%X(%d) Value:%X \n", pos + PCI_EXP_LNKCTL, 219 pos + PCI_EXP_LNKCTL, reg16); 220 pci_write_config_word(prc, pos + PCI_EXP_LNKCTL, reg16); 221 pci_read_config_word(prc, pos + PCI_EXP_LNKCTL, ®16); 222 printk("Value:%X \n", reg16); 223 224 ptr = (u32 *) 0xFFF07974; 225 printk(" 0x974:%08X , LBM Intc: %s \n", *ptr, 226 ((*ptr >> 13) & 0x1) == 0 ? "Disable" : "Enable"); 227 } 228 if (strcmp(buf_cmd, "relink") == 0) { 229 /* Link Down */ 230 printk("[%d] Link down \n", i++); 231 reg32 = __raw_readl(CNS3XXX_MISC_BASE_VIRT + 0x95C); 232 __raw_writel((reg32 & ~0x1), CNS3XXX_MISC_BASE_VIRT + 0x95C); 233 mdelay(100); 234 /* Link Up */ 235 printk("[%d] Link Up \n", i++); 236 __raw_writel((reg32 | 0x1), CNS3XXX_MISC_BASE_VIRT + 0x95C); 237 printk("Wait for PCIe0 link up..."); 238 do { 239 reg32 = __raw_readl(CNS3XXX_MISC_BASE_VIRT + 0x960); 240 } while (!(reg32 & 0x1)); 241 printk("OK.\n"); 242 243 } 244 if (strcmp(buf_cmd, "hotreset") == 0) { 245 int i = 0; 246 int rc_buf[1024 / 4], dev_buf[1024 / 4]; 247 #if 0 248 if (pdev->driver) { 249 pdev->driver->remove(pdev); 250 printk("Device driver has been removed.\n"); 251 } 252 #endif 253 printk("PCIe hot reset.\n"); 254 255 for (i = 0; i < 1024; i += 4) { 256 pci_read_config_dword(prc, i, 257 &rc_buf[i == 0 ? 0 : i / 4]); 258 pci_read_config_dword(pdev, i, 259 &dev_buf[i == 0 ? 0 : i / 4]); 260 printk("[%03X(%04d)] RC:%08X DEV:%08X\n", i, 261 i, rc_buf[i == 0 ? 0 : i / 4], 262 dev_buf[i == 0 ? 0 : i / 4]); 263 } 264 #if 0 265 266 printk("[%d] Hot Reset\n", i++); 267 reg32 = __raw_readl(CNS3XXX_MISC_BASE_VIRT + 0x95C); 268 reg32 |= (0x1 << 20); /* Assert hot reset */ 269 __raw_writel(reg32, CNS3XXX_MISC_BASE_VIRT + 0x95C); 270 mdelay(100); 271 reg32 &= ~(0x1 << 20); /* De-assert hot reset */ 272 __raw_writel(reg32, CNS3XXX_MISC_BASE_VIRT + 0x95C); 273 #endif 274 275 /* Follow spec to do hotreset */ 276 #if 1 277 { 278 u16 tmp; 279 280 pci_read_config_word(prc, PCI_CB_BRIDGE_CONTROL, &tmp); 281 printk("[%d]BRIDGE REG: %04X \n", i, tmp); 282 tmp |= PCI_CB_BRIDGE_CTL_CB_RESET; 283 pci_write_config_word(prc, PCI_CB_BRIDGE_CONTROL, tmp); 284 #if 1 285 mdelay(3); 286 tmp &= ~PCI_CB_BRIDGE_CTL_CB_RESET; 287 pci_write_config_word(prc, PCI_CB_BRIDGE_CONTROL, tmp); 288 pci_read_config_word(prc, PCI_CB_BRIDGE_CONTROL, &tmp); 289 printk("[%d]BRIDGE REG: %04X \n", i, tmp); 290 #endif 291 } 292 293 #endif 294 for (i = 0; i < 1024; i += 4) { 295 pci_write_config_dword(prc, i, 296 rc_buf[i == 0 ? 0 : i / 4]); 297 pci_write_config_dword(pdev, i, 298 dev_buf[i == 0 ? 0 : i / 4]); 299 } 300 return count; 301 } 302 303 if (strcmp(buf_cmd, "retrain") == 0) { 304 for (i = 0; i < lc; i++) { 305 pos = pci_find_capability(prc, PCI_CAP_ID_EXP); 306 pci_read_config_word(prc, pos + PCI_EXP_LNKCTL, 307 &link_ctl); 308 link_ctl |= 0x1 << 5; 309 pci_write_config_word(prc, pos + PCI_EXP_LNKCTL, 310 link_ctl); 311 312 // printk("lc: %d: Wait for link training done...",i+1); 313 do { 314 pci_read_config_word(prc, pos + PCI_EXP_LNKSTA, 315 ®16); 316 } while (reg16 & (0x1 << 11)); 317 // printk("OK.\n"); 318 319 printk("lc: %d: Wait for DL active...", i + 1); 320 do { 321 pci_read_config_word(prc, pos + PCI_EXP_LNKSTA, 322 ®16); 323 } while (!(reg16 & (0x1 << 13))); 324 printk("OK.\n"); 325 } 326 return count; 327 } 328 329 return count; 330 } 331 332 static int __init cns3xxx_proc_init(void) 333 { 334 if (cns3xxx_proc_dir == NULL) { 335 printk("Please Create Proc First \n"); 336 BUG(); 337 } 338 pcie_proc_entry = 339 create_proc_entry("pcie", S_IFREG | S_IRUGO, cns3xxx_proc_dir); 340 341 if (pcie_proc_entry) { 342 pcie_proc_entry->read_proc = cns3xxx_pcie_read_proc; 343 pcie_proc_entry->write_proc = cns3xxx_pcie_write_proc; 344 } 345 346 return 1; 347 } 348 #endif 349 350 static u32 access_base[2][3] = { 351 { 352 CNS3XXX_PCIE0_HOST_BASE_VIRT, 353 CNS3XXX_PCIE0_CFG0_BASE_VIRT, 354 CNS3XXX_PCIE0_CFG1_BASE_VIRT, 355 }, 356 { 357 CNS3XXX_PCIE1_HOST_BASE_VIRT, 358 CNS3XXX_PCIE1_CFG0_BASE_VIRT, 359 CNS3XXX_PCIE1_CFG1_BASE_VIRT, 360 }, 361 }; 362 363 static u32 cns3xxx_pci_cfg_base(struct pci_bus *bus, unsigned int devfn, 364 int where) 50 51 static u32 access_base[2][3] = { 52 { CNS3XXX_PCIE0_HOST_BASE_VIRT, CNS3XXX_PCIE0_CFG0_BASE_VIRT, CNS3XXX_PCIE0_CFG1_BASE_VIRT}, 53 { CNS3XXX_PCIE1_HOST_BASE_VIRT, CNS3XXX_PCIE1_CFG0_BASE_VIRT, CNS3XXX_PCIE1_CFG1_BASE_VIRT}, 54 }; 55 56 static int cns3xxx_pci_cfg_base(struct pci_bus *bus, 57 unsigned int devfn, int where) 365 58 { 366 59 int domain = pci_domain_nr(bus); 367 int busno = bus->number; 368 int slot = PCI_SLOT(devfn); 369 int type; 60 int slot = PCI_SLOT(devfn); 370 61 u32 base; 371 62 372 /* If there is no link, just show the CNS PCI bridge. */ 373 if (!pcie_linked[domain] && (busno > 0 || slot > 0)) 63 if ((!pcie_linked[domain]) && (bus->number || slot)) 374 64 return 0; 375 65 376 /* 377 * The CNS PCI bridge doesn't fit into the PCI hierarchy, though 378 * we still want to access it. For this to work, we must place 379 * the first device on the same bus as the CNS PCI bridge. 380 */ 381 if (busno == 0) { 66 if (!(bus->number)) { 382 67 if (slot > 1) 383 68 return 0; 384 type = slot; 69 // CFG0 Type 70 base = access_base[domain][slot]; 385 71 } else { 386 type = 2; 387 } 388 389 where &= 0xffc; 390 base = access_base[domain][type]; 391 392 return base + PCIE_ID(busno, devfn, where); 393 } 394 395 static int _cns3xxx_pci_read_config(struct pci_bus *bus, 396 unsigned int devfn, int where, int size, 397 u32 * val) 398 { 399 u32 v = 0; 400 u32 base; 401 u8 modify_class = 0; 402 int domain; 403 404 domain = pci_domain_nr(bus); 405 406 switch (size) { 407 case 1: 408 _cns3xxx_pci_read_config(bus, devfn, where, 4, &v); 409 410 switch (where % 4) { 411 case 0: 412 v &= 0x000000FF; 413 break; 414 case 1: 415 v &= 0x0000FF00; 416 v = v >> 8; 417 break; 418 case 2: 419 v &= 0x00FF0000; 420 v = v >> 16; 421 break; 422 case 3: 423 v &= 0xFF000000; 424 v = v >> 24; 425 break; 426 } 427 break; 428 429 case 2: 430 431 _cns3xxx_pci_read_config(bus, devfn, where, 4, &v); 432 433 switch (where % 4) { 434 case 0: 435 case 1: 436 v &= 0x0000FFFF; 437 break; 438 case 2: 439 case 3: 440 v &= 0xFFFF0000; 441 v = v >> 16; 442 break; 443 } 444 break; 445 446 case 4: 447 /* Read Class Code */ 448 if (bus->number == 0 && devfn == 0 && where == 0x8) { 449 modify_class = 1; 450 break; 451 } 452 453 base = cns3xxx_pci_cfg_base(bus, devfn, where); 454 if (!base) { 455 v = 0xffffffff; 456 break; 457 } 458 459 v = __raw_readl(base); 460 break; 461 } 462 463 /* RC's class is 0xb, but Linux PCI driver needs 0x604 for a PCIe bridge. */ 464 /* So we must dedicate the class code to 0x604 here */ 465 if (modify_class) { 466 v &= 0xff; 467 v |= (0x604 << 16); 468 } 469 // printk("[RLDBG] domain:%d bus:%d devfn:%d where:%d(0x%03x) v:0x%08x\n", domain, bus->number, devfn, where, where , v); 470 *val = v; 471 472 return PCIBIOS_SUCCESSFUL; 473 } 72 // CFG1 Type 73 base = access_base[domain][2]; 74 } 75 base += (((bus->number & 0xf) << 20)| (devfn << 12) | (where & 0xfc)); 76 return base; 77 } 78 474 79 static int cns3xxx_pci_read_config(struct pci_bus *bus, 475 80 unsigned int devfn, int where, int size, 476 81 u32 * val) 477 82 { 478 unsigned long flags; 479 int ret; 480 #if 0 481 local_irq_save(flags); 482 #else 483 spin_lock_irqsave(&pci_config_lock, flags); 484 #endif 485 486 ret = _cns3xxx_pci_read_config(bus, devfn, where, size, val); 487 488 #if 0 489 local_irq_restore(flags); 490 #else 491 spin_unlock_irqrestore(&pci_config_lock, flags); 492 #endif 493 494 return ret; 495 } 496 497 static int _cns3xxx_pci_write_config(struct pci_bus *bus, 498 unsigned int devfn, int where, int size, 499 u32 val) 500 { 501 u32 v; 83 u32 v = 0xffffffff; 502 84 u32 base; 503 int domain; 504 505 domain = pci_domain_nr(bus); 506 507 switch (size) { 508 case 1: 509 510 val &= 0x000000FF; 511 _cns3xxx_pci_read_config(bus, devfn, where, 4, &v); 512 513 switch (where % 4) { 514 case 0: 515 v &= 0xFFFFFF00; 516 v |= val; 517 break; 518 case 1: 519 v &= 0xFFFF00FF; 520 v |= (val << 8); 521 break; 522 case 2: 523 v &= 0xFF00FFFF; 524 v |= (val << 16); 525 break; 526 case 3: 527 v &= 0x00FFFFFF; 528 v |= (val << 24); 529 break; 530 } 531 _cns3xxx_pci_write_config(bus, devfn, where, 4, v); 532 533 break; 534 535 case 2: 536 537 val &= 0x0000FFFF; 538 _cns3xxx_pci_read_config(bus, devfn, where, 4, &v); 539 540 switch (where % 4) { 541 case 0: 542 case 1: 543 v &= 0xFFFF0000; 544 v |= val; 545 break; 546 case 2: 547 case 3: 548 v &= 0x0000FFFF; 549 v |= (val << 16); 550 break; 551 } 552 _cns3xxx_pci_write_config(bus, devfn, where, 4, v); 553 break; 554 555 case 4: 556 base = cns3xxx_pci_cfg_base(bus, devfn, where); 557 if (!base) { 558 v = 0xffffffff; 559 break; 560 } 561 562 __raw_writel(val, base); 563 break; 564 } 565 566 85 u32 mask = (0x1ull << (size * 8)) - 1; 86 int shift = (where % 4) * 8; 87 88 base = cns3xxx_pci_cfg_base(bus, devfn, where); 89 if (!base) { 90 *val = 0xFFFFFFFF; 91 return PCIBIOS_SUCCESSFUL; 92 } 93 94 v = __raw_readl(base); 95 if (bus->number == 0 && devfn == 0 && 96 (where & 0xffc) == PCI_CLASS_REVISION) { 97 /* RC's class is 0xb, but Linux PCI driver needs 0x604 for a PCIe bridge. */ 98 /* So we must dedicate the class code to 0x604 here */ 99 v &= 0xff; 100 v |= (0x604 << 16); 101 } 102 103 *val = (v >> shift) & mask; 567 104 return PCIBIOS_SUCCESSFUL; 568 105 } 569 570 106 571 107 static int cns3xxx_pci_write_config(struct pci_bus *bus, … … 573 109 u32 val) 574 110 { 575 unsigned long flags; 576 int ret; 577 #if 0 578 local_irq_save(flags); 579 #else 580 spin_lock_irqsave(&pci_config_lock, flags); 581 #endif 582 583 ret = _cns3xxx_pci_write_config(bus, devfn, where, size, val); 584 585 #if 0 586 local_irq_restore(flags); 587 #else 588 spin_unlock_irqrestore(&pci_config_lock, flags); 589 #endif 590 return ret; 591 592 } 593 111 u32 v; 112 u32 base; 113 u32 mask = (0x1ull << (size * 8)) - 1; 114 int shift = (where % 4) * 8; 115 116 base = cns3xxx_pci_cfg_base(bus, devfn, where); 117 if (!base) 118 return PCIBIOS_SUCCESSFUL; 119 120 v = __raw_readl(base); 121 v &= ~(mask << shift); 122 v |= (val & mask) << shift; 123 __raw_writel(v, base); 124 125 return PCIBIOS_SUCCESSFUL; 126 } 594 127 595 128 static struct pci_ops cns3xxx_pcie_ops = { … … 625 158 .flags = IORESOURCE_MEM, 626 159 }; 627 #if 0628 static struct resource cns3xxx_pci_prefetch_mem = {629 .name = "PCI prefetchable",630 .start = PCI_PREFETCH_MEMORY_SPACE_START,631 .end = PCI_PREFETCH_MEMORY_SPACE_END,632 .flags = IORESOURCE_MEM | IORESOURCE_PREFETCH,633 };634 #endif635 160 636 161 static int __init cns3xxx_pci_setup_resources(int nr, struct resource **resource) 637 162 { 638 int ret = 1;639 640 163 if(nr==0){ 641 ret = request_resource(&iomem_resource, &cns3xxx_pcie0_io); 642 if (ret) 643 panic("PCIe0: unable to allocate I/O region\n"); 644 ret = request_resource(&iomem_resource, &cns3xxx_pcie0_mem); 645 if (ret) 646 panic("PCIe0: unable to allocate memory region\n"); 164 BUG_ON(request_resource(&iomem_resource, &cns3xxx_pcie0_io) || 165 request_resource(&iomem_resource, &cns3xxx_pcie0_mem)); 647 166 resource[0] = &cns3xxx_pcie0_io; 648 167 resource[1] = &cns3xxx_pcie0_mem; 649 ret = 0;650 168 }else{ 651 ret = request_resource(&iomem_resource, &cns3xxx_pcie1_io); 652 if (ret) 653 panic("PCIe1: unable to allocate I/O region\n"); 654 ret = request_resource(&iomem_resource, &cns3xxx_pcie1_mem); 655 if (ret) 656 panic("PCIe1: unable to allocate memory region\n"); 169 BUG_ON(request_resource(&iomem_resource, &cns3xxx_pcie1_io) || 170 request_resource(&iomem_resource, &cns3xxx_pcie1_mem)); 657 171 resource[0] = &cns3xxx_pcie1_io; 658 172 resource[1] = &cns3xxx_pcie1_mem; 659 ret = 0; 660 } 661 662 return ret; 663 } 664 665 static irqreturn_t cns3xxx_pcie0_dev_intc(int irq, void *dev_id) 666 { 667 668 #if 0 669 u32 status; 670 /* Read PCIe0 interrupt */ 671 status = __raw_readl( CNS3XXX_PCIE0_INT_STATUS ); 672 #ifdef CNS3XXX_PCIE_DEBUG 673 printk(KERN_DEBUG "PCIe0 Device interrupt status: 0x%x\n", status); 674 #endif 675 676 /* Device interrupt is self-clear */ 677 // __raw_writel(status, CNS3XXX_PCIE0_INT_STATUS ); 678 #endif 679 680 return IRQ_HANDLED; 681 } 682 683 static irqreturn_t cns3xxx_pcie0_rc_intc(int irq, void *dev_id) 684 { 685 u32 status; 686 687 /* Read PCIe0 interrupt */ 688 status = __raw_readl( CNS3XXX_PCIE0_INT_STATUS ); 689 690 // if ((status & 0xFF) == 1) 691 // printk(KERN_DEBUG "PCIe0 interrupt status: 0x%x\n",status); 692 // else 693 // printk(KERN_DEBUG "PCIe0 RC interrupt status: 0x%x\n",status); 694 695 /* Write 1 to clear PCIe0 RC interrupt */ 696 status &= 0xFFF0; 697 if (status) 698 __raw_writel(status, CNS3XXX_PCIE0_INT_STATUS ); 699 700 return IRQ_HANDLED; 701 } 702 703 static irqreturn_t cns3xxx_pcie1_dev_intc(int irq, void *dev_id) 704 { 705 706 #if 0 707 u32 status; 708 /* Read PCIe0 interrupt */ 709 status = __raw_readl( CNS3XXX_PCIE1_INT_STATUS ); 710 #ifdef CNS3XXX_PCIE_DEBUG 711 printk(KERN_DEBUG "PCIe0 Device interrupt status: 0x%x\n", status); 712 #endif 713 714 /* Device interrupt is self-clear */ 715 // __raw_writel( CNS3XXX_PCIE1_INT_STATUS ); 716 #endif 717 718 return IRQ_HANDLED; 719 } 720 721 static irqreturn_t cns3xxx_pcie1_rc_intc(int irq, void *dev_id) 722 { 723 u32 status; 724 725 /* Read PCIe0 interrupt */ 726 status = __raw_readl( CNS3XXX_PCIE1_INT_STATUS ); 727 728 #if 0 729 #ifdef CNS3XXX_PCIE_DEBUG 730 if ((status & 0xFF) == 1) 731 printk(KERN_DEBUG "PCIe1 interrupt status: 0x%x\n",status); 732 else 733 printk(KERN_DEBUG "PCIe1 RC interrupt status: 0x%x\n",status); 734 #endif 735 #endif 736 737 /* Write 1 to clear PCIe0 RC interrupt */ 738 status &= 0xFFF0; 739 if (status) 740 __raw_writel(status, CNS3XXX_PCIE1_INT_STATUS ); 741 742 return IRQ_HANDLED; 743 } 744 173 } 174 return 0; 175 } 745 176 746 177 int __init cns3xxx_pci_setup(int nr, struct pci_sys_data *sys) 747 178 { 748 if (nr > 0) { 749 printk("[RLDBG] NR > 1 \n"); 750 return 0; 751 } 752 753 if (cns3xxx_pci_setup_resources(sys->domain,sys->resource)) { 754 BUG(); 755 } 756 179 BUG_ON(cns3xxx_pci_setup_resources(sys->domain,sys->resource)); 757 180 return 1; 758 181 } … … 760 183 struct pci_bus *cns3xxx_pci_scan_bus(int nr, struct pci_sys_data *sys) 761 184 { 762 return pci_scan_bus(sys->busnr, &cns3xxx_pcie_ops, sys); 185 struct pci_bus *ret; 186 ret = pci_scan_bus(sys->busnr, &cns3xxx_pcie_ops, sys); 187 pci_assign_unassigned_resources(); 188 return ret; 763 189 } 764 190 … … 772 198 u32 reg; 773 199 u32 time; 774 reg = __raw_readl(port == 0 ? CNS3XXX_PCIE0_CTRL : CNS3XXX_PCIE1_CTRL);775 // reg |= 0x1;776 /* Enable Appluication Request to 1, it will exit L1 automatically ,777 but when chip back, it will use another clock, still can use 0x1 */778 reg |= 0x3;779 __raw_writel(reg, port == 0 ? CNS3XXX_PCIE0_CTRL : CNS3XXX_PCIE1_CTRL);780 printk("PCIe: Port[%d] Enable PCIe LTSSM\n", port);781 printk("PCIe: Port[%d] Check data link layer...", port);782 200 783 201 time = jiffies; /* set the start time for the receive */ 784 202 while (1) { 785 203 reg = __raw_readl( port == 0 ? CNS3XXX_PCIE0_PM_DEBUG : CNS3XXX_PCIE1_PM_DEBUG); /* check link up */ 786 reg = 787 __raw_readl(port == 788 0 ? CNS3XXX_PCIE0_PM_DEBUG : 789 CNS3XXX_PCIE1_PM_DEBUG); 204 reg = __raw_readl( port == 0 ? CNS3XXX_PCIE0_PM_DEBUG : CNS3XXX_PCIE1_PM_DEBUG); 790 205 if (reg & 0x1) { 791 printk("Link up.\n"); 792 pcie_linked[port] = 1; 206 pcie_linked[port]++; 793 207 break; 794 208 } else if (time_after(jiffies, (unsigned long)(time + 50))) { 795 printk("Device not found.\n");796 209 break; 797 210 } … … 805 218 u32 devfn = 0; 806 219 u8 pri_bus, sec_bus, sub_bus; 807 u16 pos, dc; 220 u8 cp, u8tmp; 221 u16 u16tmp,pos,dc; 808 222 u32 mem_base, host_base, io_base, cfg0_base; 809 //int i;810 223 811 224 bus.number = 0; 812 225 bus.ops = &cns3xxx_pcie_ops; 813 226 sd.domain = port; 814 bus.sysdata = &sd; 815 227 bus.sysdata = &sd; 816 228 817 229 mem_base = ( port == 0 ? CNS3XXX_PCIE0_MEM_BASE : CNS3XXX_PCIE1_MEM_BASE ); … … 840 252 pci_bus_write_config_word(&bus, devfn, PCI_IO_LIMIT_UPPER16, cfg0_base); 841 253 254 pci_bus_read_config_byte(&bus, devfn, PCI_CAPABILITY_LIST, &cp); 255 while (cp != 0) { 256 pci_bus_read_config_byte(&bus, devfn, cp, &u8tmp); 257 // Read Next ID 258 pci_bus_read_config_word(&bus, devfn, cp, &u16tmp); 259 cp = (u16tmp & 0xFF00) >> 8; 260 } 261 842 262 /* Modify device's Max_Read_Request size */ 843 263 devfn = PCI_DEVFN(1,0); 844 264 if (!pcie_linked[port]) 845 265 return; 266 267 pci_bus_read_config_byte(&bus, devfn, PCI_CAPABILITY_LIST, &cp); 268 while (cp != 0) { 269 pci_bus_read_config_byte(&bus, devfn, cp, &u8tmp); 270 // Read Next ID 271 pci_bus_read_config_word(&bus, devfn, cp, &u16tmp); 272 cp = (u16tmp & 0xFF00) >> 8; 273 } 846 274 847 275 /* Set Device Max_Read_Request_Size to 128 byte */ … … 851 279 pci_bus_write_config_word(&bus, devfn, pos + PCI_EXP_DEVCTL, dc); 852 280 pci_bus_read_config_word(&bus, devfn, pos + PCI_EXP_DEVCTL, &dc); 853 if (!(dc & (0x3 << 12)))854 printk ("PCIe: Set Device Max_Read_Request_Size to 128 byte\n");855 856 } 857 858 #include <mach/board.h> 859 860 #define GPIOA_MEM_MAP_VALUE(reg_offset) (*((uint32_t volatile *)(CNS3XXX_GPIOA_BASE_VIRT + reg_offset))) 861 #define GPIOA_INPUT GPIOA_MEM_MAP_VALUE(0x004) 862 #define GPIOA_DIR GPIOA_MEM_MAP_VALUE(0x008) 281 282 if (!port) { 283 /* Disable PCIe0 Interrupt Mask INTA to INTD */ 284 __raw_writel(~0x3FFF, CNS3XXX_MISC_BASE_VIRT + 0x978); 285 } else { 286 /* Disable PCIe1 Interrupt Mask INTA to INTD */ 287 __raw_writel(~0x3FFF, CNS3XXX_MISC_BASE_VIRT + 0xA78); 288 } 289 } 290 863 291 864 292 void __init cns3xxx_pcie0_preinit(void) 865 293 { 866 int iInternalSource = 0;867 u32 u32tmp;868 869 GPIOA_DIR &= ~(0xc00);870 // printk("\nGPIOA_INPUT:0x%.8x\n\n", GPIOA_INPUT);871 872 if((GPIOA_INPUT & 0x400) && (GPIOA_INPUT & 0x800)) {873 // printk("Board version 1.x.\n");874 #ifdef CONFIG_CNS3XXX_AUTO_CLOCK_SOURCE875 iInternalSource = 0;876 #endif877 }878 else {879 // printk("Board version 2.x.\n");880 #ifdef CONFIG_CNS3XXX_AUTO_CLOCK_SOURCE881 iInternalSource = 1;882 #endif883 }884 885 #ifdef CONFIG_CNS3XXX_INTERNAL_CLOCK_SOURCE886 iInternalSource = 1;887 #endif888 889 if(iInternalSource) {890 printk("PCI-E0 uses internal clock source.\n");891 /* Turn on PCIe clock source */892 cns3xxx_pwr_power_up(1<<PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_USB);893 894 /* Enable PMU CLK */895 // printk("Enable PCIe0 PMU CLK \n");896 u32tmp = __raw_readl(CNS3XXX_PM_BASE_VIRT + 0x14);897 u32tmp |= 0x1 << 28;898 u32tmp |= 0x1 << 29;899 __raw_writel(u32tmp, CNS3XXX_PM_BASE_VIRT + 0x14);900 901 /* Enable PCIe0 Internal Clk */902 // printk("Enable PCIe0 Internal CLK \n");903 u32tmp = __raw_readl(CNS3XXX_MISC_BASE_VIRT + 0x900);904 u32tmp |= 0x1 << 11;905 __raw_writel(u32tmp, CNS3XXX_MISC_BASE_VIRT + 0x900);906 907 /*equalizer setting*/908 u32tmp = 0xe2c;909 __raw_writel(u32tmp, CNS3XXX_MISC_BASE_VIRT + 0x940);910 }911 else {912 printk("PCI-E0 uses external clock source.\n");913 }914 915 // printk("Active PCIe0 Clock, PHY and reset PCIe \n");916 /* Enable PCIe Clock */917 cns3xxx_pwr_clk_en(0x1 << PM_CLK_GATE_REG_OFFSET_PCIE0);918 919 /* Software Reset PCIe */920 cns3xxx_pwr_soft_rst( 0x1 << PM_SOFT_RST_REG_OFFST_PCIE0 );921 922 #ifdef CNS3XXX_PCIE_RESET923 /* Reset device */924 cns3xxx_pwr_clk_en(0x1 << PM_CLK_GATE_REG_OFFSET_GPIO);925 cns3xxx_pwr_power_up(0x1 << PM_CLK_GATE_REG_OFFSET_GPIO);926 cns3xxx_pwr_soft_rst(0x1 << PM_CLK_GATE_REG_OFFSET_GPIO);927 928 u32tmp = __raw_readl(CNS3XXX_GPIOA_BASE_VIRT + 0x8);929 u32tmp |= (0x1 << 21);930 __raw_writel(u32tmp, CNS3XXX_GPIOA_BASE_VIRT + 0x8);931 932 udelay(500);933 934 u32tmp = __raw_readl(CNS3XXX_GPIOA_BASE_VIRT + 0x0);935 u32tmp |= (0x1 << 21);936 __raw_writel(u32tmp, CNS3XXX_GPIOA_BASE_VIRT + 0x0);937 938 #if 0939 mdelay(10);940 u32tmp = __raw_readl(CNS3XXX_GPIOA_BASE_VIRT + 0x0);941 u32tmp &= ~(0x1 << 21);942 __raw_writel(u32tmp, CNS3XXX_GPIOA_BASE_VIRT + 0x0);943 944 mdelay(10);945 u32tmp = __raw_readl(CNS3XXX_GPIOA_BASE_VIRT + 0x0);946 u32tmp |= (0x1 << 21);947 __raw_writel(u32tmp, CNS3XXX_GPIOA_BASE_VIRT + 0x0);948 #endif949 950 #endif951 952 294 cns3xxx_pcie_check_link(0); 953 295 cns3xxx_pcie_hw_init(0); 954 296 } 297 955 298 void __init cns3xxx_pcie1_preinit(void) 956 299 { 957 int iInternalSource = 0;958 u32 u32tmp;959 960 GPIOA_DIR &= ~(0xc00);961 // printk("\nGPIOA_INPUT:0x%.8x\n\n", GPIOA_INPUT);962 963 if((GPIOA_INPUT & 0x400) && (GPIOA_INPUT & 0x800)) {964 // printk("Board version 1.x.\n");965 #ifdef CONFIG_CNS3XXX_AUTO_CLOCK_SOURCE966 iInternalSource = 0;967 #endif968 }969 else {970 // printk("Board version 2.x.\n");971 #ifdef CONFIG_CNS3XXX_AUTO_CLOCK_SOURCE972 iInternalSource = 1;973 #endif974 }975 976 #ifdef CONFIG_CNS3XXX_INTERNAL_CLOCK_SOURCE977 iInternalSource = 1;978 #endif979 980 if(iInternalSource) {981 printk("PCI-E1 uses internal clock source.\n");982 /* Turn on PCIe clock source */983 cns3xxx_pwr_power_up(1<<PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_USB);984 985 /* Enable PMU CLK */986 // printk("Enable PCIe PMU CLK \n");987 u32tmp = __raw_readl(CNS3XXX_PM_BASE_VIRT + 0x14);988 /* Bit-28 enable internal reference clock for port0 and port1989 * Bit-29 enable reference clock out for port1 */990 u32tmp |= 0x3 << 28;991 __raw_writel(u32tmp, CNS3XXX_PM_BASE_VIRT + 0x14);992 993 /* Enable PCIe1 Internal Clk */994 // printk("Enable PCIe1 Internal CLK \n");995 u32tmp = __raw_readl(CNS3XXX_MISC_BASE_VIRT + 0xA00);996 u32tmp |= 0x1 << 11;997 __raw_writel(u32tmp, CNS3XXX_MISC_BASE_VIRT + 0xA00);998 999 /*equalizer setting*/1000 u32tmp = 0xe2c;1001 __raw_writel(u32tmp, CNS3XXX_MISC_BASE_VIRT + 0xA40);1002 }1003 else {1004 printk("PCI-E1 uses external clock source.\n");1005 }1006 1007 // printk("Active PCIe1 Clock, PHY and reset PCIe \n");1008 /* Enable PCIe Clock */1009 cns3xxx_pwr_clk_en(0x1 << PM_CLK_GATE_REG_OFFSET_PCIE1);1010 1011 /* Software Reset PCIe */1012 cns3xxx_pwr_soft_rst( 0x1 << PM_SOFT_RST_REG_OFFST_PCIE1 );1013 1014 #ifdef CNS3XXX_PCIE_RESET1015 1016 /* If onlt enable PCIe1, please unmark for enable GPIO setting */1017 #if 01018 cns3xxx_pwr_clk_en(0x1 << PM_CLK_GATE_REG_OFFSET_GPIO);1019 cns3xxx_pwr_power_up(0x1 << PM_CLK_GATE_REG_OFFSET_GPIO);1020 cns3xxx_pwr_soft_rst(0x1 << PM_CLK_GATE_REG_OFFSET_GPIO);1021 #endif1022 1023 u32tmp = __raw_readl(CNS3XXX_GPIOA_BASE_VIRT + 0x8);1024 u32tmp |= (0x1 << 22);1025 __raw_writel(u32tmp, CNS3XXX_GPIOA_BASE_VIRT + 0x8);1026 1027 udelay(500);1028 1029 u32tmp = __raw_readl(CNS3XXX_GPIOA_BASE_VIRT + 0x0);1030 u32tmp |= (0x1 << 22);1031 __raw_writel(u32tmp, CNS3XXX_GPIOA_BASE_VIRT + 0x0);1032 1033 #if 01034 mdelay(10);1035 u32tmp = __raw_readl(CNS3XXX_GPIOA_BASE_VIRT + 0x0);1036 u32tmp &= ~(0x1 << 22);1037 __raw_writel(u32tmp, CNS3XXX_GPIOA_BASE_VIRT + 0x0);1038 1039 mdelay(10);1040 u32tmp = __raw_readl(CNS3XXX_GPIOA_BASE_VIRT + 0x0);1041 u32tmp |= (0x1 << 22);1042 __raw_writel(u32tmp, CNS3XXX_GPIOA_BASE_VIRT + 0x0);1043 #endif1044 1045 #endif1046 1047 300 cns3xxx_pcie_check_link(1); 1048 301 cns3xxx_pcie_hw_init(1); 1049 302 } 1050 303 1051 void __init cns3xxx_pcie0_postinit(void)1052 {1053 u32 ret;1054 u32 err;1055 1056 pcie0_bridge = pci_get_device(PCIB_VENDOR_ID, PCIB_DEVICE_ID, NULL);1057 if (pcie0_bridge == NULL) {1058 printk("PCIe0: Bridge not found.\n");1059 return;1060 } else {1061 printk("PCIe0: Bridge found.\n");1062 }1063 1064 if ((ret =1065 request_irq(IRQ_CNS3XXX_PCIE0_DEVICE, cns3xxx_pcie0_dev_intc,1066 IRQF_SHARED, "PCIe Port 0 Device", pcie0_bridge))) {1067 printk("%s: request_irq %d failed(ret=0x%x)(-EBUSY=0x%x)\n",1068 __FUNCTION__, IRQ_CNS3XXX_PCIE0_DEVICE, ret, -EBUSY);1069 return;1070 }1071 1072 if ((ret =1073 request_irq(IRQ_CNS3XXX_PCIE0_RC, cns3xxx_pcie0_rc_intc,1074 IRQF_SHARED, "PCIe Port 0 RC", pcie0_bridge))) {1075 printk("%s: request_irq %d failed(ret=0x%x)(-EBUSY=0x%x)\n",1076 __FUNCTION__, IRQ_CNS3XXX_PCIE0_RC, ret, -EBUSY);1077 return;1078 }1079 1080 //MISC_PCI_ARBITER_INTERRUPT_MASK_REG &= ~0x1f;1081 pci_write_config_dword(pcie0_bridge, PCI_BASE_ADDRESS_0, 0x0); // = 0x0, can NOT use 0x200000001082 pci_write_config_dword(pcie0_bridge, PCI_BASE_ADDRESS_1, 0x0); // = 0x0, can NOT use 0x200000001083 1084 // if we enable pci on u-boot1085 // the pci_enable_device will complain with resource collisions1086 // use this to fixup1087 {1088 int i;1089 struct resource *r;1090 1091 for (i = 0; i < 6; i++) {1092 r = pcie0_bridge->resource + i;1093 r->start = 0;1094 r->end = 0;1095 }1096 }1097 1098 err = pci_enable_device(pcie0_bridge);1099 pci_set_master(pcie0_bridge);1100 1101 /* Disable PCIe0 Interrupt Mask INTA to INTD */1102 __raw_writel(~0x3FFF, CNS3XXX_MISC_BASE_VIRT + 0x978);1103 }1104 1105 void __init cns3xxx_pcie1_postinit(void)1106 {1107 u32 ret;1108 u32 err;1109 1110 pcie1_bridge = pci_get_device(PCIB_VENDOR_ID, PCIB_DEVICE_ID, NULL);1111 if (pcie1_bridge == NULL) {1112 printk("PCIe1: Bridge not found.\n");1113 return;1114 } else {1115 printk("PCIe1: Bridge found.\n");1116 }1117 1118 if ((ret =1119 request_irq(IRQ_CNS3XXX_PCIE1_DEVICE, cns3xxx_pcie1_dev_intc,1120 IRQF_SHARED, "PCIe Port 1 Device", pcie1_bridge))) {1121 printk("%s: request_irq %d failed(ret=0x%x)(-EBUSY=0x%x)\n",1122 __FUNCTION__, IRQ_CNS3XXX_PCIE1_DEVICE, ret, -EBUSY);1123 return;1124 }1125 1126 if ((ret =1127 request_irq(IRQ_CNS3XXX_PCIE1_RC, cns3xxx_pcie1_rc_intc,1128 IRQF_SHARED, "PCIe Port 1 RC", pcie1_bridge))) {1129 printk("%s: request_irq %d failed(ret=0x%x)(-EBUSY=0x%x)\n",1130 __FUNCTION__, IRQ_CNS3XXX_PCIE1_RC, ret, -EBUSY);1131 return;1132 }1133 1134 //MISC_PCI_ARBITER_INTERRUPT_MASK_REG &= ~0x1f;1135 pci_write_config_dword(pcie1_bridge, PCI_BASE_ADDRESS_0, 0x0); // = 0x0, can NOT use 0x200000001136 pci_write_config_dword(pcie1_bridge, PCI_BASE_ADDRESS_1, 0x0); // = 0x0, can NOT use 0x200000001137 1138 // if we enable pci on u-boot1139 // the pci_enable_device will complain with resource collisions1140 // use this to fixup1141 {1142 int i;1143 struct resource *r;1144 1145 for (i = 0; i < 6; i++) {1146 r = pcie1_bridge->resource + i;1147 r->start = 0;1148 r->end = 0;1149 }1150 }1151 1152 err = pci_enable_device(pcie1_bridge);1153 pci_set_master(pcie1_bridge);1154 1155 /* Disable PCIe1 Interrupt Mask INTA to INTD */1156 __raw_writel(~0x3FFF, CNS3XXX_MISC_BASE_VIRT + 0xA78);1157 }1158 304 /* 1159 305 * map the specified device/slot/pin to an IRQ. Different backplanes may need to modify this. … … 1162 308 static int __init cns3xxx_pcie0_map_irq(struct pci_dev *dev, u8 slot, u8 pin) 1163 309 { 1164 int irq; 1165 1166 /* slot, pin, irq 1167 * 0 1 PCIe 0 Device, 61 1168 * 1 1 PCIe 0 RC, 88 1169 * 2 1 PCIe 1 Device, 62 1170 * 3 1 PCIe 1 RC, 89 1171 */ 1172 irq = cns3xxx_pcie0_irqs[slot]; 1173 1174 printk("PCIe0 map irq: %04d:%02x:%02x.%02x slot %d, pin %d, irq: %d\n", 1175 pci_domain_nr(dev->bus),dev->bus->number, PCI_SLOT(dev->devfn), 1176 PCI_FUNC(dev->devfn), slot, pin, irq); 1177 1178 return irq; 310 return cns3xxx_pcie0_irqs[slot]; 1179 311 } 1180 312 1181 313 static int __init cns3xxx_pcie1_map_irq(struct pci_dev *dev, u8 slot, u8 pin) 1182 314 { 1183 int irq; 1184 1185 /* slot, pin, irq 1186 * 0 1 PCIe 0 Device, 61 1187 * 1 1 PCIe 0 RC, 88 1188 * 2 1 PCIe 1 Device, 62 1189 * 3 1 PCIe 1 RC, 89 1190 */ 1191 irq = cns3xxx_pcie1_irqs[slot]; 1192 1193 printk("PCIe1 map irq: %04d:%02x:%02x.%02x slot %d, pin %d, irq: %d\n", 1194 pci_domain_nr(dev->bus),dev->bus->number, PCI_SLOT(dev->devfn), 1195 PCI_FUNC(dev->devfn), slot, pin, irq); 1196 1197 return irq; 1198 } 1199 1200 static struct hw_pci cns3xxx_pcie0 __initdata = { 1201 .swizzle = pci_std_swizzle, 1202 .map_irq = cns3xxx_pcie0_map_irq, 1203 .nr_controllers = 1, 1204 .nr_domains = 0, 1205 .setup = cns3xxx_pci_setup, 1206 .scan = cns3xxx_pci_scan_bus, 1207 .preinit = cns3xxx_pcie0_preinit, 1208 .postinit = cns3xxx_pcie0_postinit, 1209 }; 1210 static struct hw_pci cns3xxx_pcie1 __initdata = { 1211 .swizzle = pci_std_swizzle, 1212 .map_irq = cns3xxx_pcie1_map_irq, 1213 .nr_controllers = 1, 1214 .nr_domains = 1, 1215 .setup = cns3xxx_pci_setup, 1216 .scan = cns3xxx_pci_scan_bus, 1217 .preinit = cns3xxx_pcie1_preinit, 1218 .postinit = cns3xxx_pcie1_postinit, 1219 }; 1220 1221 #ifdef CONFIG_DEBUG_FS 1222 struct pcie_dbgfs_reg dbgfs_reg[] = { 1223 {"PCIEPHY0_CMCTL0", (u32 *)CNS3XXX_PCIEPHY0_CMCTL0}, 1224 {"PCIEPHY0_CMCTL1", (u32 *)CNS3XXX_PCIEPHY0_CMCTL1}, 1225 {"PCIEPHY0_CTL1", (u32 *)CNS3XXX_PCIEPHY0_CTL1}, 1226 {"PCIE0_AXIS_AWMISC", (u32 *)CNS3XXX_PCIE0_AXIS_AWMISC}, 1227 {"PCIE0_AXIS_ARMISC", (u32 *)CNS3XXX_PCIE0_AXIS_ARMISC}, 1228 {"PCIE0_AXIS_RMISC", (u32 *)CNS3XXX_PCIE0_AXIS_RMISC}, 1229 {"PCIE0_AXIS_BMISC", (u32 *)CNS3XXX_PCIE0_AXIS_BMISC}, 1230 {"PCIE0_AXIM_RMISC", (u32 *)CNS3XXX_PCIE0_AXIS_RMISC}, 1231 {"PCIE0_AXIM_BMISC", (u32 *)CNS3XXX_PCIE0_AXIS_BMISC}, 1232 {"PCIE0_CTRL", (u32 *)CNS3XXX_PCIE0_CTRL}, 1233 {"PCIE0_PM_DEBUG", (u32 *)CNS3XXX_PCIE0_PM_DEBUG}, 1234 {"PCIE0_RFC_DEBUG", (u32 *)CNS3XXX_PCIE0_RFC_DEBUG}, 1235 {"PCIE0_CXPL_DEBUGL", (u32 *)CNS3XXX_PCIE0_CXPL_DEBUGL}, 1236 {"PCIE0_CXPL_DEBUGH", (u32 *)CNS3XXX_PCIE0_CXPL_DEBUGH}, 1237 {"PCIE0_DIAG", (u32 *)CNS3XXX_PCIE0_DIAG}, 1238 {"PCIE0_INT_STATUS", (u32 *)CNS3XXX_PCIE0_INT_STATUS}, 1239 {"PCIE0_INT_MASK", (u32 *)CNS3XXX_PCIE0_INT_MASK}, 1240 {"PCIEPHY1_CMCTL0", (u32 *)CNS3XXX_PCIEPHY0_CMCTL0}, 1241 {"PCIEPHY1_CMCTL1", (u32 *)CNS3XXX_PCIEPHY0_CMCTL1}, 1242 {"PCIEPHY1_CTL1", (u32 *)CNS3XXX_PCIEPHY0_CTL1}, 1243 {"PCIE1_AXIS_AWMISC", (u32 *)CNS3XXX_PCIE0_AXIS_AWMISC}, 1244 {"PCIE1_AXIS_ARMISC", (u32 *)CNS3XXX_PCIE0_AXIS_ARMISC}, 1245 {"PCIE1_AXIS_RMISC", (u32 *)CNS3XXX_PCIE0_AXIS_RMISC}, 1246 {"PCIE1_AXIS_BMISC", (u32 *)CNS3XXX_PCIE0_AXIS_BMISC}, 1247 {"PCIE1_AXIM_RMISC", (u32 *)CNS3XXX_PCIE0_AXIS_RMISC}, 1248 {"PCIE1_AXIM_BMISC", (u32 *)CNS3XXX_PCIE0_AXIS_BMISC}, 1249 {"PCIE1_CTRL", (u32 *)CNS3XXX_PCIE0_CTRL}, 1250 {"PCIE1_PM_DEBUG", (u32 *)CNS3XXX_PCIE0_PM_DEBUG}, 1251 {"PCIE1_RFC_DEBUG", (u32 *)CNS3XXX_PCIE0_RFC_DEBUG}, 1252 {"PCIE1_CXPL_DEBUGL", (u32 *)CNS3XXX_PCIE0_CXPL_DEBUGL}, 1253 {"PCIE1_CXPL_DEBUGH", (u32 *)CNS3XXX_PCIE0_CXPL_DEBUGH}, 1254 {"PCIE1_DIAG", (u32 *)CNS3XXX_PCIE0_DIAG}, 1255 {"PCIE1_INT_STATUS", (u32 *)CNS3XXX_PCIE0_INT_STATUS}, 1256 {"PCIE1_INT_MASK", (u32 *)CNS3XXX_PCIE0_INT_MASK}, 1257 {0,0} 1258 }; 1259 static void pcie_debugfs_init(void){ 1260 1261 struct dentry *pcie_dir; 1262 //char *data; 1263 int i=0; 1264 1265 /* if( cns3xxx_debugfs_dir == NULL ){ 1266 printk("Create Debug fs failed \n"); 1267 BUG(); 1268 } */ 1269 1270 // pcie_dir = debugfs_create_dir("pcie", cns3xxx_debugfs_dir); 1271 pcie_dir = debugfs_create_dir("pcie", NULL); 1272 1273 if( pcie_dir != NULL ) { 1274 while( dbgfs_reg[i].name != 0 ){ 1275 // printk("name: %s addr : %08x \n", dbgfs_reg[i].name, dbgfs_reg[i].addr); 1276 debugfs_create_x32(dbgfs_reg[i].name, 0644, pcie_dir, dbgfs_reg[i].addr); 1277 i++; 1278 } 1279 } 1280 1281 } 1282 #endif 315 return cns3xxx_pcie1_irqs[slot]; 316 } 317 318 static struct hw_pci cns3xxx_pcie[2] __initdata = { 319 { 320 .swizzle = pci_std_swizzle, 321 .map_irq = cns3xxx_pcie0_map_irq, 322 .nr_controllers = 1, 323 .nr_domains = 0, 324 .setup = cns3xxx_pci_setup, 325 .scan = cns3xxx_pci_scan_bus, 326 .preinit = cns3xxx_pcie0_preinit, 327 }, 328 { 329 .swizzle = pci_std_swizzle, 330 .map_irq = cns3xxx_pcie1_map_irq, 331 .nr_controllers = 1, 332 .nr_domains = 1, 333 .setup = cns3xxx_pci_setup, 334 .scan = cns3xxx_pci_scan_bus, 335 .preinit = cns3xxx_pcie1_preinit, 336 } 337 }; 1283 338 1284 339 static int cns3xxx_pcie_abort_handler(unsigned long addr, unsigned int fsr, 1285 struct pt_regs *regs) 1286 { 1287 /* 1288 * It seems we can't identify if that was really PCIe that caused an 1289 * imprecise external abort (PCIe status register doesn't report that). 1290 * So ignore all aborts, for now. 1291 * 1292 * Later, if there is really no way to ask hardware about the cause 1293 * of the abort, we'll have to use some global variable under irqsave 1294 * spinlock during the time we access the PCIe config space. 1295 */ 340 struct pt_regs *regs) 341 { 342 if (fsr & (1 << 10)) 343 regs->ARM_pc += 4; 344 return 0; 345 } 346 347 //extern void pci_common_init(struct hw_pci *); 348 int cns3xxx_pcie_init(u8 ports) 349 { 350 hook_fault_code(16 + 6, cns3xxx_pcie_abort_handler, SIGBUS, "imprecise external abort"); 351 352 if (ports & 0x1) 353 pci_common_init(&cns3xxx_pcie[0]); 354 if (ports & 0x2) 355 pci_common_init(&cns3xxx_pcie[1]); 356 1296 357 return 0; 1297 358 } 1298 359 1299 extern void pci_common_init(struct hw_pci *); 1300 1301 int cns3xxx_pcie_init(u8 ports) 1302 { 1303 1304 printk("CNS3XXX PCIe Host Control Driver\n"); 1305 1306 cns3xxx_pwr_clk_en(0x1 << PM_CLK_GATE_REG_OFFSET_GPIO); 1307 cns3xxx_pwr_power_up(0x1 << PM_CLK_GATE_REG_OFFSET_GPIO); 1308 cns3xxx_pwr_soft_rst(0x1 << PM_CLK_GATE_REG_OFFSET_GPIO); 1309 1310 /* hook in our fault handler for PCI errors */ 1311 hook_fault_code(16 + 6, cns3xxx_pcie_abort_handler, SIGBUS, 1312 "imprecise external abort"); 1313 1314 if (ports & 1) 1315 pci_common_init(&cns3xxx_pcie0); 1316 if (ports & 2) 1317 pci_common_init(&cns3xxx_pcie1); 1318 1319 pci_assign_unassigned_resources(); 1320 1321 #ifdef CNS3XXX_PCIE_DEBUG 1322 cns3xxx_proc_init(); 1323 #endif 1324 #ifdef CONFIG_DEBUG_FS 1325 pcie_debugfs_init(); 1326 #endif 1327 return 0; 1328 } 1329 360 //device_initcall(cns3xxx_pcie_init);
Note: See TracChangeset
for help on using the changeset viewer.
