summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2013-04-09 15:27:52 +0200
committerArnd Bergmann <arnd@arndb.de>2013-04-09 15:27:52 +0200
commit8024206dbf4e0701f0cdf259a122ea23db3a7a16 (patch)
tree11d2f30d0c9209036613ec8f78d682ae31c89315 /arch/arm/mach-tegra
parent5be8f6368800d9e3e570373d2aaff8a48be36574 (diff)
parent6affb4826405dc1f53bae0e5c302a18f734a44ca (diff)
downloadlinux-3.10-8024206dbf4e0701f0cdf259a122ea23db3a7a16.tar.gz
linux-3.10-8024206dbf4e0701f0cdf259a122ea23db3a7a16.tar.bz2
linux-3.10-8024206dbf4e0701f0cdf259a122ea23db3a7a16.zip
Merge tag 'tegra-for-3.10-cleanup' of git://git.kernel.org/pub/scm/linux/kernel/git/swarren/linux-tegra into next/cleanup
From Stephen Warren <swarren@wwwdotorg.org>: ARM: tegra: cleanup This branch includes various cleanup of the core Tegra support. * Unification of the separate board-dt-tegra*.c files into a single tegra.c, now that everything is DT-driven and basically identical. * Use of_clk_get() in the Tegra clocksource driver so that clocks are described in DT rather than hard-coding clock names. * Some cleanup of the PMC-related code, with the aim that the PMC "driver" contains more of the code that touches PMC registers, rather than spreading PMC register accesses through other files. * Conversion of the "PMC" driver to acquire resources describe in device tree rather than hard-coding them. * Use of common code for the CPU sleep TLB invalidation. This branch is based on the previous fixes pull request. * tag 'tegra-for-3.10-cleanup' of git://git.kernel.org/pub/scm/linux/kernel/git/swarren/linux-tegra: ARM: tegra: use setup_mm_for_reboot rather than explicit pgd switch ARM: tegra: replace the CPU power on function with PMC call ARM: tegra: pmc: add power on function for secondary CPUs ARM: tegra: pmc: convert PMC driver to support DT only ARM: tegra: fix the PMC compatible string in DT ARM: tegra: pmc: add specific compatible DT string for Tegra30 and Tegra114 ARM: tegra: refactor tegra{20,30}_boot_secondary clocksource: tegra: move to of_clk_get ARM: tegra: Unify Device tree board files ARM: tegra: Rename board-dt-tegra20.c to tegra.c ARM: tegra: Unify tegra{20,30,114}_init_early() Conflicts: drivers/clocksource/tegra20_timer.c Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'arch/arm/mach-tegra')
-rw-r--r--arch/arm/mach-tegra/Makefile4
-rw-r--r--arch/arm/mach-tegra/board-dt-tegra114.c46
-rw-r--r--arch/arm/mach-tegra/board-dt-tegra30.c60
-rw-r--r--arch/arm/mach-tegra/board.h4
-rw-r--r--arch/arm/mach-tegra/common.c26
-rw-r--r--arch/arm/mach-tegra/hotplug.c23
-rw-r--r--arch/arm/mach-tegra/platsmp.c110
-rw-r--r--arch/arm/mach-tegra/pm.c7
-rw-r--r--arch/arm/mach-tegra/pmc.c152
-rw-r--r--arch/arm/mach-tegra/pmc.h4
-rw-r--r--arch/arm/mach-tegra/sleep.h10
-rw-r--r--arch/arm/mach-tegra/tegra.c (renamed from arch/arm/mach-tegra/board-dt-tegra20.c)16
12 files changed, 199 insertions, 263 deletions
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
index f6b46ae2b7f..92703f955a3 100644
--- a/arch/arm/mach-tegra/Makefile
+++ b/arch/arm/mach-tegra/Makefile
@@ -10,6 +10,7 @@ obj-y += pm.o
obj-y += reset.o
obj-y += reset-handler.o
obj-y += sleep.o
+obj-y += tegra.o
obj-$(CONFIG_CPU_IDLE) += cpuidle.o
obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20_speedo.o
obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_emc.o
@@ -27,9 +28,6 @@ obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
obj-$(CONFIG_CPU_FREQ) += cpu-tegra.o
obj-$(CONFIG_TEGRA_PCI) += pcie.o
-obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += board-dt-tegra20.o
-obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += board-dt-tegra30.o
-obj-$(CONFIG_ARCH_TEGRA_114_SOC) += board-dt-tegra114.o
ifeq ($(CONFIG_CPU_IDLE),y)
obj-$(CONFIG_ARCH_TEGRA_114_SOC) += cpuidle-tegra114.o
endif
diff --git a/arch/arm/mach-tegra/board-dt-tegra114.c b/arch/arm/mach-tegra/board-dt-tegra114.c
deleted file mode 100644
index 085d63637b6..00000000000
--- a/arch/arm/mach-tegra/board-dt-tegra114.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * NVIDIA Tegra114 device tree board support
- *
- * Copyright (C) 2013 NVIDIA Corporation
- *
- * 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.
- *
- */
-
-#include <linux/of.h>
-#include <linux/of_platform.h>
-#include <linux/clocksource.h>
-
-#include <asm/mach/arch.h>
-
-#include "board.h"
-#include "common.h"
-
-static void __init tegra114_dt_init(void)
-{
- of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
-}
-
-static const char * const tegra114_dt_board_compat[] = {
- "nvidia,tegra114",
- NULL,
-};
-
-DT_MACHINE_START(TEGRA114_DT, "NVIDIA Tegra114 (Flattened Device Tree)")
- .smp = smp_ops(tegra_smp_ops),
- .map_io = tegra_map_common_io,
- .init_early = tegra114_init_early,
- .init_irq = tegra_dt_init_irq,
- .init_time = clocksource_of_init,
- .init_machine = tegra114_dt_init,
- .init_late = tegra_init_late,
- .restart = tegra_assert_system_reset,
- .dt_compat = tegra114_dt_board_compat,
-MACHINE_END
diff --git a/arch/arm/mach-tegra/board-dt-tegra30.c b/arch/arm/mach-tegra/board-dt-tegra30.c
deleted file mode 100644
index bf68567e549..00000000000
--- a/arch/arm/mach-tegra/board-dt-tegra30.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * arch/arm/mach-tegra/board-dt-tegra30.c
- *
- * NVIDIA Tegra30 device tree board support
- *
- * Copyright (C) 2011 NVIDIA Corporation
- *
- * Derived from:
- *
- * arch/arm/mach-tegra/board-dt-tegra20.c
- *
- * Copyright (C) 2010 Secret Lab Technologies, Ltd.
- * Copyright (C) 2010 Google, Inc.
- *
- * 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.
- *
- */
-
-#include <linux/clocksource.h>
-#include <linux/kernel.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/of_fdt.h>
-#include <linux/of_irq.h>
-#include <linux/of_platform.h>
-
-#include <asm/mach/arch.h>
-
-#include "board.h"
-#include "common.h"
-#include "iomap.h"
-
-static void __init tegra30_dt_init(void)
-{
- of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
-}
-
-static const char *tegra30_dt_board_compat[] = {
- "nvidia,tegra30",
- NULL
-};
-
-DT_MACHINE_START(TEGRA30_DT, "NVIDIA Tegra30 (Flattened Device Tree)")
- .smp = smp_ops(tegra_smp_ops),
- .map_io = tegra_map_common_io,
- .init_early = tegra30_init_early,
- .init_irq = tegra_dt_init_irq,
- .init_time = clocksource_of_init,
- .init_machine = tegra30_dt_init,
- .init_late = tegra_init_late,
- .restart = tegra_assert_system_reset,
- .dt_compat = tegra30_dt_board_compat,
-MACHINE_END
diff --git a/arch/arm/mach-tegra/board.h b/arch/arm/mach-tegra/board.h
index 86851c81a35..60431de585c 100644
--- a/arch/arm/mach-tegra/board.h
+++ b/arch/arm/mach-tegra/board.h
@@ -26,9 +26,7 @@
void tegra_assert_system_reset(char mode, const char *cmd);
-void __init tegra20_init_early(void);
-void __init tegra30_init_early(void);
-void __init tegra114_init_early(void);
+void __init tegra_init_early(void);
void __init tegra_map_common_io(void);
void __init tegra_init_irq(void);
void __init tegra_dt_init_irq(void);
diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c
index 5449a3f2977..f0315c95c76 100644
--- a/arch/arm/mach-tegra/common.c
+++ b/arch/arm/mach-tegra/common.c
@@ -94,7 +94,7 @@ static void __init tegra_init_cache(void)
}
-static void __init tegra_init_early(void)
+void __init tegra_init_early(void)
{
tegra_cpu_reset_handler_init();
tegra_apb_io_init();
@@ -102,31 +102,9 @@ static void __init tegra_init_early(void)
tegra_init_cache();
tegra_pmc_init();
tegra_powergate_init();
+ tegra_hotplug_init();
}
-#ifdef CONFIG_ARCH_TEGRA_2x_SOC
-void __init tegra20_init_early(void)
-{
- tegra_init_early();
- tegra20_hotplug_init();
-}
-#endif
-
-#ifdef CONFIG_ARCH_TEGRA_3x_SOC
-void __init tegra30_init_early(void)
-{
- tegra_init_early();
- tegra30_hotplug_init();
-}
-#endif
-
-#ifdef CONFIG_ARCH_TEGRA_114_SOC
-void __init tegra114_init_early(void)
-{
- tegra_init_early();
-}
-#endif
-
void __init tegra_init_late(void)
{
tegra_powergate_debugfs_init();
diff --git a/arch/arm/mach-tegra/hotplug.c b/arch/arm/mach-tegra/hotplug.c
index a599f6e36de..8da9f78475d 100644
--- a/arch/arm/mach-tegra/hotplug.c
+++ b/arch/arm/mach-tegra/hotplug.c
@@ -1,8 +1,7 @@
/*
- *
* Copyright (C) 2002 ARM Ltd.
* All Rights Reserved
- * Copyright (c) 2010, 2012 NVIDIA Corporation. All rights reserved.
+ * Copyright (c) 2010, 2012-2013, NVIDIA Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -15,6 +14,7 @@
#include <asm/cacheflush.h>
#include <asm/smp_plat.h>
+#include "fuse.h"
#include "sleep.h"
static void (*tegra_hotplug_shutdown)(void);
@@ -56,18 +56,13 @@ int tegra_cpu_disable(unsigned int cpu)
return cpu == 0 ? -EPERM : 0;
}
-#ifdef CONFIG_ARCH_TEGRA_2x_SOC
-extern void tegra20_hotplug_shutdown(void);
-void __init tegra20_hotplug_init(void)
+void __init tegra_hotplug_init(void)
{
- tegra_hotplug_shutdown = tegra20_hotplug_shutdown;
-}
-#endif
+ if (!IS_ENABLED(CONFIG_HOTPLUG_CPU))
+ return;
-#ifdef CONFIG_ARCH_TEGRA_3x_SOC
-extern void tegra30_hotplug_shutdown(void);
-void __init tegra30_hotplug_init(void)
-{
- tegra_hotplug_shutdown = tegra30_hotplug_shutdown;
+ if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && tegra_chip_id == TEGRA20)
+ tegra_hotplug_shutdown = tegra20_hotplug_shutdown;
+ if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) && tegra_chip_id == TEGRA30)
+ tegra_hotplug_shutdown = tegra30_hotplug_shutdown;
}
-#endif
diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c
index fb86a00ce25..c31db797e19 100644
--- a/arch/arm/mach-tegra/platsmp.c
+++ b/arch/arm/mach-tegra/platsmp.c
@@ -25,46 +25,58 @@
#include <asm/smp_scu.h>
#include <asm/smp_plat.h>
-#include <mach/powergate.h>
-
#include "fuse.h"
#include "flowctrl.h"
#include "reset.h"
+#include "pmc.h"
#include "common.h"
#include "iomap.h"
-extern void tegra_secondary_startup(void);
-
static cpumask_t tegra_cpu_init_mask;
-#define EVP_CPU_RESET_VECTOR \
- (IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE) + 0x100)
-
static void __cpuinit tegra_secondary_init(unsigned int cpu)
{
cpumask_set_cpu(cpu, &tegra_cpu_init_mask);
}
-static int tegra20_power_up_cpu(unsigned int cpu)
+
+static int tegra20_boot_secondary(unsigned int cpu, struct task_struct *idle)
{
- /* Enable the CPU clock. */
- tegra_enable_cpu_clock(cpu);
+ cpu = cpu_logical_map(cpu);
- /* Clear flow controller CSR. */
- flowctrl_write_cpu_csr(cpu, 0);
+ /*
+ * Force the CPU into reset. The CPU must remain in reset when
+ * the flow controller state is cleared (which will cause the
+ * flow controller to stop driving reset if the CPU has been
+ * power-gated via the flow controller). This will have no
+ * effect on first boot of the CPU since it should already be
+ * in reset.
+ */
+ tegra_put_cpu_in_reset(cpu);
+ /*
+ * Unhalt the CPU. If the flow controller was used to
+ * power-gate the CPU this will cause the flow controller to
+ * stop driving reset. The CPU will remain in reset because the
+ * clock and reset block is now driving reset.
+ */
+ flowctrl_write_cpu_halt(cpu, 0);
+
+ tegra_enable_cpu_clock(cpu);
+ flowctrl_write_cpu_csr(cpu, 0); /* Clear flow controller CSR. */
+ tegra_cpu_out_of_reset(cpu);
return 0;
}
-static int tegra30_power_up_cpu(unsigned int cpu)
+static int tegra30_boot_secondary(unsigned int cpu, struct task_struct *idle)
{
- int ret, pwrgateid;
+ int ret;
unsigned long timeout;
- pwrgateid = tegra_cpu_powergate_id(cpu);
- if (pwrgateid < 0)
- return pwrgateid;
+ cpu = cpu_logical_map(cpu);
+ tegra_put_cpu_in_reset(cpu);
+ flowctrl_write_cpu_halt(cpu, 0);
/*
* The power up sequence of cold boot CPU and warm boot CPU
@@ -77,13 +89,13 @@ static int tegra30_power_up_cpu(unsigned int cpu)
* the IO clamps.
* For cold boot CPU, do not wait. After the cold boot CPU be
* booted, it will run to tegra_secondary_init() and set
- * tegra_cpu_init_mask which influences what tegra30_power_up_cpu()
+ * tegra_cpu_init_mask which influences what tegra30_boot_secondary()
* next time around.
*/
if (cpumask_test_cpu(cpu, &tegra_cpu_init_mask)) {
timeout = jiffies + msecs_to_jiffies(50);
do {
- if (tegra_powergate_is_powered(pwrgateid))
+ if (tegra_pmc_cpu_is_powered(cpu))
goto remove_clamps;
udelay(10);
} while (time_before(jiffies, timeout));
@@ -95,14 +107,14 @@ static int tegra30_power_up_cpu(unsigned int cpu)
* be un-gated by un-toggling the power gate register
* manually.
*/
- if (!tegra_powergate_is_powered(pwrgateid)) {
- ret = tegra_powergate_power_on(pwrgateid);
+ if (!tegra_pmc_cpu_is_powered(cpu)) {
+ ret = tegra_pmc_cpu_power_on(cpu);
if (ret)
return ret;
/* Wait for the power to come up. */
timeout = jiffies + msecs_to_jiffies(100);
- while (tegra_powergate_is_powered(pwrgateid)) {
+ while (tegra_pmc_cpu_is_powered(cpu)) {
if (time_after(jiffies, timeout))
return -ETIMEDOUT;
udelay(10);
@@ -115,60 +127,26 @@ remove_clamps:
udelay(10);
/* Remove I/O clamps. */
- ret = tegra_powergate_remove_clamping(pwrgateid);
+ ret = tegra_pmc_cpu_remove_clamping(cpu);
if (ret)
return ret;
udelay(10);
- /* Clear flow controller CSR. */
- flowctrl_write_cpu_csr(cpu, 0);
-
+ flowctrl_write_cpu_csr(cpu, 0); /* Clear flow controller CSR. */
+ tegra_cpu_out_of_reset(cpu);
return 0;
}
-static int __cpuinit tegra_boot_secondary(unsigned int cpu, struct task_struct *idle)
+static int __cpuinit tegra_boot_secondary(unsigned int cpu,
+ struct task_struct *idle)
{
- int status;
-
- cpu = cpu_logical_map(cpu);
-
- /*
- * Force the CPU into reset. The CPU must remain in reset when the
- * flow controller state is cleared (which will cause the flow
- * controller to stop driving reset if the CPU has been power-gated
- * via the flow controller). This will have no effect on first boot
- * of the CPU since it should already be in reset.
- */
- tegra_put_cpu_in_reset(cpu);
+ if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && tegra_chip_id == TEGRA20)
+ return tegra20_boot_secondary(cpu, idle);
+ if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) && tegra_chip_id == TEGRA30)
+ return tegra30_boot_secondary(cpu, idle);
- /*
- * Unhalt the CPU. If the flow controller was used to power-gate the
- * CPU this will cause the flow controller to stop driving reset.
- * The CPU will remain in reset because the clock and reset block
- * is now driving reset.
- */
- flowctrl_write_cpu_halt(cpu, 0);
-
- switch (tegra_chip_id) {
- case TEGRA20:
- status = tegra20_power_up_cpu(cpu);
- break;
- case TEGRA30:
- status = tegra30_power_up_cpu(cpu);
- break;
- default:
- status = -EINVAL;
- break;
- }
-
- if (status)
- goto done;
-
- /* Take the CPU out of reset. */
- tegra_cpu_out_of_reset(cpu);
-done:
- return status;
+ return -EINVAL;
}
static void __init tegra_smp_prepare_cpus(unsigned int max_cpus)
diff --git a/arch/arm/mach-tegra/pm.c b/arch/arm/mach-tegra/pm.c
index 0494f739c95..acacbe8d1af 100644
--- a/arch/arm/mach-tegra/pm.c
+++ b/arch/arm/mach-tegra/pm.c
@@ -164,12 +164,7 @@ bool tegra_set_cpu_in_lp2(int phy_cpu_id)
static int tegra_sleep_cpu(unsigned long v2p)
{
- /* Switch to the identity mapping. */
- cpu_switch_mm(idmap_pgd, &init_mm);
-
- /* Flush the TLB. */
- local_flush_tlb_all();
-
+ setup_mm_for_reboot();
tegra_sleep_cpu_finish(v2p);
/* should never here */
diff --git a/arch/arm/mach-tegra/pmc.c b/arch/arm/mach-tegra/pmc.c
index d4fdb5fcec2..b30e921cc3a 100644
--- a/arch/arm/mach-tegra/pmc.c
+++ b/arch/arm/mach-tegra/pmc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved.
+ * Copyright (C) 2012,2013 NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -18,57 +18,149 @@
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/of.h>
+#include <linux/of_address.h>
-#include "iomap.h"
+#define PMC_CTRL 0x0
+#define PMC_CTRL_INTR_LOW (1 << 17)
+#define PMC_PWRGATE_TOGGLE 0x30
+#define PMC_PWRGATE_TOGGLE_START (1 << 8)
+#define PMC_REMOVE_CLAMPING 0x34
+#define PMC_PWRGATE_STATUS 0x38
-#define PMC_CTRL 0x0
-#define PMC_CTRL_INTR_LOW (1 << 17)
+#define TEGRA_POWERGATE_PCIE 3
+#define TEGRA_POWERGATE_VDEC 4
+#define TEGRA_POWERGATE_CPU1 9
+#define TEGRA_POWERGATE_CPU2 10
+#define TEGRA_POWERGATE_CPU3 11
+
+static u8 tegra_cpu_domains[] = {
+ 0xFF, /* not available for CPU0 */
+ TEGRA_POWERGATE_CPU1,
+ TEGRA_POWERGATE_CPU2,
+ TEGRA_POWERGATE_CPU3,
+};
+static DEFINE_SPINLOCK(tegra_powergate_lock);
+
+static void __iomem *tegra_pmc_base;
+static bool tegra_pmc_invert_interrupt;
static inline u32 tegra_pmc_readl(u32 reg)
{
- return readl(IO_ADDRESS(TEGRA_PMC_BASE + reg));
+ return readl(tegra_pmc_base + reg);
}
static inline void tegra_pmc_writel(u32 val, u32 reg)
{
- writel(val, IO_ADDRESS(TEGRA_PMC_BASE + reg));
+ writel(val, tegra_pmc_base + reg);
+}
+
+static int tegra_pmc_get_cpu_powerdomain_id(int cpuid)
+{
+ if (cpuid <= 0 || cpuid >= num_possible_cpus())
+ return -EINVAL;
+ return tegra_cpu_domains[cpuid];
+}
+
+static bool tegra_pmc_powergate_is_powered(int id)
+{
+ return (tegra_pmc_readl(PMC_PWRGATE_STATUS) >> id) & 1;
+}
+
+static int tegra_pmc_powergate_set(int id, bool new_state)
+{
+ bool old_state;
+ unsigned long flags;
+
+ spin_lock_irqsave(&tegra_powergate_lock, flags);
+
+ old_state = tegra_pmc_powergate_is_powered(id);
+ WARN_ON(old_state == new_state);
+
+ tegra_pmc_writel(PMC_PWRGATE_TOGGLE_START | id, PMC_PWRGATE_TOGGLE);
+
+ spin_unlock_irqrestore(&tegra_powergate_lock, flags);
+
+ return 0;
+}
+
+static int tegra_pmc_powergate_remove_clamping(int id)
+{
+ u32 mask;
+
+ /*
+ * Tegra has a bug where PCIE and VDE clamping masks are
+ * swapped relatively to the partition ids.
+ */
+ if (id == TEGRA_POWERGATE_VDEC)
+ mask = (1 << TEGRA_POWERGATE_PCIE);
+ else if (id == TEGRA_POWERGATE_PCIE)
+ mask = (1 << TEGRA_POWERGATE_VDEC);
+ else
+ mask = (1 << id);
+
+ tegra_pmc_writel(mask, PMC_REMOVE_CLAMPING);
+
+ return 0;
+}
+
+bool tegra_pmc_cpu_is_powered(int cpuid)
+{
+ int id;
+
+ id = tegra_pmc_get_cpu_powerdomain_id(cpuid);
+ if (id < 0)
+ return false;
+ return tegra_pmc_powergate_is_powered(id);
+}
+
+int tegra_pmc_cpu_power_on(int cpuid)
+{
+ int id;
+
+ id = tegra_pmc_get_cpu_powerdomain_id(cpuid);
+ if (id < 0)
+ return id;
+ return tegra_pmc_powergate_set(id, true);
+}
+
+int tegra_pmc_cpu_remove_clamping(int cpuid)
+{
+ int id;
+
+ id = tegra_pmc_get_cpu_powerdomain_id(cpuid);
+ if (id < 0)
+ return id;
+ return tegra_pmc_powergate_remove_clamping(id);
}
-#ifdef CONFIG_OF
static const struct of_device_id matches[] __initconst = {
+ { .compatible = "nvidia,tegra114-pmc" },
+ { .compatible = "nvidia,tegra30-pmc" },
{ .compatible = "nvidia,tegra20-pmc" },
{ }
};
-#endif
-void __init tegra_pmc_init(void)
+static void tegra_pmc_parse_dt(void)
{
- /*
- * For now, Harmony is the only board that uses the PMC, and it wants
- * the signal inverted. Seaboard would too if it used the PMC.
- * Hopefully by the time other boards want to use the PMC, everything
- * will be device-tree, or they also want it inverted.
- */
- bool invert_interrupt = true;
- u32 val;
+ struct device_node *np;
-#ifdef CONFIG_OF
- if (of_have_populated_dt()) {
- struct device_node *np;
+ np = of_find_matching_node(NULL, matches);
+ BUG_ON(!np);
- invert_interrupt = false;
+ tegra_pmc_base = of_iomap(np, 0);
+
+ tegra_pmc_invert_interrupt = of_property_read_bool(np,
+ "nvidia,invert-interrupt");
+}
+
+void __init tegra_pmc_init(void)
+{
+ u32 val;
- np = of_find_matching_node(NULL, matches);
- if (np) {
- if (of_find_property(np, "nvidia,invert-interrupt",
- NULL))
- invert_interrupt = true;
- }
- }
-#endif
+ tegra_pmc_parse_dt();
val = tegra_pmc_readl(PMC_CTRL);
- if (invert_interrupt)
+ if (tegra_pmc_invert_interrupt)
val |= PMC_CTRL_INTR_LOW;
else
val &= ~PMC_CTRL_INTR_LOW;
diff --git a/arch/arm/mach-tegra/pmc.h b/arch/arm/mach-tegra/pmc.h
index 8995ee4a876..7d44710368b 100644
--- a/arch/arm/mach-tegra/pmc.h
+++ b/arch/arm/mach-tegra/pmc.h
@@ -18,6 +18,10 @@
#ifndef __MACH_TEGRA_PMC_H
#define __MACH_TEGRA_PMC_H
+bool tegra_pmc_cpu_is_powered(int cpuid);
+int tegra_pmc_cpu_power_on(int cpuid);
+int tegra_pmc_cpu_remove_clamping(int cpuid);
+
void tegra_pmc_init(void);
#endif
diff --git a/arch/arm/mach-tegra/sleep.h b/arch/arm/mach-tegra/sleep.h
index 4ffae541726..970ebd5138b 100644
--- a/arch/arm/mach-tegra/sleep.h
+++ b/arch/arm/mach-tegra/sleep.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2012, NVIDIA Corporation. All rights reserved.
+ * Copyright (c) 2010-2013, NVIDIA Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -124,11 +124,11 @@ int tegra_sleep_cpu_finish(unsigned long);
void tegra_disable_clean_inv_dcache(void);
#ifdef CONFIG_HOTPLUG_CPU
-void tegra20_hotplug_init(void);
-void tegra30_hotplug_init(void);
+void tegra20_hotplug_shutdown(void);
+void tegra30_hotplug_shutdown(void);
+void tegra_hotplug_init(void);
#else
-static inline void tegra20_hotplug_init(void) {}
-static inline void tegra30_hotplug_init(void) {}
+static inline void tegra_hotplug_init(void) {}
#endif
void tegra20_cpu_shutdown(int cpu);
diff --git a/arch/arm/mach-tegra/board-dt-tegra20.c b/arch/arm/mach-tegra/tegra.c
index a0edf251028..27232c901a2 100644
--- a/arch/arm/mach-tegra/board-dt-tegra20.c
+++ b/arch/arm/mach-tegra/tegra.c
@@ -1,6 +1,7 @@
/*
- * nVidia Tegra device tree board support
+ * NVIDIA Tegra SoC device tree board support
*
+ * Copyright (C) 2011, 2013, NVIDIA Corporation
* Copyright (C) 2010 Secret Lab Technologies, Ltd.
* Copyright (C) 2010 Google, Inc.
*
@@ -111,7 +112,8 @@ static void __init harmony_init(void)
static void __init paz00_init(void)
{
- tegra_paz00_wifikill_init();
+ if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC))
+ tegra_paz00_wifikill_init();
}
static struct {
@@ -137,19 +139,21 @@ static void __init tegra_dt_init_late(void)
}
}
-static const char *tegra20_dt_board_compat[] = {
+static const char * const tegra_dt_board_compat[] = {
+ "nvidia,tegra114",
+ "nvidia,tegra30",
"nvidia,tegra20",
NULL
};
-DT_MACHINE_START(TEGRA_DT, "nVidia Tegra20 (Flattened Device Tree)")
+DT_MACHINE_START(TEGRA_DT, "NVIDIA Tegra SoC (Flattened Device Tree)")
.map_io = tegra_map_common_io,
.smp = smp_ops(tegra_smp_ops),
- .init_early = tegra20_init_early,
+ .init_early = tegra_init_early,
.init_irq = tegra_dt_init_irq,
.init_time = clocksource_of_init,
.init_machine = tegra_dt_init,
.init_late = tegra_dt_init_late,
.restart = tegra_assert_system_reset,
- .dt_compat = tegra20_dt_board_compat,
+ .dt_compat = tegra_dt_board_compat,
MACHINE_END