aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Rapoport <mike@compulab.co.il>2010-09-27 05:26:33 -0400
committerColin Cross <ccross@android.com>2010-10-21 21:13:02 -0400
commit77ffc1465cec32489889d6bc9c288b7b0d2ce9fb (patch)
treebb61f413ebaa2b4923e5af6ea633b112021276c6
parent8d685bc5e5cad76c05c9986c23a821c5bcef7c16 (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/Kconfig4
-rw-r--r--arch/arm/mach-tegra/Makefile1
-rw-r--r--arch/arm/mach-tegra/board.h1
-rw-r--r--arch/arm/mach-tegra/include/mach/hardware.h4
-rw-r--r--arch/arm/mach-tegra/include/mach/io.h12
-rw-r--r--arch/arm/mach-tegra/pcie.c915
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
17endchoice 17endchoice
18 18
19config TEGRA_PCI
20 bool "PCI Express support"
21 select PCI
22
19comment "Tegra board type" 23comment "Tegra board type"
20 24
21config MACH_HARMONY 25config 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
14obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o 14obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
15obj-$(CONFIG_TEGRA_SYSTEM_DMA) += dma.o 15obj-$(CONFIG_TEGRA_SYSTEM_DMA) += dma.o
16obj-$(CONFIG_CPU_FREQ) += cpu-tegra.o 16obj-$(CONFIG_CPU_FREQ) += cpu-tegra.o
17obj-$(CONFIG_TEGRA_PCI) += pcie.o
17 18
18obj-${CONFIG_MACH_HARMONY} += board-harmony.o 19obj-${CONFIG_MACH_HARMONY} += board-harmony.o
19obj-${CONFIG_MACH_HARMONY} += board-harmony-pinmux.o 20obj-${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);
27void __init tegra_map_common_io(void); 27void __init tegra_map_common_io(void);
28void __init tegra_init_irq(void); 28void __init tegra_init_irq(void);
29void __init tegra_init_clock(void); 29void __init tegra_init_clock(void);
30int __init tegra_pcie_init(bool init_port0, bool init_port1);
30 31
31extern struct sys_timer tegra_timer; 32extern 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
77extern void __iomem *tegra_pcie_io_base;
78
79static inline void __iomem *__io(unsigned long addr)
80{
81 return tegra_pcie_io_base + (addr & IO_SPACE_LIMIT);
82}
83#else
76static inline void __iomem *__io(unsigned long addr) 84static 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_