select RTC_LIB
select SYS_SUPPORTS_APM_EMULATION
select GENERIC_ATOMIC64 if (CPU_V6 || !CPU_32v6K || !AEABI)
+ select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
select HAVE_OPROFILE if (HAVE_PERF_EVENTS)
select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL
select HAVE_ARCH_KGDB
select GENERIC_IRQ_PROBE
select GENERIC_IRQ_SHOW
select GENERIC_IRQ_PROBE
+ select ARCH_WANT_IPC_PARSE_VERSION
select HARDIRQS_SW_RESEND
select CPU_PM if (SUSPEND || CPU_IDLE)
select GENERIC_PCI_IOMAP
select GENERIC_SMP_IDLE_THREAD
select KTIME_SCALAR
select GENERIC_CLOCKEVENTS_BROADCAST if SMP
+ select GENERIC_STRNCPY_FROM_USER
+ select GENERIC_STRNLEN_USER
+ select DCACHE_WORD_ACCESS if (CPU_V6 || CPU_V6K || CPU_V7) && !CPU_BIG_ENDIAN
help
The ARM series is a line of low-power-consumption RISC chip designs
licensed by ARM Ltd and targeted at embedded applications and
prompt "ARM system type"
default ARCH_VERSATILE
+config ARCH_SOCFPGA
+ bool "Altera SOCFPGA family"
+ select ARCH_WANT_OPTIONAL_GPIOLIB
+ select ARM_AMBA
+ select ARM_GIC
+ select CACHE_L2X0
+ select CLKDEV_LOOKUP
+ select COMMON_CLK
+ select CPU_V7
+ select DW_APB_TIMER
+ select DW_APB_TIMER_OF
+ select GENERIC_CLOCKEVENTS
+ select GPIO_PL061 if GPIOLIB
+ select HAVE_ARM_SCU
+ select SPARSE_IRQ
+ select USE_OF
+ help
+ This enables support for Altera SOCFPGA Cyclone V platform
+
config ARCH_INTEGRATOR
bool "ARM Ltd. Integrator family"
select ARM_AMBA
select ARCH_HAS_CPUFREQ
- select CLKDEV_LOOKUP
- select HAVE_MACH_CLKDEV
+ select COMMON_CLK
+ select CLK_VERSATILE
select HAVE_TCM
select ICST
select GENERIC_CLOCKEVENTS
select PLAT_VERSATILE
select PLAT_VERSATILE_FPGA_IRQ
- select NEED_MACH_IO_H
select NEED_MACH_MEMORY_H
select SPARSE_IRQ
select MULTI_IRQ_HANDLER
select GENERIC_CLOCKEVENTS
select ARCH_WANT_OPTIONAL_GPIOLIB
select PLAT_VERSATILE
+ select PLAT_VERSATILE_CLOCK
select PLAT_VERSATILE_CLCD
select ARM_TIMER_SP804
select GPIO_PL061 if GPIOLIB
select ICST
select GENERIC_CLOCKEVENTS
select ARCH_WANT_OPTIONAL_GPIOLIB
- select NEED_MACH_IO_H if PCI
select PLAT_VERSATILE
+ select PLAT_VERSATILE_CLOCK
select PLAT_VERSATILE_CLCD
select PLAT_VERSATILE_FPGA_IRQ
select ARM_TIMER_SP804
select ARM_AMBA
select ARM_TIMER_SP804
select CLKDEV_LOOKUP
- select HAVE_MACH_CLKDEV
+ select COMMON_CLK
select GENERIC_CLOCKEVENTS
select HAVE_CLK
select HAVE_PATA_PLATFORM
select NO_IOPORT
select PLAT_VERSATILE
select PLAT_VERSATILE_CLCD
+ select REGULATOR_FIXED_VOLTAGE if REGULATOR
help
This enables support for the ARM Ltd Versatile Express boards.
select ARM_TIMER_SP804
select CACHE_L2X0
select CLKDEV_LOOKUP
+ select COMMON_CLK
select CPU_V7
select GENERIC_CLOCKEVENTS
select HAVE_ARM_SCU
bool "CSR SiRFSoC PRIMA2 ARM Cortex A9 Platform"
select CPU_V7
select NO_IOPORT
+ select ARCH_REQUIRE_GPIOLIB
select GENERIC_CLOCKEVENTS
select CLKDEV_LOOKUP
select GENERIC_IRQ_CHIP
select FOOTBRIDGE
select GENERIC_CLOCKEVENTS
select HAVE_IDE
- select NEED_MACH_IO_H
+ select NEED_MACH_IO_H if !MMU
select NEED_MACH_MEMORY_H
help
Support for systems based on the DC21285 companion chip
select CLKSRC_MMIO
select GENERIC_IRQ_CHIP
select MULTI_IRQ_HANDLER
+ select SPARSE_IRQ
+ select USE_OF
help
Support for Freescale MXC/iMX-based family of processors
select PCI
select ARCH_SUPPORTS_MSI
select VMSPLIT_1G
- select NEED_MACH_IO_H
select NEED_MACH_MEMORY_H
select NEED_RET_TO_USER
help
bool "IOP32x-based"
depends on MMU
select CPU_XSCALE
- select NEED_MACH_IO_H
select NEED_RET_TO_USER
select PLAT_IOP
select PCI
bool "IOP33x-based"
depends on MMU
select CPU_XSCALE
- select NEED_MACH_IO_H
select NEED_RET_TO_USER
select PLAT_IOP
select PCI
help
Support for Intel's IXP4XX (XScale) family of processors.
+config ARCH_MVEBU
+ bool "Marvell SOCs with Device Tree support"
+ select GENERIC_CLOCKEVENTS
+ select MULTI_IRQ_HANDLER
+ select SPARSE_IRQ
+ select CLKSRC_MMIO
+ select GENERIC_IRQ_CHIP
+ select IRQ_DOMAIN
+ select COMMON_CLK
+ help
+ Support for the Marvell SoC Family with device tree support
+
config ARCH_DOVE
bool "Marvell Dove"
select CPU_V7
select PCI
select ARCH_REQUIRE_GPIOLIB
select GENERIC_CLOCKEVENTS
- select NEED_MACH_IO_H
select PLAT_ORION
help
Support for the Marvell Dove SoC 88AP510
select PCI
select ARCH_REQUIRE_GPIOLIB
select GENERIC_CLOCKEVENTS
- select NEED_MACH_IO_H
select PLAT_ORION
help
Support for the following Marvell Kirkwood series SoCs:
select CLKDEV_LOOKUP
select GENERIC_CLOCKEVENTS
select USE_OF
+ select HAVE_PWM
help
Support for the NXP LPC32XX family of processors
select PCI
select ARCH_REQUIRE_GPIOLIB
select GENERIC_CLOCKEVENTS
- select NEED_MACH_IO_H
select PLAT_ORION
help
Support for the following Marvell MV78xx0 series SoCs:
select PCI
select ARCH_REQUIRE_GPIOLIB
select GENERIC_CLOCKEVENTS
- select NEED_MACH_IO_H
select PLAT_ORION
help
Support for the following Marvell Orion 5x series SoCs:
select HAVE_CLK
select HAVE_SMP
select MIGHT_HAVE_CACHE_L2X0
- select NEED_MACH_IO_H if PCI
select ARCH_HAS_CPUFREQ
+ select USE_OF
help
This enables support for NVIDIA Tegra based systems (Tegra APX,
Tegra 6xx and Tegra 2 series).
select ARM_VIC
select CPU_V6K
select DW_APB_TIMER
+ select DW_APB_TIMER_OF
select GENERIC_CLOCKEVENTS
select GENERIC_GPIO
select HAVE_TCM
select PCI
select ARCH_USES_GETTIMEOFFSET
select NEED_MACH_MEMORY_H
- select NEED_MACH_IO_H
help
Support for the StrongARM based Digital DNARD machine, also known
as "Shark" (<http://www.shark-linux.de/shark.html>).
select ARM_VIC
select GENERIC_CLOCKEVENTS
select CLKDEV_LOOKUP
- select HAVE_MACH_CLKDEV
+ select COMMON_CLK
select GENERIC_GPIO
select ARCH_REQUIRE_GPIOLIB
help
select ARM_AMBA
select ARM_VIC
select CPU_ARM926T
- select CLKDEV_LOOKUP
+ select COMMON_CLK
select GENERIC_CLOCKEVENTS
select PINCTRL
select MIGHT_HAVE_CACHE_L2X0
config ARCH_OMAP
bool "TI OMAP"
+ depends on MMU
select HAVE_CLK
select ARCH_REQUIRE_GPIOLIB
select ARCH_HAS_CPUFREQ
select ARCH_HAS_CPUFREQ
select GENERIC_CLOCKEVENTS
select ARCH_REQUIRE_GPIOLIB
- select HAVE_PWM
help
Support for VIA/WonderMedia VT8500/WM85xx System-on-Chip.
# Kconfigs may be included either alphabetically (according to the
# plat- suffix) or along side the corresponding mach-* source.
#
+source "arch/arm/mach-mvebu/Kconfig"
+
source "arch/arm/mach-at91/Kconfig"
source "arch/arm/mach-bcmring/Kconfig"
source "arch/arm/mach-ks8695/Kconfig"
-source "arch/arm/mach-lpc32xx/Kconfig"
-
source "arch/arm/mach-msm/Kconfig"
source "arch/arm/mach-mv78xx0/Kconfig"
bool
select CLKSRC_MMIO
select GENERIC_IRQ_CHIP
+ select IRQ_DOMAIN
select COMMON_CLK
config PLAT_PXA
default 1024 if ARCH_SHMOBILE || ARCH_TEGRA
default 355 if ARCH_U8500
default 264 if MACH_H4700
+ default 512 if SOC_OMAP5
default 0
help
Maximum number of GPIOs in the system.
bootloaders, this option allows zImage to extract the information
from the ATAG list and store it at run time into the appended DTB.
+choice
+ prompt "Kernel command line type" if ARM_ATAG_DTB_COMPAT
+ default ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER
+
+config ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER
+ bool "Use bootloader kernel arguments if available"
+ help
+ Uses the command-line options passed by the boot loader instead of
+ the device tree bootargs property. If the boot loader doesn't provide
+ any, the device tree bootargs property will be used.
+
+config ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND
+ bool "Extend with bootloader kernel arguments"
+ help
+ The command-line arguments provided by the boot loader will be
+ appended to the the device tree bootargs property.
+
+endchoice
+
config CMDLINE
string "Default kernel command string"
default ""
#include <linux/io.h>
#include <asm/mach-types.h>
+ #include <asm/mach/map.h>
#include <asm/mach/pci.h>
static int debug_pci;
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693, pci_fixup_cy82c693);
-static void __init pci_fixup_it8152(struct pci_dev *dev)
+static void __devinit pci_fixup_it8152(struct pci_dev *dev)
{
int i;
/* fixup for ITE 8152 devices */
return irq;
}
+ static int __init pcibios_init_resources(int busnr, struct pci_sys_data *sys)
+ {
+ int ret;
+ struct pci_host_bridge_window *window;
+
+ if (list_empty(&sys->resources)) {
+ pci_add_resource_offset(&sys->resources,
+ &iomem_resource, sys->mem_offset);
+ }
+
+ list_for_each_entry(window, &sys->resources, list) {
+ if (resource_type(window->res) == IORESOURCE_IO)
+ return 0;
+ }
+
+ sys->io_res.start = (busnr * SZ_64K) ? : pcibios_min_io;
+ sys->io_res.end = (busnr + 1) * SZ_64K - 1;
+ sys->io_res.flags = IORESOURCE_IO;
+ sys->io_res.name = sys->io_res_name;
+ sprintf(sys->io_res_name, "PCI%d I/O", busnr);
+
+ ret = request_resource(&ioport_resource, &sys->io_res);
+ if (ret) {
+ pr_err("PCI: unable to allocate I/O port region (%d)\n", ret);
+ return ret;
+ }
+ pci_add_resource_offset(&sys->resources, &sys->io_res,
+ sys->io_offset);
+
+ return 0;
+ }
+
static void __init pcibios_init_hw(struct hw_pci *hw, struct list_head *head)
{
struct pci_sys_data *sys = NULL;
ret = hw->setup(nr, sys);
if (ret > 0) {
- if (list_empty(&sys->resources)) {
- pci_add_resource_offset(&sys->resources,
- &ioport_resource, sys->io_offset);
- pci_add_resource_offset(&sys->resources,
- &iomem_resource, sys->mem_offset);
+ ret = pcibios_init_resources(nr, sys);
+ if (ret) {
+ kfree(sys);
+ break;
}
if (hw->scan)
if (!sys->bus)
panic("PCI: unable to scan bus!");
- busnr = sys->bus->subordinate + 1;
+ busnr = sys->bus->busn_res.end + 1;
list_add(&sys->node, head);
} else {
return 0;
}
+
+ void __init pci_map_io_early(unsigned long pfn)
+ {
+ struct map_desc pci_io_desc = {
+ .virtual = PCI_IO_VIRT_BASE,
+ .type = MT_DEVICE,
+ .length = SZ_64K,
+ };
+
+ pci_io_desc.pfn = pfn;
+ iotable_init(&pci_io_desc, 1);
+ }
.pfn = __phys_to_pfn(DOVE_NB_REGS_PHYS_BASE),
.length = DOVE_NB_REGS_SIZE,
.type = MT_DEVICE,
- }, {
- .virtual = DOVE_PCIE0_IO_VIRT_BASE,
- .pfn = __phys_to_pfn(DOVE_PCIE0_IO_PHYS_BASE),
- .length = DOVE_PCIE0_IO_SIZE,
- .type = MT_DEVICE,
- }, {
- .virtual = DOVE_PCIE1_IO_VIRT_BASE,
- .pfn = __phys_to_pfn(DOVE_PCIE1_IO_PHYS_BASE),
- .length = DOVE_PCIE1_IO_SIZE,
- .type = MT_DEVICE,
},
};
****************************************************************************/
void __init dove_ge00_init(struct mv643xx_eth_platform_data *eth_data)
{
- orion_ge00_init(eth_data,
- DOVE_GE00_PHYS_BASE, IRQ_DOVE_GE00_SUM, 0);
+ orion_ge00_init(eth_data, DOVE_GE00_PHYS_BASE,
+ IRQ_DOVE_GE00_SUM, IRQ_DOVE_GE00_ERR);
}
/*****************************************************************************
#include <linux/io.h>
#include <linux/mtd/physmap.h>
#include <linux/clk.h>
+#include <linux/platform_data/clk-integrator.h>
#include <video/vga.h>
#include <mach/hardware.h>
#include <asm/mach/arch.h>
#include <asm/mach/irq.h>
#include <asm/mach/map.h>
+ #include <asm/mach/pci.h>
#include <asm/mach/time.h>
#include <plat/fpga-irq.h>
* e8000000 40000000 PCI memory PHYS_PCI_MEM_BASE (max 512M)
* ec000000 61000000 PCI config space PHYS_PCI_CONFIG_BASE (max 16M)
* ed000000 62000000 PCI V3 regs PHYS_PCI_V3_BASE (max 64k)
- * ee000000 60000000 PCI IO PHYS_PCI_IO_BASE (max 16M)
+ * fee00000 60000000 PCI IO PHYS_PCI_IO_BASE (max 16M)
* ef000000 Cache flush
* f1000000 10000000 Core module registers
* f1100000 11000000 System controller registers
.pfn = __phys_to_pfn(PHYS_PCI_V3_BASE),
.length = SZ_64K,
.type = MT_DEVICE
- }, {
- .virtual = PCI_IO_VADDR,
- .pfn = __phys_to_pfn(PHYS_PCI_IO_BASE),
- .length = SZ_64K,
- .type = MT_DEVICE
}
};
{
iotable_init(ap_io_desc, ARRAY_SIZE(ap_io_desc));
vga_base = PCI_MEMORY_VADDR;
+ pci_map_io_early(__phys_to_pfn(PHYS_PCI_IO_BASE));
}
#define INTEGRATOR_SC_VALID_INT 0x003fffff
fpga_irq_init(VA_IC_BASE, "SC", IRQ_PIC_START,
-1, INTEGRATOR_SC_VALID_INT, NULL);
+ integrator_clk_init(false);
}
#ifdef CONFIG_PM
0xffffU);
}
+void __init ap_init_early(void)
+{
+}
+
/*
* Set up timer(s).
*/
.reserve = integrator_reserve,
.map_io = ap_map_io,
.nr_irqs = NR_IRQS_INTEGRATOR_AP,
- .init_early = integrator_init_early,
+ .init_early = ap_init_early,
.init_irq = ap_init_irq,
.handle_irq = fpga_handle_irq,
.timer = &ap_timer,
#include <linux/dma-mapping.h>
#include <linux/clk-provider.h>
#include <linux/spinlock.h>
+#include <linux/mv643xx_i2c.h>
#include <net/dsa.h>
#include <asm/page.h>
#include <asm/timex.h>
****************************************************************************/
static struct map_desc kirkwood_io_desc[] __initdata = {
{
- .virtual = KIRKWOOD_PCIE_IO_VIRT_BASE,
- .pfn = __phys_to_pfn(KIRKWOOD_PCIE_IO_PHYS_BASE),
- .length = KIRKWOOD_PCIE_IO_SIZE,
- .type = MT_DEVICE,
- }, {
- .virtual = KIRKWOOD_PCIE1_IO_VIRT_BASE,
- .pfn = __phys_to_pfn(KIRKWOOD_PCIE1_IO_PHYS_BASE),
- .length = KIRKWOOD_PCIE1_IO_SIZE,
- .type = MT_DEVICE,
- }, {
.virtual = KIRKWOOD_REGS_VIRT_BASE,
.pfn = __phys_to_pfn(KIRKWOOD_REGS_PHYS_BASE),
.length = KIRKWOOD_REGS_SIZE,
* CLK tree
****************************************************************************/
+static void enable_sata0(void)
+{
+ /* Enable PLL and IVREF */
+ writel(readl(SATA0_PHY_MODE_2) | 0xf, SATA0_PHY_MODE_2);
+ /* Enable PHY */
+ writel(readl(SATA0_IF_CTRL) & ~0x200, SATA0_IF_CTRL);
+}
+
static void disable_sata0(void)
{
/* Disable PLL and IVREF */
writel(readl(SATA0_IF_CTRL) | 0x200, SATA0_IF_CTRL);
}
+static void enable_sata1(void)
+{
+ /* Enable PLL and IVREF */
+ writel(readl(SATA1_PHY_MODE_2) | 0xf, SATA1_PHY_MODE_2);
+ /* Enable PHY */
+ writel(readl(SATA1_IF_CTRL) & ~0x200, SATA1_IF_CTRL);
+}
+
static void disable_sata1(void)
{
/* Disable PLL and IVREF */
}
}
-/* An extended version of the gated clk. This calls fn() before
- * disabling the clock. We use this to turn off PHYs etc. */
+/* An extended version of the gated clk. This calls fn_en()/fn_dis
+ * before enabling/disabling the clock. We use this to turn on/off
+ * PHYs etc. */
struct clk_gate_fn {
struct clk_gate gate;
- void (*fn)(void);
+ void (*fn_en)(void);
+ void (*fn_dis)(void);
};
#define to_clk_gate_fn(_gate) container_of(_gate, struct clk_gate_fn, gate)
#define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw)
+static int clk_gate_fn_enable(struct clk_hw *hw)
+{
+ struct clk_gate *gate = to_clk_gate(hw);
+ struct clk_gate_fn *gate_fn = to_clk_gate_fn(gate);
+ int ret;
+
+ ret = clk_gate_ops.enable(hw);
+ if (!ret && gate_fn->fn_en)
+ gate_fn->fn_en();
+
+ return ret;
+}
+
static void clk_gate_fn_disable(struct clk_hw *hw)
{
struct clk_gate *gate = to_clk_gate(hw);
struct clk_gate_fn *gate_fn = to_clk_gate_fn(gate);
- if (gate_fn->fn)
- gate_fn->fn();
+ if (gate_fn->fn_dis)
+ gate_fn->fn_dis();
clk_gate_ops.disable(hw);
}
const char *parent_name, unsigned long flags,
void __iomem *reg, u8 bit_idx,
u8 clk_gate_flags, spinlock_t *lock,
- void (*fn)(void))
+ void (*fn_en)(void), void (*fn_dis)(void))
{
struct clk_gate_fn *gate_fn;
struct clk *clk;
gate_fn->gate.flags = clk_gate_flags;
gate_fn->gate.lock = lock;
gate_fn->gate.hw.init = &init;
- gate_fn->fn = fn;
+ gate_fn->fn_en = fn_en;
+ gate_fn->fn_dis = fn_dis;
- /* ops is the gate ops, but with our disable function */
- if (clk_gate_fn_ops.disable != clk_gate_fn_disable) {
+ /* ops is the gate ops, but with our enable/disable functions */
+ if (clk_gate_fn_ops.enable != clk_gate_fn_enable ||
+ clk_gate_fn_ops.disable != clk_gate_fn_disable) {
clk_gate_fn_ops = clk_gate_ops;
+ clk_gate_fn_ops.enable = clk_gate_fn_enable;
clk_gate_fn_ops.disable = clk_gate_fn_disable;
}
static struct clk __init *kirkwood_register_gate_fn(const char *name,
u8 bit_idx,
- void (*fn)(void))
+ void (*fn_en)(void),
+ void (*fn_dis)(void))
{
return clk_register_gate_fn(NULL, name, "tclk", 0,
(void __iomem *)CLOCK_GATING_CTRL,
- bit_idx, 0, &gating_lock, fn);
+ bit_idx, 0, &gating_lock, fn_en, fn_dis);
}
static struct clk *ge0, *ge1;
ge0 = kirkwood_register_gate("ge0", CGC_BIT_GE0);
ge1 = kirkwood_register_gate("ge1", CGC_BIT_GE1);
sata0 = kirkwood_register_gate_fn("sata0", CGC_BIT_SATA0,
- disable_sata0);
+ enable_sata0, disable_sata0);
sata1 = kirkwood_register_gate_fn("sata1", CGC_BIT_SATA1,
- disable_sata1);
+ enable_sata1, disable_sata1);
usb0 = kirkwood_register_gate("usb0", CGC_BIT_USB0);
sdio = kirkwood_register_gate("sdio", CGC_BIT_SDIO);
crypto = kirkwood_register_gate("crypto", CGC_BIT_CRYPTO);
xor0 = kirkwood_register_gate("xor0", CGC_BIT_XOR0);
xor1 = kirkwood_register_gate("xor1", CGC_BIT_XOR1);
pex0 = kirkwood_register_gate_fn("pex0", CGC_BIT_PEX0,
- disable_pcie0);
+ NULL, disable_pcie0);
pex1 = kirkwood_register_gate_fn("pex1", CGC_BIT_PEX1,
- disable_pcie1);
+ NULL, disable_pcie1);
audio = kirkwood_register_gate("audio", CGC_BIT_AUDIO);
kirkwood_register_gate("tdm", CGC_BIT_TDM);
kirkwood_register_gate("tsu", CGC_BIT_TSU);
orion_clkdev_add("0", "pcie", pex0);
orion_clkdev_add("1", "pcie", pex1);
orion_clkdev_add(NULL, "kirkwood-i2s", audio);
+ orion_clkdev_add(NULL, MV64XXX_I2C_CTLR_NAME ".0", runit);
+
+ /* Marvell says runit is used by SPI, UART, NAND, TWSI, ...,
+ * so should never be gated.
+ */
+ clk_prepare_enable(runit);
}
/*****************************************************************************
* 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
#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)
bool link_up;
- char io_space_name[16];
char mem_space_name[16];
char prefetch_space_name[20];
- struct resource res[3];
+ struct resource res[2];
};
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)
{
pp = tegra_pcie.port + nr;
pp->root_bus_nr = sys->busnr;
- /*
- * IORESOURCE_IO
- */
- snprintf(pp->io_space_name, sizeof(pp->io_space_name),
- "PCIe %d I/O", pp->index);
- pp->io_space_name[sizeof(pp->io_space_name) - 1] = 0;
- pp->res[0].name = pp->io_space_name;
- if (pp->index == 0) {
- pp->res[0].start = PCIBIOS_MIN_IO;
- 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].flags = IORESOURCE_IO;
- if (request_resource(&ioport_resource, &pp->res[0]))
- panic("Request PCIe IO resource failed\n");
- pci_add_resource_offset(&sys->resources, &pp->res[0], sys->io_offset);
+ pci_ioremap_io(nr * SZ_64K, TEGRA_PCIE_IO_BASE);
/*
* IORESOURCE_MEM
snprintf(pp->mem_space_name, sizeof(pp->mem_space_name),
"PCIe %d MEM", pp->index);
pp->mem_space_name[sizeof(pp->mem_space_name) - 1] = 0;
- pp->res[1].name = pp->mem_space_name;
+ pp->res[0].name = pp->mem_space_name;
if (pp->index == 0) {
- pp->res[1].start = MEM_BASE_0;
- pp->res[1].end = pp->res[1].start + MEM_SIZE_0 - 1;
+ pp->res[0].start = MEM_BASE_0;
+ pp->res[0].end = pp->res[0].start + MEM_SIZE_0 - 1;
} else {
- pp->res[1].start = MEM_BASE_1;
- pp->res[1].end = pp->res[1].start + MEM_SIZE_1 - 1;
+ pp->res[0].start = MEM_BASE_1;
+ pp->res[0].end = pp->res[0].start + MEM_SIZE_1 - 1;
}
- pp->res[1].flags = IORESOURCE_MEM;
- if (request_resource(&iomem_resource, &pp->res[1]))
+ pp->res[0].flags = IORESOURCE_MEM;
+ if (request_resource(&iomem_resource, &pp->res[0]))
panic("Request PCIe Memory resource failed\n");
- pci_add_resource_offset(&sys->resources, &pp->res[1], sys->mem_offset);
+ pci_add_resource_offset(&sys->resources, &pp->res[0], sys->mem_offset);
/*
* IORESOURCE_MEM | IORESOURCE_PREFETCH
snprintf(pp->prefetch_space_name, sizeof(pp->prefetch_space_name),
"PCIe %d PREFETCH MEM", pp->index);
pp->prefetch_space_name[sizeof(pp->prefetch_space_name) - 1] = 0;
- pp->res[2].name = pp->prefetch_space_name;
+ pp->res[1].name = pp->prefetch_space_name;
if (pp->index == 0) {
- pp->res[2].start = PREFETCH_MEM_BASE_0;
- pp->res[2].end = pp->res[2].start + PREFETCH_MEM_SIZE_0 - 1;
+ pp->res[1].start = PREFETCH_MEM_BASE_0;
+ pp->res[1].end = pp->res[1].start + PREFETCH_MEM_SIZE_0 - 1;
} else {
- pp->res[2].start = PREFETCH_MEM_BASE_1;
- pp->res[2].end = pp->res[2].start + PREFETCH_MEM_SIZE_1 - 1;
+ pp->res[1].start = PREFETCH_MEM_BASE_1;
+ pp->res[1].end = pp->res[1].start + PREFETCH_MEM_SIZE_1 - 1;
}
- pp->res[2].flags = IORESOURCE_MEM | IORESOURCE_PREFETCH;
- if (request_resource(&iomem_resource, &pp->res[2]))
+ pp->res[1].flags = IORESOURCE_MEM | IORESOURCE_PREFETCH;
+ if (request_resource(&iomem_resource, &pp->res[1]))
panic("Request PCIe Prefetch Memory resource failed\n");
- pci_add_resource_offset(&sys->resources, &pp->res[2], sys->mem_offset);
+ pci_add_resource_offset(&sys->resources, &pp->res[1], sys->mem_offset);
return 1;
}
/* Bar 2: downstream IO bar */
fpci_bar = ((__u32)0xfdfc << 16);
- size = MMIO_SIZE;
- axi_address = MMIO_BASE;
+ size = SZ_128K;
+ 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);
tegra_pcie_xclk_clamp(false);
- clk_enable(tegra_pcie.afi_clk);
- clk_enable(tegra_pcie.pex_clk);
- return clk_enable(tegra_pcie.pll_e);
+ clk_prepare_enable(tegra_pcie.afi_clk);
+ clk_prepare_enable(tegra_pcie.pex_clk);
+ return clk_prepare_enable(tegra_pcie.pll_e);
}
static int tegra_pcie_clocks_get(void)
static int __init tegra_pcie_get_resources(void)
{
- struct resource *res_mmio = &tegra_pcie.res_mmio;
int err;
err = tegra_pcie_clocks_get();
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:
#include <linux/mm.h>
#include <linux/vmalloc.h>
#include <linux/io.h>
+#include <linux/sizes.h>
#include <asm/cp15.h>
#include <asm/cputype.h>
#include <asm/mmu_context.h>
#include <asm/pgalloc.h>
#include <asm/tlbflush.h>
-#include <asm/sizes.h>
#include <asm/system_info.h>
#include <asm/mach/map.h>
+ #include <asm/mach/pci.h>
#include "mm.h"
int ioremap_page(unsigned long virt, unsigned long phys,
arch_iounmap(io_addr);
}
EXPORT_SYMBOL(__arm_iounmap);
+
+ #ifdef CONFIG_PCI
+ int pci_ioremap_io(unsigned int offset, phys_addr_t phys_addr)
+ {
+ BUG_ON(offset + SZ_64K > IO_SPACE_LIMIT);
+
+ return ioremap_page_range(PCI_IO_VIRT_BASE + offset,
+ PCI_IO_VIRT_BASE + offset + SZ_64K,
+ phys_addr,
+ __pgprot(get_mem_type(MT_DEVICE)->prot_pte));
+ }
+ EXPORT_SYMBOL_GPL(pci_ioremap_io);
+ #endif
#include <linux/memblock.h>
#include <linux/fs.h>
#include <linux/vmalloc.h>
+#include <linux/sizes.h>
#include <asm/cp15.h>
#include <asm/cputype.h>
#include <asm/sections.h>
#include <asm/cachetype.h>
#include <asm/setup.h>
-#include <asm/sizes.h>
#include <asm/smp_plat.h>
#include <asm/tlb.h>
#include <asm/highmem.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
+ #include <asm/mach/pci.h>
#include "mm.h"
.prot_l1 = PMD_TYPE_TABLE,
.prot_sect = PROT_SECT_DEVICE | PMD_SECT_WB,
.domain = DOMAIN_IO,
- },
+ },
[MT_DEVICE_WC] = { /* ioremap_wc */
.prot_pte = PROT_PTE_DEVICE | L_PTE_MT_DEV_WC,
.prot_l1 = PMD_TYPE_TABLE,
cp = &cache_policies[cachepolicy];
vecs_pgprot = kern_pgprot = user_pgprot = cp->pte;
- /*
- * Only use write-through for non-SMP systems
- */
- if (!is_smp() && cpu_arch >= CPU_ARCH_ARMv5 && cachepolicy > CPOLICY_WRITETHROUGH)
- vecs_pgprot = cache_policies[CPOLICY_WRITETHROUGH].pte;
-
/*
* Enable CPU-specific coherency if supported.
* (Only available on XSC3 at the moment.)
create_mapping(md);
vm->addr = (void *)(md->virtual & PAGE_MASK);
vm->size = PAGE_ALIGN(md->length + (md->virtual & ~PAGE_MASK));
- vm->phys_addr = __pfn_to_phys(md->pfn);
- vm->flags = VM_IOREMAP | VM_ARM_STATIC_MAPPING;
+ vm->phys_addr = __pfn_to_phys(md->pfn);
+ vm->flags = VM_IOREMAP | VM_ARM_STATIC_MAPPING;
vm->flags |= VM_ARM_MTYPE(md->type);
vm->caller = iotable_init;
vm_area_add_early(vm++);
}
}
+ void __init vm_reserve_area_early(unsigned long addr, unsigned long size,
+ void *caller)
+ {
+ struct vm_struct *vm;
+
+ vm = early_alloc_aligned(sizeof(*vm), __alignof__(*vm));
+ vm->addr = (void *)addr;
+ vm->size = size;
+ vm->flags = VM_IOREMAP | VM_ARM_STATIC_MAPPING;
+ vm->caller = caller;
+ vm_area_add_early(vm);
+ }
+
#ifndef CONFIG_ARM_LPAE
/*
static void __init pmd_empty_section_gap(unsigned long addr)
{
- struct vm_struct *vm;
-
- vm = early_alloc_aligned(sizeof(*vm), __alignof__(*vm));
- vm->addr = (void *)addr;
- vm->size = SECTION_SIZE;
- vm->flags = VM_IOREMAP | VM_ARM_STATIC_MAPPING;
- vm->caller = pmd_empty_section_gap;
- vm_area_add_early(vm);
+ vm_reserve_area_early(addr, SECTION_SIZE, pmd_empty_section_gap);
}
static void __init fill_pmd_gaps(void)
#define fill_pmd_gaps() do { } while (0)
#endif
+ #if defined(CONFIG_PCI) && !defined(CONFIG_NEED_MACH_IO_H)
+ static void __init pci_reserve_io(void)
+ {
+ struct vm_struct *vm;
+ unsigned long addr;
+
+ /* we're still single threaded hence no lock needed here */
+ for (vm = vmlist; vm; vm = vm->next) {
+ if (!(vm->flags & VM_ARM_STATIC_MAPPING))
+ continue;
+ addr = (unsigned long)vm->addr;
+ addr &= ~(SZ_2M - 1);
+ if (addr == PCI_IO_VIRT_BASE)
+ return;
+
+ }
+ vm_reserve_area_early(PCI_IO_VIRT_BASE, SZ_2M, pci_reserve_io);
+ }
+ #else
+ #define pci_reserve_io() do { } while (0)
+ #endif
+
static void * __initdata vmalloc_min =
(void *)(VMALLOC_END - (240 << 20) - VMALLOC_OFFSET);
mdesc->map_io();
fill_pmd_gaps();
+ /* Reserve fixed i/o space in VMALLOC region */
+ pci_reserve_io();
+
/*
* Finally flush the caches and tlb to ensure that we're in a
* consistent state wrt the writebuffer. This also ensures that