[PATCH 03/15] ARM: tegra: use fixed PCI i/o mapping

Rob Herring robherring2 at gmail.com
Sun Jul 8 10:17:44 EDT 2012


On 07/08/2012 01:09 AM, Thierry Reding wrote:
> On Fri, Jul 06, 2012 at 01:40:28PM -0500, Rob Herring wrote:
>> From: Rob Herring <rob.herring at calxeda.com>
>>
>> Move tegra PCI to fixed i/o mapping and remove io.h.
>>
>> Signed-off-by: Rob Herring <rob.herring at calxeda.com>
>> Cc: Colin Cross <ccross at android.com>
>> Cc: Olof Johansson <olof at lixom.net>
>> Acked-by: Stephen Warren <swarren at nvidia.com>
>> ---
>>  arch/arm/Kconfig                         |    1 -
>>  arch/arm/mach-tegra/include/mach/io.h    |   46 ------------------------------
>>  arch/arm/mach-tegra/include/mach/iomap.h |    3 ++
>>  arch/arm/mach-tegra/io.c                 |    2 ++
>>  arch/arm/mach-tegra/pcie.c               |   43 ++++------------------------
>>  5 files changed, 10 insertions(+), 85 deletions(-)
>>  delete mode 100644 arch/arm/mach-tegra/include/mach/io.h
> 
> Hi Rob,
> 
> generally this looks good. However I've been working on a rewrite of the
> Tegra PCIe support to make it work as a driver and add DT support. This
> entails that PCIe support isn't initialized until very late in the
> process because it makes use of deferred probe if some regulators aren't
> available. One problem caused by this is that it suddenly requires a lot
> of code marked as __init to be available after the init phase and I see
> that you've introduced pci_map_io_single_pfn() that is __init annotated,
> so it will cause problems when used with my patches.

This function can only be called during .map_io anyway, so the __init is
irrelevant.

> I'm not very familiar with the inner workings of the iotable and the
> mappings initialized by it, but I wonder if this can be done dynamically
> at a later stage. The way this is currently done in this patch, the I/O
> region is statically mapped from a fixed offset within the PCIe address
> range. Part of the patches to add DT support is to allow this region to
> be defined by the DT, so that will obviously also create problems.

Is the i/o address something you could extract from DT earlier? This can
be done separately if it doesn't require information from the driver.

I'm sure exactly how to do a fixed virtual mapping other than the
io_table mappings. There was some discussion of use fixmap region
previously, but doing so will be a bit more complex. I'll look into this
some.

Rob

> If both of those issues can be easily addressed, then this certainly
> looks very nice.
> 
> Thierry
> 
>>
>> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
>> index 8fb7e4a..ac446e3 100644
>> --- a/arch/arm/Kconfig
>> +++ b/arch/arm/Kconfig
>> @@ -644,7 +644,6 @@ config ARCH_TEGRA
>>  	select HAVE_CLK
>>  	select HAVE_SMP
>>  	select MIGHT_HAVE_CACHE_L2X0
>> -	select NEED_MACH_IO_H if PCI
>>  	select ARCH_HAS_CPUFREQ
>>  	help
>>  	  This enables support for NVIDIA Tegra based systems (Tegra APX,
>> diff --git a/arch/arm/mach-tegra/include/mach/io.h b/arch/arm/mach-tegra/include/mach/io.h
>> deleted file mode 100644
>> index fe700f9..0000000
>> --- a/arch/arm/mach-tegra/include/mach/io.h
>> +++ /dev/null
>> @@ -1,46 +0,0 @@
>> -/*
>> - * arch/arm/mach-tegra/include/mach/io.h
>> - *
>> - * Copyright (C) 2010 Google, Inc.
>> - *
>> - * Author:
>> - *	Colin Cross <ccross at google.com>
>> - *	Erik Gilling <konkers at google.com>
>> - *
>> - * This software is licensed under the terms of the GNU General Public
>> - * License version 2, as published by the Free Software Foundation, and
>> - * may be copied, distributed, and modified under those terms.
>> - *
>> - * 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.
>> - *
>> - */
>> -
>> -#ifndef __MACH_TEGRA_IO_H
>> -#define __MACH_TEGRA_IO_H
>> -
>> -#define IO_SPACE_LIMIT 0xffff
>> -
>> -#ifndef __ASSEMBLER__
>> -
>> -#ifdef CONFIG_TEGRA_PCI
>> -extern void __iomem *tegra_pcie_io_base;
>> -
>> -static inline void __iomem *__io(unsigned long addr)
>> -{
>> -	return tegra_pcie_io_base + (addr & IO_SPACE_LIMIT);
>> -}
>> -#else
>> -static inline void __iomem *__io(unsigned long addr)
>> -{
>> -	return (void __iomem *)addr;
>> -}
>> -#endif
>> -
>> -#define __io(a)         __io(a)
>> -
>> -#endif
>> -
>> -#endif
>> diff --git a/arch/arm/mach-tegra/include/mach/iomap.h b/arch/arm/mach-tegra/include/mach/iomap.h
>> index 7e76da7..fee3a94 100644
>> --- a/arch/arm/mach-tegra/include/mach/iomap.h
>> +++ b/arch/arm/mach-tegra/include/mach/iomap.h
>> @@ -303,6 +303,9 @@
>>  #define IO_APB_VIRT	IOMEM(0xFE300000)
>>  #define IO_APB_SIZE	SZ_1M
>>  
>> +#define TEGRA_PCIE_BASE		0x80000000
>> +#define TEGRA_PCIE_IO_BASE	(TEGRA_PCIE_BASE + SZ_4M)
>> +
>>  #define IO_TO_VIRT_BETWEEN(p, st, sz)	((p) >= (st) && (p) < ((st) + (sz)))
>>  #define IO_TO_VIRT_XLATE(p, pst, vst)	(((p) - (pst) + (vst)))
>>  
>> diff --git a/arch/arm/mach-tegra/io.c b/arch/arm/mach-tegra/io.c
>> index 58b4baf..7a29e10 100644
>> --- a/arch/arm/mach-tegra/io.c
>> +++ b/arch/arm/mach-tegra/io.c
>> @@ -26,6 +26,7 @@
>>  
>>  #include <asm/page.h>
>>  #include <asm/mach/map.h>
>> +#include <asm/mach/pci.h>
>>  #include <mach/iomap.h>
>>  
>>  #include "board.h"
>> @@ -59,5 +60,6 @@ static struct map_desc tegra_io_desc[] __initdata = {
>>  
>>  void __init tegra_map_common_io(void)
>>  {
>> +	pci_map_io_single(TEGRA_PCIE_IO_BASE);
>>  	iotable_init(tegra_io_desc, ARRAY_SIZE(tegra_io_desc));
>>  }
>> diff --git a/arch/arm/mach-tegra/pcie.c b/arch/arm/mach-tegra/pcie.c
>> index 0e09137..c989a8e 100644
>> --- a/arch/arm/mach-tegra/pcie.c
>> +++ b/arch/arm/mach-tegra/pcie.c
>> @@ -171,8 +171,6 @@ static void __iomem *reg_pmc_base = IO_ADDRESS(TEGRA_PMC_BASE);
>>   * 0x90000000 - 0x9fffffff - non-prefetchable memory
>>   * 0xa0000000 - 0xbfffffff - prefetchable memory
>>   */
>> -#define TEGRA_PCIE_BASE		0x80000000
>> -
>>  #define PCIE_REGS_SZ		SZ_16K
>>  #define PCIE_CFG_OFF		PCIE_REGS_SZ
>>  #define PCIE_CFG_SZ		SZ_1M
>> @@ -180,8 +178,6 @@ static void __iomem *reg_pmc_base = IO_ADDRESS(TEGRA_PMC_BASE);
>>  #define PCIE_EXT_CFG_SZ		SZ_1M
>>  #define PCIE_IOMAP_SZ		(PCIE_REGS_SZ + PCIE_CFG_SZ + PCIE_EXT_CFG_SZ)
>>  
>> -#define MMIO_BASE		(TEGRA_PCIE_BASE + SZ_4M)
>> -#define MMIO_SIZE		SZ_64K
>>  #define MEM_BASE_0		(TEGRA_PCIE_BASE + SZ_256M)
>>  #define MEM_SIZE_0		SZ_128M
>>  #define MEM_BASE_1		(MEM_BASE_0 + MEM_SIZE_0)
>> @@ -223,17 +219,7 @@ struct tegra_pcie_info {
>>  	struct clk		*pll_e;
>>  };
>>  
>> -static struct tegra_pcie_info tegra_pcie = {
>> -	.res_mmio = {
>> -		.name = "PCI IO",
>> -		.start = MMIO_BASE,
>> -		.end = MMIO_BASE + MMIO_SIZE - 1,
>> -		.flags = IORESOURCE_MEM,
>> -	},
>> -};
>> -
>> -void __iomem *tegra_pcie_io_base;
>> -EXPORT_SYMBOL(tegra_pcie_io_base);
>> +static struct tegra_pcie_info tegra_pcie;
>>  
>>  static inline void afi_writel(u32 value, unsigned long offset)
>>  {
>> @@ -403,7 +389,7 @@ static int tegra_pcie_setup(int nr, struct pci_sys_data *sys)
>>  		pp->res[0].end = pp->res[0].start + SZ_32K - 1;
>>  	} else {
>>  		pp->res[0].start = PCIBIOS_MIN_IO + SZ_32K;
>> -		pp->res[0].end = IO_SPACE_LIMIT;
>> +		pp->res[0].end = SZ_64K - 1;
>>  	}
>>  	pp->res[0].flags = IORESOURCE_IO;
>>  	if (request_resource(&ioport_resource, &pp->res[0]))
>> @@ -541,8 +527,8 @@ static void tegra_pcie_setup_translations(void)
>>  
>>  	/* Bar 2: downstream IO bar */
>>  	fpci_bar = ((__u32)0xfdfc << 16);
>> -	size = MMIO_SIZE;
>> -	axi_address = MMIO_BASE;
>> +	size = SZ_64K;
>> +	axi_address = TEGRA_PCIE_IO_BASE;
>>  	afi_writel(axi_address, AFI_AXI_BAR2_START);
>>  	afi_writel(size >> 12, AFI_AXI_BAR2_SZ);
>>  	afi_writel(fpci_bar, AFI_FPCI_BAR2);
>> @@ -776,7 +762,6 @@ static void tegra_pcie_clocks_put(void)
>>  
>>  static int __init tegra_pcie_get_resources(void)
>>  {
>> -	struct resource *res_mmio = &tegra_pcie.res_mmio;
>>  	int err;
>>  
>>  	err = tegra_pcie_clocks_get();
>> @@ -798,34 +783,16 @@ static int __init tegra_pcie_get_resources(void)
>>  		goto err_map_reg;
>>  	}
>>  
>> -	err = request_resource(&iomem_resource, res_mmio);
>> -	if (err) {
>> -		pr_err("PCIE: Failed to request resources: %d\n", err);
>> -		goto err_req_io;
>> -	}
>> -
>> -	tegra_pcie_io_base = ioremap_nocache(res_mmio->start,
>> -					     resource_size(res_mmio));
>> -	if (tegra_pcie_io_base == NULL) {
>> -		pr_err("PCIE: Failed to map IO\n");
>> -		err = -ENOMEM;
>> -		goto err_map_io;
>> -	}
>> -
>>  	err = request_irq(INT_PCIE_INTR, tegra_pcie_isr,
>>  			  IRQF_SHARED, "PCIE", &tegra_pcie);
>>  	if (err) {
>>  		pr_err("PCIE: Failed to register IRQ: %d\n", err);
>> -		goto err_irq;
>> +		goto err_req_io;
>>  	}
>>  	set_irq_flags(INT_PCIE_INTR, IRQF_VALID);
>>  
>>  	return 0;
>>  
>> -err_irq:
>> -	iounmap(tegra_pcie_io_base);
>> -err_map_io:
>> -	release_resource(&tegra_pcie.res_mmio);
>>  err_req_io:
>>  	iounmap(tegra_pcie.regs);
>>  err_map_reg:
>> -- 
>> 1.7.9.5
>>
>>
>>




More information about the linux-arm-kernel mailing list