diff options
Diffstat (limited to 'arch/mips/pci/pci-octeon.c')
-rw-r--r-- | arch/mips/pci/pci-octeon.c | 60 |
1 files changed, 54 insertions, 6 deletions
diff --git a/arch/mips/pci/pci-octeon.c b/arch/mips/pci/pci-octeon.c index d248b707eff3..2d74fc9ae3ba 100644 --- a/arch/mips/pci/pci-octeon.c +++ b/arch/mips/pci/pci-octeon.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/interrupt.h> | 11 | #include <linux/interrupt.h> |
12 | #include <linux/time.h> | 12 | #include <linux/time.h> |
13 | #include <linux/delay.h> | 13 | #include <linux/delay.h> |
14 | #include <linux/swiotlb.h> | ||
14 | 15 | ||
15 | #include <asm/time.h> | 16 | #include <asm/time.h> |
16 | 17 | ||
@@ -19,6 +20,8 @@ | |||
19 | #include <asm/octeon/cvmx-pci-defs.h> | 20 | #include <asm/octeon/cvmx-pci-defs.h> |
20 | #include <asm/octeon/pci-octeon.h> | 21 | #include <asm/octeon/pci-octeon.h> |
21 | 22 | ||
23 | #include <dma-coherence.h> | ||
24 | |||
22 | #define USE_OCTEON_INTERNAL_ARBITER | 25 | #define USE_OCTEON_INTERNAL_ARBITER |
23 | 26 | ||
24 | /* | 27 | /* |
@@ -32,6 +35,8 @@ | |||
32 | /* Octeon't PCI controller uses did=3, subdid=3 for PCI memory. */ | 35 | /* Octeon't PCI controller uses did=3, subdid=3 for PCI memory. */ |
33 | #define OCTEON_PCI_MEMSPACE_OFFSET (0x00011b0000000000ull) | 36 | #define OCTEON_PCI_MEMSPACE_OFFSET (0x00011b0000000000ull) |
34 | 37 | ||
38 | u64 octeon_bar1_pci_phys; | ||
39 | |||
35 | /** | 40 | /** |
36 | * This is the bit decoding used for the Octeon PCI controller addresses | 41 | * This is the bit decoding used for the Octeon PCI controller addresses |
37 | */ | 42 | */ |
@@ -170,6 +175,8 @@ int pcibios_plat_dev_init(struct pci_dev *dev) | |||
170 | pci_write_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, dconfig); | 175 | pci_write_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, dconfig); |
171 | } | 176 | } |
172 | 177 | ||
178 | dev->dev.archdata.dma_ops = octeon_pci_dma_map_ops; | ||
179 | |||
173 | return 0; | 180 | return 0; |
174 | } | 181 | } |
175 | 182 | ||
@@ -618,12 +625,10 @@ static int __init octeon_pci_setup(void) | |||
618 | * before the readl()'s below. We don't want BAR2 overlapping | 625 | * before the readl()'s below. We don't want BAR2 overlapping |
619 | * with BAR0/BAR1 during these reads. | 626 | * with BAR0/BAR1 during these reads. |
620 | */ | 627 | */ |
621 | octeon_npi_write32(CVMX_NPI_PCI_CFG08, 0); | 628 | octeon_npi_write32(CVMX_NPI_PCI_CFG08, |
622 | octeon_npi_write32(CVMX_NPI_PCI_CFG09, 0x80); | 629 | (u32)(OCTEON_BAR2_PCI_ADDRESS & 0xffffffffull)); |
623 | 630 | octeon_npi_write32(CVMX_NPI_PCI_CFG09, | |
624 | /* Disable the BAR1 movable mappings */ | 631 | (u32)(OCTEON_BAR2_PCI_ADDRESS >> 32)); |
625 | for (index = 0; index < 32; index++) | ||
626 | octeon_npi_write32(CVMX_NPI_PCI_BAR1_INDEXX(index), 0); | ||
627 | 632 | ||
628 | if (octeon_dma_bar_type == OCTEON_DMA_BAR_TYPE_BIG) { | 633 | if (octeon_dma_bar_type == OCTEON_DMA_BAR_TYPE_BIG) { |
629 | /* Remap the Octeon BAR 0 to 0-2GB */ | 634 | /* Remap the Octeon BAR 0 to 0-2GB */ |
@@ -637,6 +642,25 @@ static int __init octeon_pci_setup(void) | |||
637 | octeon_npi_write32(CVMX_NPI_PCI_CFG06, 2ul << 30); | 642 | octeon_npi_write32(CVMX_NPI_PCI_CFG06, 2ul << 30); |
638 | octeon_npi_write32(CVMX_NPI_PCI_CFG07, 0); | 643 | octeon_npi_write32(CVMX_NPI_PCI_CFG07, 0); |
639 | 644 | ||
645 | /* BAR1 movable mappings set for identity mapping */ | ||
646 | octeon_bar1_pci_phys = 0x80000000ull; | ||
647 | for (index = 0; index < 32; index++) { | ||
648 | union cvmx_pci_bar1_indexx bar1_index; | ||
649 | |||
650 | bar1_index.u32 = 0; | ||
651 | /* Address bits[35:22] sent to L2C */ | ||
652 | bar1_index.s.addr_idx = | ||
653 | (octeon_bar1_pci_phys >> 22) + index; | ||
654 | /* Don't put PCI accesses in L2. */ | ||
655 | bar1_index.s.ca = 1; | ||
656 | /* Endian Swap Mode */ | ||
657 | bar1_index.s.end_swp = 1; | ||
658 | /* Set '1' when the selected address range is valid. */ | ||
659 | bar1_index.s.addr_v = 1; | ||
660 | octeon_npi_write32(CVMX_NPI_PCI_BAR1_INDEXX(index), | ||
661 | bar1_index.u32); | ||
662 | } | ||
663 | |||
640 | /* Devices go after BAR1 */ | 664 | /* Devices go after BAR1 */ |
641 | octeon_pci_mem_resource.start = | 665 | octeon_pci_mem_resource.start = |
642 | OCTEON_PCI_MEMSPACE_OFFSET + (4ul << 30) - | 666 | OCTEON_PCI_MEMSPACE_OFFSET + (4ul << 30) - |
@@ -652,6 +676,27 @@ static int __init octeon_pci_setup(void) | |||
652 | octeon_npi_write32(CVMX_NPI_PCI_CFG06, 0); | 676 | octeon_npi_write32(CVMX_NPI_PCI_CFG06, 0); |
653 | octeon_npi_write32(CVMX_NPI_PCI_CFG07, 0); | 677 | octeon_npi_write32(CVMX_NPI_PCI_CFG07, 0); |
654 | 678 | ||
679 | /* BAR1 movable regions contiguous to cover the swiotlb */ | ||
680 | octeon_bar1_pci_phys = | ||
681 | virt_to_phys(octeon_swiotlb) & ~((1ull << 22) - 1); | ||
682 | |||
683 | for (index = 0; index < 32; index++) { | ||
684 | union cvmx_pci_bar1_indexx bar1_index; | ||
685 | |||
686 | bar1_index.u32 = 0; | ||
687 | /* Address bits[35:22] sent to L2C */ | ||
688 | bar1_index.s.addr_idx = | ||
689 | (octeon_bar1_pci_phys >> 22) + index; | ||
690 | /* Don't put PCI accesses in L2. */ | ||
691 | bar1_index.s.ca = 1; | ||
692 | /* Endian Swap Mode */ | ||
693 | bar1_index.s.end_swp = 1; | ||
694 | /* Set '1' when the selected address range is valid. */ | ||
695 | bar1_index.s.addr_v = 1; | ||
696 | octeon_npi_write32(CVMX_NPI_PCI_BAR1_INDEXX(index), | ||
697 | bar1_index.u32); | ||
698 | } | ||
699 | |||
655 | /* Devices go after BAR0 */ | 700 | /* Devices go after BAR0 */ |
656 | octeon_pci_mem_resource.start = | 701 | octeon_pci_mem_resource.start = |
657 | OCTEON_PCI_MEMSPACE_OFFSET + (128ul << 20) + | 702 | OCTEON_PCI_MEMSPACE_OFFSET + (128ul << 20) + |
@@ -667,6 +712,9 @@ static int __init octeon_pci_setup(void) | |||
667 | * was setup properly. | 712 | * was setup properly. |
668 | */ | 713 | */ |
669 | cvmx_write_csr(CVMX_NPI_PCI_INT_SUM2, -1); | 714 | cvmx_write_csr(CVMX_NPI_PCI_INT_SUM2, -1); |
715 | |||
716 | octeon_pci_dma_init(); | ||
717 | |||
670 | return 0; | 718 | return 0; |
671 | } | 719 | } |
672 | 720 | ||