mv_pci.c (e7153b2583ec32ced588706fe1996d909b23bc3c) | mv_pci.c (6975124c23e9314a1e0eaa111cc0fe829ea102bd) |
---|---|
1/*- 2 * Copyright (C) 2008 MARVELL INTERNATIONAL LTD. 3 * All rights reserved. 4 * 5 * Developed by Semihalf. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 66 unchanged lines hidden (view full) --- 75 76#define PCIE_REG_CFG_ADDR 0x18F8 77#define PCIE_REG_CFG_DATA 0x18FC 78#define PCIE_REG_CONTROL 0x1A00 79#define PCIE_CTRL_LINK1X 0x00000001 80#define PCIE_REG_STATUS 0x1A04 81#define PCIE_REG_IRQ_MASK 0x1910 82 | 1/*- 2 * Copyright (C) 2008 MARVELL INTERNATIONAL LTD. 3 * All rights reserved. 4 * 5 * Developed by Semihalf. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 66 unchanged lines hidden (view full) --- 75 76#define PCIE_REG_CFG_ADDR 0x18F8 77#define PCIE_REG_CFG_DATA 0x18FC 78#define PCIE_REG_CONTROL 0x1A00 79#define PCIE_CTRL_LINK1X 0x00000001 80#define PCIE_REG_STATUS 0x1A04 81#define PCIE_REG_IRQ_MASK 0x1910 82 |
83#define STATUS_LINK_DOWN 1 | |
84#define STATUS_BUS_OFFS 8 85#define STATUS_BUS_MASK (0xFF << STATUS_BUS_OFFS) 86#define STATUS_DEV_OFFS 16 87#define STATUS_DEV_MASK (0x1F << STATUS_DEV_OFFS) 88 89#define P2P_CONF_BUS_OFFS 16 90#define P2P_CONF_BUS_MASK (0xFF << P2P_CONF_BUS_OFFS) 91#define P2P_CONF_DEV_OFFS 24 92#define P2P_CONF_DEV_MASK (0x1F << P2P_CONF_DEV_OFFS) 93 94#define PCI_VENDORID_MRVL 0x11AB 95 96struct pcib_mbus_softc { 97 device_t sc_dev; 98 | 83#define STATUS_BUS_OFFS 8 84#define STATUS_BUS_MASK (0xFF << STATUS_BUS_OFFS) 85#define STATUS_DEV_OFFS 16 86#define STATUS_DEV_MASK (0x1F << STATUS_DEV_OFFS) 87 88#define P2P_CONF_BUS_OFFS 16 89#define P2P_CONF_BUS_MASK (0xFF << P2P_CONF_BUS_OFFS) 90#define P2P_CONF_DEV_OFFS 24 91#define P2P_CONF_DEV_MASK (0x1F << P2P_CONF_DEV_OFFS) 92 93#define PCI_VENDORID_MRVL 0x11AB 94 95struct pcib_mbus_softc { 96 device_t sc_dev; 97 |
99 struct rman sc_iomem_rman; | |
100 bus_addr_t sc_iomem_base; 101 bus_addr_t sc_iomem_size; 102 bus_addr_t sc_iomem_alloc; /* Next allocation. */ 103 | 98 bus_addr_t sc_iomem_base; 99 bus_addr_t sc_iomem_size; 100 bus_addr_t sc_iomem_alloc; /* Next allocation. */ 101 |
104 struct rman sc_ioport_rman; | |
105 bus_addr_t sc_ioport_base; 106 bus_addr_t sc_ioport_size; 107 bus_addr_t sc_ioport_alloc; /* Next allocation. */ 108 109 struct resource *sc_res; 110 bus_space_handle_t sc_bsh; 111 bus_space_tag_t sc_bst; 112 int sc_rid; --- 254 unchanged lines hidden (view full) --- 367 /* 368 * Read link configuration 369 */ 370 sc->sc_rid = 0; 371 sc->sc_res = BUS_ALLOC_RESOURCE(parent, parent, SYS_RES_MEMORY, 372 &sc->sc_rid, sc->sc_info->op_base, sc->sc_info->op_base + 373 sc->sc_info->op_size - 1, sc->sc_info->op_size, 374 RF_ACTIVE); | 102 bus_addr_t sc_ioport_base; 103 bus_addr_t sc_ioport_size; 104 bus_addr_t sc_ioport_alloc; /* Next allocation. */ 105 106 struct resource *sc_res; 107 bus_space_handle_t sc_bsh; 108 bus_space_tag_t sc_bst; 109 int sc_rid; --- 254 unchanged lines hidden (view full) --- 364 /* 365 * Read link configuration 366 */ 367 sc->sc_rid = 0; 368 sc->sc_res = BUS_ALLOC_RESOURCE(parent, parent, SYS_RES_MEMORY, 369 &sc->sc_rid, sc->sc_info->op_base, sc->sc_info->op_base + 370 sc->sc_info->op_size - 1, sc->sc_info->op_size, 371 RF_ACTIVE); |
375 if (sc->sc_res == NULL) { | 372 if (sc->sc_res == NULL) |
376 device_printf(parent, "Could not map pcib memory\n"); | 373 device_printf(parent, "Could not map pcib memory\n"); |
377 break; 378 } | |
379 380 sc->sc_bst = rman_get_bustag(sc->sc_res); 381 sc->sc_bsh = rman_get_bushandle(sc->sc_res); 382 383 control = bus_space_read_4(sc->sc_bst, sc->sc_bsh, 384 PCIE_REG_CONTROL); 385 386 BUS_RELEASE_RESOURCE(parent, parent, SYS_RES_MEMORY, sc->sc_rid, --- 45 unchanged lines hidden (view full) --- 432 val = bus_space_read_4(sc->sc_bst, sc->sc_bsh, 433 PCI_REG_P2P_CONF); 434 bus = sc->sc_busnr = (val & P2P_CONF_BUS_MASK) >> 435 P2P_CONF_BUS_OFFS; 436 dev = sc->sc_devnr = (val & P2P_CONF_DEV_MASK) >> 437 P2P_CONF_DEV_OFFS; 438 } else { 439 val = bus_space_read_4(sc->sc_bst, sc->sc_bsh, PCIE_REG_STATUS); | 374 375 sc->sc_bst = rman_get_bustag(sc->sc_res); 376 sc->sc_bsh = rman_get_bushandle(sc->sc_res); 377 378 control = bus_space_read_4(sc->sc_bst, sc->sc_bsh, 379 PCIE_REG_CONTROL); 380 381 BUS_RELEASE_RESOURCE(parent, parent, SYS_RES_MEMORY, sc->sc_rid, --- 45 unchanged lines hidden (view full) --- 427 val = bus_space_read_4(sc->sc_bst, sc->sc_bsh, 428 PCI_REG_P2P_CONF); 429 bus = sc->sc_busnr = (val & P2P_CONF_BUS_MASK) >> 430 P2P_CONF_BUS_OFFS; 431 dev = sc->sc_devnr = (val & P2P_CONF_DEV_MASK) >> 432 P2P_CONF_DEV_OFFS; 433 } else { 434 val = bus_space_read_4(sc->sc_bst, sc->sc_bsh, PCIE_REG_STATUS); |
440 if (val & STATUS_LINK_DOWN) 441 goto out; | |
442 bus = sc->sc_busnr = (val & STATUS_BUS_MASK) >> STATUS_BUS_OFFS; 443 dev = sc->sc_devnr = (val & STATUS_DEV_MASK) >> STATUS_DEV_OFFS; 444 } 445 446 val = pcib_mbus_hw_cfgread(sc, bus, dev, 0, PCIR_VENDOR, 2); 447 if (val != PCI_VENDORID_MRVL) 448 goto out; 449 --- 4 unchanged lines hidden (view full) --- 454 break; 455 case 0x5182: 456 id = "88F5182"; 457 break; 458 case 0x6281: 459 id = "88F6281"; 460 break; 461 case 0x6381: | 435 bus = sc->sc_busnr = (val & STATUS_BUS_MASK) >> STATUS_BUS_OFFS; 436 dev = sc->sc_devnr = (val & STATUS_DEV_MASK) >> STATUS_DEV_OFFS; 437 } 438 439 val = pcib_mbus_hw_cfgread(sc, bus, dev, 0, PCIR_VENDOR, 2); 440 if (val != PCI_VENDORID_MRVL) 441 goto out; 442 --- 4 unchanged lines hidden (view full) --- 447 break; 448 case 0x5182: 449 id = "88F5182"; 450 break; 451 case 0x6281: 452 id = "88F6281"; 453 break; 454 case 0x6381: |
462 id = "MV78100 Z0"; 463 break; 464 case 0x7810: | |
465 id = "MV78100"; 466 break; | 455 id = "MV78100"; 456 break; |
467 case 0x7820: 468 /* 469 * According to documentation ID 0x7820 is assigned to MV78200. 470 * However some MV78100 chips also use it. 471 */ 472 id = "MV78100/MV78200"; 473 break; | |
474 default: 475 device_printf(self, "unknown Marvell PCI bridge: %x\n", val); 476 goto out; 477 } 478 479 type = "PCI"; 480 val = pcib_mbus_hw_cfgread(sc, bus, dev, 0, PCIR_CAP_PTR, 1); 481 while (val != 0) { --- 49 unchanged lines hidden (view full) --- 531 sc->sc_iomem_base = sc->sc_info->op_mem_base; 532 sc->sc_iomem_size = sc->sc_info->op_mem_size; 533 sc->sc_iomem_alloc = sc->sc_info->op_mem_base; 534 535 sc->sc_ioport_base = sc->sc_info->op_io_base; 536 sc->sc_ioport_size = sc->sc_info->op_io_size; 537 sc->sc_ioport_alloc = sc->sc_info->op_io_base; 538 | 457 default: 458 device_printf(self, "unknown Marvell PCI bridge: %x\n", val); 459 goto out; 460 } 461 462 type = "PCI"; 463 val = pcib_mbus_hw_cfgread(sc, bus, dev, 0, PCIR_CAP_PTR, 1); 464 while (val != 0) { --- 49 unchanged lines hidden (view full) --- 514 sc->sc_iomem_base = sc->sc_info->op_mem_base; 515 sc->sc_iomem_size = sc->sc_info->op_mem_size; 516 sc->sc_iomem_alloc = sc->sc_info->op_mem_base; 517 518 sc->sc_ioport_base = sc->sc_info->op_io_base; 519 sc->sc_ioport_size = sc->sc_info->op_io_size; 520 sc->sc_ioport_alloc = sc->sc_info->op_io_base; 521 |
539 sc->sc_iomem_rman.rm_type = RMAN_ARRAY; 540 err = rman_init(&sc->sc_iomem_rman); 541 if (err) 542 return (err); 543 544 sc->sc_ioport_rman.rm_type = RMAN_ARRAY; 545 err = rman_init(&sc->sc_ioport_rman); 546 if (err) { 547 rman_fini(&sc->sc_iomem_rman); 548 return (err); 549 } 550 551 err = rman_manage_region(&sc->sc_iomem_rman, sc->sc_iomem_base, 552 sc->sc_iomem_base + sc->sc_iomem_size - 1); 553 if (err) 554 goto error; 555 556 err = rman_manage_region(&sc->sc_ioport_rman, sc->sc_ioport_base, 557 sc->sc_ioport_base + sc->sc_ioport_size - 1); 558 if (err) 559 goto error; 560 | |
561 err = pcib_mbus_init(sc, sc->sc_busnr, pcib_mbus_maxslots(sc->sc_dev)); 562 if (err) | 522 err = pcib_mbus_init(sc, sc->sc_busnr, pcib_mbus_maxslots(sc->sc_dev)); 523 if (err) |
563 goto error; | 524 return(err); |
564 565 device_add_child(self, "pci", -1); 566 return (bus_generic_attach(self)); | 525 526 device_add_child(self, "pci", -1); 527 return (bus_generic_attach(self)); |
567 568error: 569 rman_fini(&sc->sc_iomem_rman); 570 rman_fini(&sc->sc_ioport_rman); 571 return (err); | |
572} 573 574static int 575pcib_mbus_init_bar(struct pcib_mbus_softc *sc, int bus, int slot, int func, 576 int barno) 577{ 578 bus_addr_t *allocp, limit; 579 uint32_t addr, bar, mask, size; --- 27 unchanged lines hidden (view full) --- 607 mask = ~size; 608 size = mask + 1; 609 610 /* Sanity check (must be a power of 2) */ 611 if (size & mask) 612 return (width); 613 614 addr = (*allocp + mask) & ~mask; | 528} 529 530static int 531pcib_mbus_init_bar(struct pcib_mbus_softc *sc, int bus, int slot, int func, 532 int barno) 533{ 534 bus_addr_t *allocp, limit; 535 uint32_t addr, bar, mask, size; --- 27 unchanged lines hidden (view full) --- 563 mask = ~size; 564 size = mask + 1; 565 566 /* Sanity check (must be a power of 2) */ 567 if (size & mask) 568 return (width); 569 570 addr = (*allocp + mask) & ~mask; |
615 if ((*allocp = addr + size) > limit) | 571 if ((*allocp = addr + size) >= limit) |
616 return (-1); 617 618 if (bootverbose) 619 printf("PCI %u:%u:%u: reg %x: size=%08x: addr=%08x\n", 620 bus, slot, func, reg, size, addr); 621 622 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, reg, addr, 4); 623 if (width == 2) --- 11 unchanged lines hidden (view full) --- 635 int secbus; 636 637 io_base = sc->sc_info->op_io_base; 638 io_limit = io_base + sc->sc_info->op_io_size - 1; 639 mem_base = sc->sc_info->op_mem_base; 640 mem_limit = mem_base + sc->sc_info->op_mem_size - 1; 641 642 /* Configure I/O decode registers */ | 572 return (-1); 573 574 if (bootverbose) 575 printf("PCI %u:%u:%u: reg %x: size=%08x: addr=%08x\n", 576 bus, slot, func, reg, size, addr); 577 578 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, reg, addr, 4); 579 if (width == 2) --- 11 unchanged lines hidden (view full) --- 591 int secbus; 592 593 io_base = sc->sc_info->op_io_base; 594 io_limit = io_base + sc->sc_info->op_io_size - 1; 595 mem_base = sc->sc_info->op_mem_base; 596 mem_limit = mem_base + sc->sc_info->op_mem_size - 1; 597 598 /* Configure I/O decode registers */ |
643 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, PCIR_IOBASEL_1, 644 io_base >> 8, 1); 645 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, PCIR_IOBASEH_1, 646 io_base >> 16, 2); | |
647 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, PCIR_IOLIMITL_1, 648 io_limit >> 8, 1); 649 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, PCIR_IOLIMITH_1, 650 io_limit >> 16, 2); 651 652 /* Configure memory decode registers */ 653 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, PCIR_MEMBASE_1, 654 mem_base >> 16, 2); --- 16 unchanged lines hidden (view full) --- 671 /* Configure buses behind the bridge */ 672 pcib_mbus_init(sc, secbus, PCI_SLOTMAX); 673} 674 675static int 676pcib_mbus_init_resources(struct pcib_mbus_softc *sc, int bus, int slot, 677 int func, int hdrtype) 678{ | 599 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, PCIR_IOLIMITL_1, 600 io_limit >> 8, 1); 601 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, PCIR_IOLIMITH_1, 602 io_limit >> 16, 2); 603 604 /* Configure memory decode registers */ 605 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, PCIR_MEMBASE_1, 606 mem_base >> 16, 2); --- 16 unchanged lines hidden (view full) --- 623 /* Configure buses behind the bridge */ 624 pcib_mbus_init(sc, secbus, PCI_SLOTMAX); 625} 626 627static int 628pcib_mbus_init_resources(struct pcib_mbus_softc *sc, int bus, int slot, 629 int func, int hdrtype) 630{ |
679 const struct obio_pci_irq_map *map = sc->sc_info->op_pci_irq_map; | |
680 int maxbar = (hdrtype & PCIM_HDRTYPE) ? 0 : 6; | 631 int maxbar = (hdrtype & PCIM_HDRTYPE) ? 0 : 6; |
681 int bar = 0, irq = -1; 682 int pin, i; | 632 int bar = 0, irq, pin, i; |
683 684 /* Program the base address registers */ 685 while (bar < maxbar) { 686 i = pcib_mbus_init_bar(sc, bus, slot, func, bar); 687 bar += i; 688 if (i < 0) { 689 device_printf(sc->sc_dev, 690 "PCI IO/Memory space exhausted\n"); 691 return (ENOMEM); 692 } 693 } 694 695 /* Perform interrupt routing */ 696 pin = pcib_mbus_read_config(sc->sc_dev, bus, slot, func, 697 PCIR_INTPIN, 1); 698 | 633 634 /* Program the base address registers */ 635 while (bar < maxbar) { 636 i = pcib_mbus_init_bar(sc, bus, slot, func, bar); 637 bar += i; 638 if (i < 0) { 639 device_printf(sc->sc_dev, 640 "PCI IO/Memory space exhausted\n"); 641 return (ENOMEM); 642 } 643 } 644 645 /* Perform interrupt routing */ 646 pin = pcib_mbus_read_config(sc->sc_dev, bus, slot, func, 647 PCIR_INTPIN, 1); 648 |
699 if (map != NULL) 700 while (map->opim_irq >= 0) { 701 if ((map->opim_slot == slot || map->opim_slot < 0) && 702 (map->opim_pin == pin || map->opim_pin < 0)) 703 irq = map->opim_irq; 704 705 map++; 706 } | 649 if (sc->sc_info->op_get_irq != NULL) 650 irq = sc->sc_info->op_get_irq(bus, slot, func, pin); |
707 else 708 irq = sc->sc_info->op_irq; 709 710 if (irq >= 0) 711 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, 712 PCIR_INTLINE, irq, 1); 713 else { 714 device_printf(sc->sc_dev, "Missing IRQ routing information " --- 58 unchanged lines hidden (view full) --- 773 774 return (0); 775} 776 777static struct resource * 778pcib_mbus_alloc_resource(device_t dev, device_t child, int type, int *rid, 779 u_long start, u_long end, u_long count, u_int flags) 780{ | 651 else 652 irq = sc->sc_info->op_irq; 653 654 if (irq >= 0) 655 pcib_mbus_write_config(sc->sc_dev, bus, slot, func, 656 PCIR_INTLINE, irq, 1); 657 else { 658 device_printf(sc->sc_dev, "Missing IRQ routing information " --- 58 unchanged lines hidden (view full) --- 717 718 return (0); 719} 720 721static struct resource * 722pcib_mbus_alloc_resource(device_t dev, device_t child, int type, int *rid, 723 u_long start, u_long end, u_long count, u_int flags) 724{ |
781 struct pcib_mbus_softc *sc = device_get_softc(dev); 782 struct rman *rm = NULL; 783 struct resource *res; | |
784 | 725 |
785 switch (type) { 786 case SYS_RES_IOPORT: 787 rm = &sc->sc_ioport_rman; 788 break; 789 case SYS_RES_MEMORY: 790 rm = &sc->sc_iomem_rman; 791 break; 792 default: 793 return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child, 794 type, rid, start, end, count, flags)); 795 }; 796 797 res = rman_reserve_resource(rm, start, end, count, flags, child); 798 if (res == NULL) 799 return (NULL); 800 801 rman_set_rid(res, *rid); 802 rman_set_bustag(res, obio_tag); 803 rman_set_bushandle(res, start); 804 805 if (flags & RF_ACTIVE) 806 if (bus_activate_resource(child, type, *rid, res)) { 807 rman_release_resource(res); 808 return (NULL); 809 } 810 811 return (res); | 726 return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child, 727 type, rid, start, end, count, flags)); |
812} 813 814static int 815pcib_mbus_release_resource(device_t dev, device_t child, int type, int rid, 816 struct resource *res) 817{ 818 | 728} 729 730static int 731pcib_mbus_release_resource(device_t dev, device_t child, int type, int rid, 732 struct resource *res) 733{ 734 |
819 if (type != SYS_RES_IOPORT && type != SYS_RES_MEMORY) 820 return (BUS_RELEASE_RESOURCE(device_get_parent(dev), child, 821 type, rid, res)); 822 823 return (rman_release_resource(res)); | 735 return (BUS_RELEASE_RESOURCE(device_get_parent(dev), child, 736 type, rid, res)); |
824} 825 826static int 827pcib_mbus_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) 828{ 829 struct pcib_mbus_softc *sc = device_get_softc(dev); 830 831 switch (which) { --- 24 unchanged lines hidden --- | 737} 738 739static int 740pcib_mbus_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) 741{ 742 struct pcib_mbus_softc *sc = device_get_softc(dev); 743 744 switch (which) { --- 24 unchanged lines hidden --- |