diff options
-rw-r--r-- | arch/arm/mach-tegra/Kconfig | 8 | ||||
-rw-r--r-- | arch/arm/mach-tegra/Makefile | 6 | ||||
-rw-r--r-- | arch/arm/mach-tegra/include/mach/hardware.h | 7 | ||||
-rw-r--r-- | arch/arm/mach-tegra/pci.c | 108 |
4 files changed, 128 insertions, 1 deletions
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig index ac2824d57464..85154422c9cf 100644 --- a/arch/arm/mach-tegra/Kconfig +++ b/arch/arm/mach-tegra/Kconfig @@ -76,6 +76,14 @@ config TEGRA_ODM_VIBRATE Adds a timed output vibrator device node for an NVIDIA Tegra ODM kit vibrator driver +config TEGRA_PCI + boolean "PCIe host controller driver" + depends on !ARCH_TEGRA_1x_SOC + select PCI + default n + help + Adds PCIe Host controller driver for tegra2 based systems + config TEGRA_SNOR boolean diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile index 84fcff9cd12d..6b8ac3027872 100644 --- a/arch/arm/mach-tegra/Makefile +++ b/arch/arm/mach-tegra/Makefile @@ -60,5 +60,9 @@ obj-$(CONFIG_TEGRA_ODM_RFKILL) += tegra_rfkill_odm.o obj-$(CONFIG_TEGRA_ODM_VIBRATE) += tegra_vibrate.o # NvEc -obj-$(CONFIG_TEGRA_NVEC) += nvec/ +obj-$(CONFIG_TEGRA_NVEC) += nvec/ obj-$(CONFIG_TEGRA_NVEC_USER) += nvec_user.o + +# PCIe support +obj-$(CONFIG_TEGRA_PCI) += pci.o + diff --git a/arch/arm/mach-tegra/include/mach/hardware.h b/arch/arm/mach-tegra/include/mach/hardware.h index 045db3bc41cd..911f7a70ee83 100644 --- a/arch/arm/mach-tegra/include/mach/hardware.h +++ b/arch/arm/mach-tegra/include/mach/hardware.h @@ -20,4 +20,11 @@ #ifndef __MACH_TEGRA_HARDWARE_H +#define pcibios_assign_all_busses() 1 + +extern unsigned long pci_tegra_get_base(char *aperture); + +#define PCIBIOS_MIN_IO pci_tegra_get_base("io") +#define PCIBIOS_MIN_MEM pci_tegra_get_base("mem") + #endif diff --git a/arch/arm/mach-tegra/pci.c b/arch/arm/mach-tegra/pci.c new file mode 100644 index 000000000000..dcfdb7981464 --- /dev/null +++ b/arch/arm/mach-tegra/pci.c @@ -0,0 +1,108 @@ +/* + * arch/arm/mach-tegra/pci.c + * + * PCIe host controller driver for TEGRA(2) SOCs + * + * Copyright (c) 2008-2009, NVIDIA Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <linux/kernel.h> +#include <linux/pci.h> +#include <asm/mach/pci.h> +#include <linux/interrupt.h> +#include <linux/irq.h> + +static int __init pcie_tegra_init(void); + +static void __init pci_tegra_preinit(void); +static int __init pci_tegra_setup(int nr, struct pci_sys_data *data); +static struct pci_bus __init *pci_tegra_scan_bus(int nr, + struct pci_sys_data *sys); + +static int pci_tegra_read_conf(struct pci_bus *bus, u32 devfn, + int where, int size, u32 *val); +static int pci_tegra_read_conf(struct pci_bus *bus, u32 devfn, + int where, int size, u32 *val); + +static int __init pcie_tegra_init(void); + +unsigned long pci_tegra_get_base(char *aperture) +{ + if (!strcmp(aperture, "mem")) + return 0x90000000; + else if (!strcmp(aperture, "io")) + return 0x82000000; + else + return (unsigned long)-1; +} + +static int pci_tegra_read_conf(struct pci_bus *bus, u32 devfn, + int where, int size, u32 *val) +{ + int i; + + for (i=0; i<size; i++) + ((__u8 *)val)[i] = 0xff; + + return PCIBIOS_SUCCESSFUL; +} + +static int pci_tegra_write_conf(struct pci_bus *bus, u32 devfn, + int where, int size, u32 val) +{ + return PCIBIOS_SUCCESSFUL; +} + +static struct pci_ops pci_tegra_ops = { + .read = pci_tegra_read_conf, + .write = pci_tegra_write_conf, +}; + +static void __init pci_tegra_preinit(void) +{ + +} + +static int __init pci_tegra_setup(int nr, struct pci_sys_data *data) +{ + return (nr == 0); +} + +static struct pci_bus __init *pci_tegra_scan_bus(int nr, + struct pci_sys_data *sys) +{ + if (nr == 0) + return pci_scan_bus(sys->busnr, &pci_tegra_ops, sys); + + return NULL; +} + +static struct hw_pci pci_tegra_data __initdata = { + .nr_controllers = 2, + .preinit = pci_tegra_preinit, + .setup = pci_tegra_setup, + .scan = pci_tegra_scan_bus, + .swizzle = pci_std_swizzle, +}; + +late_initcall(pcie_tegra_init); + +static int __init pcie_tegra_init(void) +{ + pci_common_init(&pci_tegra_data); + return 0; +} |