diff options
| author | Mike Rapoport <mike@compulab.co.il> | 2010-09-27 05:26:33 -0400 |
|---|---|---|
| committer | Colin Cross <ccross@android.com> | 2010-10-21 21:13:02 -0400 |
| commit | 77ffc1465cec32489889d6bc9c288b7b0d2ce9fb (patch) | |
| tree | bb61f413ebaa2b4923e5af6ea633b112021276c6 | |
| parent | 8d685bc5e5cad76c05c9986c23a821c5bcef7c16 (diff) | |
tegra: add PCI Express support
Change-Id: Ibd0bcd46895eb88952b9db29e1f68572d39aae01
Signed-off-by: Mike Rapoport <mike@compulab.co.il>
Acked-by: Arnd Bergmann <arnd@arndb.de>
CC: Russell King <linux@arm.linux.org.uk>
CC: Gary King <GKing@nvidia.com>
Signed-off-by: Colin Cross <ccross@android.com>
| -rw-r--r-- | arch/arm/mach-tegra/Kconfig | 4 | ||||
| -rw-r--r-- | arch/arm/mach-tegra/Makefile | 1 | ||||
| -rw-r--r-- | arch/arm/mach-tegra/board.h | 1 | ||||
| -rw-r--r-- | arch/arm/mach-tegra/include/mach/hardware.h | 4 | ||||
| -rw-r--r-- | arch/arm/mach-tegra/include/mach/io.h | 12 | ||||
| -rw-r--r-- | arch/arm/mach-tegra/pcie.c | 915 |
6 files changed, 936 insertions, 1 deletions
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig index 8e32d9d7ec8d..acd9552f8ada 100644 --- a/arch/arm/mach-tegra/Kconfig +++ b/arch/arm/mach-tegra/Kconfig | |||
| @@ -16,6 +16,10 @@ config ARCH_TEGRA_2x_SOC | |||
| 16 | 16 | ||
| 17 | endchoice | 17 | endchoice |
| 18 | 18 | ||
| 19 | config TEGRA_PCI | ||
| 20 | bool "PCI Express support" | ||
| 21 | select PCI | ||
| 22 | |||
| 19 | comment "Tegra board type" | 23 | comment "Tegra board type" |
| 20 | 24 | ||
| 21 | config MACH_HARMONY | 25 | config MACH_HARMONY |
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile index fc069a9e0f6b..b4c07e67a1fb 100644 --- a/arch/arm/mach-tegra/Makefile +++ b/arch/arm/mach-tegra/Makefile | |||
| @@ -14,6 +14,7 @@ obj-$(CONFIG_SMP) += platsmp.o localtimer.o headsmp.o | |||
| 14 | obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o | 14 | obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o |
| 15 | obj-$(CONFIG_TEGRA_SYSTEM_DMA) += dma.o | 15 | obj-$(CONFIG_TEGRA_SYSTEM_DMA) += dma.o |
| 16 | obj-$(CONFIG_CPU_FREQ) += cpu-tegra.o | 16 | obj-$(CONFIG_CPU_FREQ) += cpu-tegra.o |
| 17 | obj-$(CONFIG_TEGRA_PCI) += pcie.o | ||
| 17 | 18 | ||
| 18 | obj-${CONFIG_MACH_HARMONY} += board-harmony.o | 19 | obj-${CONFIG_MACH_HARMONY} += board-harmony.o |
| 19 | obj-${CONFIG_MACH_HARMONY} += board-harmony-pinmux.o | 20 | obj-${CONFIG_MACH_HARMONY} += board-harmony-pinmux.o |
diff --git a/arch/arm/mach-tegra/board.h b/arch/arm/mach-tegra/board.h index 3d06354136f2..0de565ca37c5 100644 --- a/arch/arm/mach-tegra/board.h +++ b/arch/arm/mach-tegra/board.h | |||
| @@ -27,6 +27,7 @@ void __init tegra_common_init(void); | |||
| 27 | void __init tegra_map_common_io(void); | 27 | void __init tegra_map_common_io(void); |
| 28 | void __init tegra_init_irq(void); | 28 | void __init tegra_init_irq(void); |
| 29 | void __init tegra_init_clock(void); | 29 | void __init tegra_init_clock(void); |
| 30 | int __init tegra_pcie_init(bool init_port0, bool init_port1); | ||
| 30 | 31 | ||
| 31 | extern struct sys_timer tegra_timer; | 32 | extern struct sys_timer tegra_timer; |
| 32 | #endif | 33 | #endif |
diff --git a/arch/arm/mach-tegra/include/mach/hardware.h b/arch/arm/mach-tegra/include/mach/hardware.h index 6014edf60d93..56e43b3a5b97 100644 --- a/arch/arm/mach-tegra/include/mach/hardware.h +++ b/arch/arm/mach-tegra/include/mach/hardware.h | |||
| @@ -21,4 +21,8 @@ | |||
| 21 | #ifndef __MACH_TEGRA_HARDWARE_H | 21 | #ifndef __MACH_TEGRA_HARDWARE_H |
| 22 | #define __MACH_TEGRA_HARDWARE_H | 22 | #define __MACH_TEGRA_HARDWARE_H |
| 23 | 23 | ||
| 24 | #define PCIBIOS_MIN_IO 0x1000 | ||
| 25 | #define PCIBIOS_MIN_MEM 0 | ||
| 26 | #define pcibios_assign_all_busses() 1 | ||
| 27 | |||
| 24 | #endif | 28 | #endif |
diff --git a/arch/arm/mach-tegra/include/mach/io.h b/arch/arm/mach-tegra/include/mach/io.h index 16f16189b5eb..f0981b1ac59e 100644 --- a/arch/arm/mach-tegra/include/mach/io.h +++ b/arch/arm/mach-tegra/include/mach/io.h | |||
| @@ -21,7 +21,7 @@ | |||
| 21 | #ifndef __MACH_TEGRA_IO_H | 21 | #ifndef __MACH_TEGRA_IO_H |
| 22 | #define __MACH_TEGRA_IO_H | 22 | #define __MACH_TEGRA_IO_H |
| 23 | 23 | ||
| 24 | #define IO_SPACE_LIMIT 0xffffffff | 24 | #define IO_SPACE_LIMIT 0xffff |
| 25 | 25 | ||
| 26 | /* On TEGRA, many peripherals are very closely packed in | 26 | /* On TEGRA, many peripherals are very closely packed in |
| 27 | * two 256MB io windows (that actually only use about 64KB | 27 | * two 256MB io windows (that actually only use about 64KB |
| @@ -73,10 +73,20 @@ void tegra_iounmap(volatile void __iomem *addr); | |||
| 73 | 73 | ||
| 74 | #define IO_ADDRESS(n) ((void __iomem *) IO_TO_VIRT(n)) | 74 | #define IO_ADDRESS(n) ((void __iomem *) IO_TO_VIRT(n)) |
| 75 | 75 | ||
| 76 | #ifdef CONFIG_TEGRA_PCI | ||
| 77 | extern void __iomem *tegra_pcie_io_base; | ||
| 78 | |||
| 79 | static inline void __iomem *__io(unsigned long addr) | ||
| 80 | { | ||
| 81 | return tegra_pcie_io_base + (addr & IO_SPACE_LIMIT); | ||
| 82 | } | ||
| 83 | #else | ||
| 76 | static inline void __iomem *__io(unsigned long addr) | 84 | static inline void __iomem *__io(unsigned long addr) |
| 77 | { | 85 | { |
| 78 | return (void __iomem *)addr; | 86 | return (void __iomem *)addr; |
| 79 | } | 87 | } |
| 88 | #endif | ||
| 89 | |||
| 80 | #define __io(a) __io(a) | 90 | #define __io(a) __io(a) |
| 81 | #define __mem_pci(a) (a) | 91 | #define __mem_pci(a) (a) |
| 82 | 92 | ||
diff --git a/arch/arm/mach-tegra/pcie.c b/arch/arm/mach-tegra/pcie.c new file mode 100644 index 000000000000..53f5fa37014a --- /dev/null +++ b/arch/arm/mach-tegra/pcie.c | |||
| @@ -0,0 +1,915 @@ | |||
| 1 | /* | ||
| 2 | * arch/arm/mach-tegra/pci.c | ||
| 3 | * | ||
| 4 | * PCIe host controller driver for TEGRA(2) SOCs | ||
| 5 | * | ||
| 6 | * Copyright (c) 2010, CompuLab, Ltd. | ||
| 7 | * Author: Mike Rapoport <mike@compulab.co.il> | ||
| 8 | * | ||
| 9 | * Based on NVIDIA PCIe driver | ||
| 10 | * Copyright (c) 2008-2009, NVIDIA Corporation. | ||
| 11 | * | ||
| 12 | * Bits taken from arch/arm/mach-dove/pcie.c | ||
| 13 | * | ||
| 14 | * This program is free software; you can redistribute it and/or modify | ||
| 15 | * it under the terms of the GNU General Public License as published by | ||
| 16 | * the Free Software Foundation; either version 2 of the License, or | ||
| 17 | * (at your option) any later version. | ||
| 18 | * | ||
| 19 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
| 20 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 21 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 22 | * more details. | ||
| 23 | * | ||
| 24 | * You should have received a copy of the GNU General Public License along | ||
| 25 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
| 26 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
| 27 | */ | ||
| 28 | |||
| 29 | #include <linux/kernel.h> | ||
| 30 | #include <linux/pci.h> | ||
| 31 | #include <linux/interrupt.h> | ||
| 32 | #include <linux/irq.h> | ||
| 33 | #include <linux/clk.h> | ||
| 34 | #include <linux/delay.h> | ||
| 35 | |||
| 36 | #include <asm/sizes.h> | ||
| 37 | #include <asm/mach/pci.h> | ||
| 38 | |||
| 39 | #include <mach/pinmux.h> | ||
| 40 | #include <mach/iomap.h> | ||
| 41 | #include <mach/clk.h> | ||
| 42 | |||
| 43 | /* register definitions */ | ||
| 44 | #define AFI_OFFSET 0x3800 | ||
| 45 | #define PADS_OFFSET 0x3000 | ||
| 46 | #define RP0_OFFSET 0x0000 | ||
| 47 | #define RP1_OFFSET 0x1000 | ||
| 48 | |||
| 49 | #define AFI_AXI_BAR0_SZ 0x00 | ||
| 50 | #define AFI_AXI_BAR1_SZ 0x04 | ||
| 51 | #define AFI_AXI_BAR2_SZ 0x08 | ||
| 52 | #define AFI_AXI_BAR3_SZ 0x0c | ||
| 53 | #define AFI_AXI_BAR4_SZ 0x10 | ||
| 54 | #define AFI_AXI_BAR5_SZ 0x14 | ||
| 55 | |||
| 56 | #define AFI_AXI_BAR0_START 0x18 | ||
| 57 | #define AFI_AXI_BAR1_START 0x1c | ||
| 58 | #define AFI_AXI_BAR2_START 0x20 | ||
| 59 | #define AFI_AXI_BAR3_START 0x24 | ||
| 60 | #define AFI_AXI_BAR4_START 0x28 | ||
| 61 | #define AFI_AXI_BAR5_START 0x2c | ||
| 62 | |||
| 63 | #define AFI_FPCI_BAR0 0x30 | ||
| 64 | #define AFI_FPCI_BAR1 0x34 | ||
| 65 | #define AFI_FPCI_BAR2 0x38 | ||
| 66 | #define AFI_FPCI_BAR3 0x3c | ||
| 67 | #define AFI_FPCI_BAR4 0x40 | ||
| 68 | #define AFI_FPCI_BAR5 0x44 | ||
| 69 | |||
| 70 | #define AFI_CACHE_BAR0_SZ 0x48 | ||
| 71 | #define AFI_CACHE_BAR0_ST 0x4c | ||
| 72 | #define AFI_CACHE_BAR1_SZ 0x50 | ||
| 73 | #define AFI_CACHE_BAR1_ST 0x54 | ||
| 74 | |||
| 75 | #define AFI_MSI_BAR_SZ 0x60 | ||
| 76 | #define AFI_MSI_FPCI_BAR_ST 0x64 | ||
| 77 | #define AFI_MSI_AXI_BAR_ST 0x68 | ||
| 78 | |||
| 79 | #define AFI_CONFIGURATION 0xac | ||
| 80 | #define AFI_CONFIGURATION_EN_FPCI (1 << 0) | ||
| 81 | |||
| 82 | #define AFI_FPCI_ERROR_MASKS 0xb0 | ||
| 83 | |||
| 84 | #define AFI_INTR_MASK 0xb4 | ||
| 85 | #define AFI_INTR_MASK_INT_MASK (1 << 0) | ||
| 86 | #define AFI_INTR_MASK_MSI_MASK (1 << 8) | ||
| 87 | |||
| 88 | #define AFI_INTR_CODE 0xb8 | ||
| 89 | #define AFI_INTR_CODE_MASK 0xf | ||
| 90 | #define AFI_INTR_MASTER_ABORT 4 | ||
| 91 | #define AFI_INTR_LEGACY 6 | ||
| 92 | |||
| 93 | #define AFI_INTR_SIGNATURE 0xbc | ||
| 94 | #define AFI_SM_INTR_ENABLE 0xc4 | ||
| 95 | |||
| 96 | #define AFI_AFI_INTR_ENABLE 0xc8 | ||
| 97 | #define AFI_ | ||
