aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-tegra
diff options
context:
space:
mode:
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.c118
-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, 271 deletions
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
index 09b578f9eb84..c1970005f805 100644
--- a/arch/arm/mach-tegra/Makefile
+++ b/arch/arm/mach-tegra/Makefile
@@ -10,6 +10,7 @@ obj-y += pm.o
10obj-y += reset.o 10obj-y += reset.o
11obj-y += reset-handler.o 11obj-y += reset-handler.o
12obj-y += sleep.o 12obj-y += sleep.o
13obj-y += tegra.o
13obj-$(CONFIG_CPU_IDLE) += cpuidle.o 14obj-$(CONFIG_CPU_IDLE) += cpuidle.o
14obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20_speedo.o 15obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra20_speedo.o
15obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_emc.o 16obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_emc.o
@@ -26,9 +27,6 @@ obj-$(CONFIG_SMP) += platsmp.o headsmp.o
26obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o 27obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
27obj-$(CONFIG_TEGRA_PCI) += pcie.o 28obj-$(CONFIG_TEGRA_PCI) += pcie.o
28 29
29obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += board-dt-tegra20.o
30obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += board-dt-tegra30.o
31obj-$(CONFIG_ARCH_TEGRA_114_SOC) += board-dt-tegra114.o
32ifeq ($(CONFIG_CPU_IDLE),y) 30ifeq ($(CONFIG_CPU_IDLE),y)
33obj-$(CONFIG_ARCH_TEGRA_114_SOC) += cpuidle-tegra114.o 31obj-$(CONFIG_ARCH_TEGRA_114_SOC) += cpuidle-tegra114.o
34endif 32endif
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 085d63637b62..000000000000
--- a/arch/arm/mach-tegra/board-dt-tegra114.c
+++ /dev/null
@@ -1,46 +0,0 @@
1/*
2 * NVIDIA Tegra114 device tree board support
3 *
4 * Copyright (C) 2013 NVIDIA Corporation
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#include <linux/of.h>
18#include <linux/of_platform.h>
19#include <linux/clocksource.h>
20
21#include <asm/mach/arch.h>
22
23#include "board.h"
24#include "common.h"
25
26static void __init tegra114_dt_init(void)
27{
28 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
29}
30
31static const char * const tegra114_dt_board_compat[] = {
32 "nvidia,tegra114",
33 NULL,
34};
35
36DT_MACHINE_START(TEGRA114_DT, "NVIDIA Tegra114 (Flattened Device Tree)")
37 .smp = smp_ops(tegra_smp_ops),
38 .map_io = tegra_map_common_io,
39 .init_early = tegra114_init_early,
40 .init_irq = tegra_dt_init_irq,
41 .init_time = clocksource_of_init,
42 .init_machine = tegra114_dt_init,
43 .init_late = tegra_init_late,
44 .restart = tegra_assert_system_reset,
45 .dt_compat = tegra114_dt_board_compat,
46MACHINE_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 bf68567e549d..000000000000
--- a/arch/arm/mach-tegra/board-dt-tegra30.c
+++ /dev/null
@@ -1,60 +0,0 @@
1/*
2 * arch/arm/mach-tegra/board-dt-tegra30.c
3 *
4 * NVIDIA Tegra30 device tree board support
5 *
6 * Copyright (C) 2011 NVIDIA Corporation
7 *
8 * Derived from:
9 *
10 * arch/arm/mach-tegra/board-dt-tegra20.c
11 *
12 * Copyright (C) 2010 Secret Lab Technologies, Ltd.
13 * Copyright (C) 2010 Google, Inc.
14 *
15 * This software is licensed under the terms of the GNU General Public
16 * License version 2, as published by the Free Software Foundation, and
17 * may be copied, distributed, and modified under those terms.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 */
25
26#include <linux/clocksource.h>
27#include <linux/kernel.h>
28#include <linux/of.h>
29#include <linux/of_address.h>
30#include <linux/of_fdt.h>
31#include <linux/of_irq.h>
32#include <linux/of_platform.h>
33
34#include <asm/mach/arch.h>
35
36#include "board.h"
37#include "common.h"
38#include "iomap.h"
39
40static void __init tegra30_dt_init(void)
41{
42 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
43}
44
45static const char *tegra30_dt_board_compat[] = {
46 "nvidia,tegra30",
47 NULL
48};
49
50DT_MACHINE_START(TEGRA30_DT, "NVIDIA Tegra30 (Flattened Device Tree)")
51 .smp = smp_ops(tegra_smp_ops),
52 .map_io = tegra_map_common_io,
53 .init_early = tegra30_init_early,
54 .init_irq = tegra_dt_init_irq,
55 .init_time = clocksource_of_init,
56 .init_machine = tegra30_dt_init,
57 .init_late = tegra_init_late,
58 .restart = tegra_assert_system_reset,
59 .dt_compat = tegra30_dt_board_compat,
60MACHINE_END
diff --git a/arch/arm/mach-tegra/board.h b/arch/arm/mach-tegra/board.h
index 86851c81a350..60431de585ca 100644
--- a/arch/arm/mach-tegra/board.h
+++ b/arch/arm/mach-tegra/board.h
@@ -26,9 +26,7 @@
26 26
27void tegra_assert_system_reset(char mode, const char *cmd); 27void tegra_assert_system_reset(char mode, const char *cmd);
28 28
29void __init tegra20_init_early(void); 29void __init tegra_init_early(void);
30void __init tegra30_init_early(void);
31void __init tegra114_init_early(void);
32void __init tegra_map_common_io(void); 30void __init tegra_map_common_io(void);
33void __init tegra_init_irq(void); 31void __init tegra_init_irq(void);
34void __init tegra_dt_init_irq(void); 32void __init tegra_dt_init_irq(void);
diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c
index 5449a3f2977b..f0315c95c76d 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)
94 94
95} 95}
96 96
97static void __init tegra_init_early(void) 97void __init tegra_init_early(void)
98{ 98{
99 tegra_cpu_reset_handler_init(); 99 tegra_cpu_reset_handler_init();
100 tegra_apb_io_init(); 100 tegra_apb_io_init();
@@ -102,31 +102,9 @@ static void __init tegra_init_early(void)
102 tegra_init_cache(); 102 tegra_init_cache();
103 tegra_pmc_init(); 103 tegra_pmc_init();
104 tegra_powergate_init(); 104 tegra_powergate_init();
105 tegra_hotplug_init();
105} 106}
106 107
107#ifdef CONFIG_ARCH_TEGRA_2x_SOC
108void __init tegra20_init_early(void)
109{
110 tegra_init_early();
111 tegra20_hotplug_init();
112}
113#endif
114
115#ifdef CONFIG_ARCH_TEGRA_3x_SOC
116void __init tegra30_init_early(void)
117{
118 tegra_init_early();
119 tegra30_hotplug_init();
120}
121#endif
122
123#ifdef CONFIG_ARCH_TEGRA_114_SOC
124void __init tegra114_init_early(void)
125{
126 tegra_init_early();
127}
128#endif
129
130void __init tegra_init_late(void) 108void __init tegra_init_late(void)
131{ 109{
132 tegra_powergate_debugfs_init(); 110 tegra_powergate_debugfs_init();
diff --git a/arch/arm/mach-tegra/hotplug.c b/arch/arm/mach-tegra/hotplug.c
index a599f6e36dea..8da9f78475da 100644
--- a/arch/arm/mach-tegra/hotplug.c
+++ b/arch/arm/mach-tegra/hotplug.c
@@ -1,8 +1,7 @@
1/* 1/*
2 *
3 * Copyright (C) 2002 ARM Ltd. 2 * Copyright (C) 2002 ARM Ltd.
4 * All Rights Reserved 3 * All Rights Reserved
5 * Copyright (c) 2010, 2012 NVIDIA Corporation. All rights reserved. 4 * Copyright (c) 2010, 2012-2013, NVIDIA Corporation. All rights reserved.
6 * 5 *
7 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as 7 * it under the terms of the GNU General Public License version 2 as
@@ -15,6 +14,7 @@
15#include <asm/cacheflush.h> 14#include <asm/cacheflush.h>
16#include <asm/smp_plat.h> 15#include <asm/smp_plat.h>
17 16
17#include "fuse.h"
18#include "sleep.h" 18#include "sleep.h"
19 19
20static void (*tegra_hotplug_shutdown)(void); 20static void (*tegra_hotplug_shutdown)(void);
@@ -56,18 +56,13 @@ int tegra_cpu_disable(unsigned int cpu)
56 return cpu == 0 ? -EPERM : 0; 56 return cpu == 0 ? -EPERM : 0;
57} 57}
58 58
59#ifdef CONFIG_ARCH_TEGRA_2x_SOC 59void __init tegra_hotplug_init(void)
60extern void tegra20_hotplug_shutdown(void);
61void __init tegra20_hotplug_init(void)
62{ 60{
63 tegra_hotplug_shutdown = tegra20_hotplug_shutdown; 61 if (!IS_ENABLED(CONFIG_HOTPLUG_CPU))
64} 62 return;
65#endif
66 63
67#ifdef CONFIG_ARCH_TEGRA_3x_SOC 64 if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && tegra_chip_id == TEGRA20)
68extern void tegra30_hotplug_shutdown(void); 65 tegra_hotplug_shutdown = tegra20_hotplug_shutdown;
69void __init tegra30_hotplug_init(void) 66 if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) && tegra_chip_id == TEGRA30)
70{ 67 tegra_hotplug_shutdown = tegra30_hotplug_shutdown;
71 tegra_hotplug_shutdown = tegra30_hotplug_shutdown;
72} 68}
73#endif
diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c
index e78d52d83acd..c31db797e199 100644
--- a/arch/arm/mach-tegra/platsmp.c
+++ b/arch/arm/mach-tegra/platsmp.c
@@ -18,7 +18,6 @@
18#include <linux/jiffies.h> 18#include <linux/jiffies.h>
19#include <linux/smp.h> 19#include <linux/smp.h>
20#include <linux/io.h> 20#include <linux/io.h>
21#include <linux/irqchip/arm-gic.h>
22#include <linux/clk/tegra.h> 21#include <linux/clk/tegra.h>
23 22
24#include <asm/cacheflush.h> 23#include <asm/cacheflush.h>
@@ -26,53 +25,58 @@
26#include <asm/smp_scu.h> 25#include <asm/smp_scu.h>
27#include <asm/smp_plat.h> 26#include <asm/smp_plat.h>
28 27
29#include <mach/powergate.h>
30
31#include "fuse.h" 28#include "fuse.h"
32#include "flowctrl.h" 29#include "flowctrl.h"
33#include "reset.h" 30#include "reset.h"
31#include "pmc.h"
34 32
35#include "common.h" 33#include "common.h"
36#include "iomap.h" 34#include "iomap.h"
37 35
38extern void tegra_secondary_startup(void);
39
40static cpumask_t tegra_cpu_init_mask; 36static cpumask_t tegra_cpu_init_mask;
41 37
42#define EVP_CPU_RESET_VECTOR \
43 (IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE) + 0x100)
44
45static void __cpuinit tegra_secondary_init(unsigned int cpu) 38static void __cpuinit tegra_secondary_init(unsigned int cpu)
46{ 39{
47 /*
48 * if any interrupts are already enabled for the primary
49 * core (e.g. timer irq), then they will not have been enabled
50 * for us: do so
51 */
52 gic_secondary_init(0);
53
54 cpumask_set_cpu(cpu, &tegra_cpu_init_mask); 40 cpumask_set_cpu(cpu, &tegra_cpu_init_mask);
55} 41}
56 42
57static int tegra20_power_up_cpu(unsigned int cpu) 43
44static int tegra20_boot_secondary(unsigned int cpu, struct task_struct *idle)
58{ 45{
59 /* Enable the CPU clock. */ 46 cpu = cpu_logical_map(cpu);
60 tegra_enable_cpu_clock(cpu);
61 47
62 /* Clear flow controller CSR. */ 48 /*
63 flowctrl_write_cpu_csr(cpu, 0); 49 * Force the CPU into reset. The CPU must remain in reset when
50 * the flow controller state is cleared (which will cause the
51 * flow controller to stop driving reset if the CPU has been
52 * power-gated via the flow controller). This will have no
53 * effect on first boot of the CPU since it should already be
54 * in reset.
55 */
56 tegra_put_cpu_in_reset(cpu);
64 57
58 /*
59 * Unhalt the CPU. If the flow controller was used to
60 * power-gate the CPU this will cause the flow controller to
61 * stop driving reset. The CPU will remain in reset because the
62 * clock and reset block is now driving reset.
63 */
64 flowctrl_write_cpu_halt(cpu, 0);
65
66 tegra_enable_cpu_clock(cpu);
67 flowctrl_write_cpu_csr(cpu, 0); /* Clear flow controller CSR. */
68 tegra_cpu_out_of_reset(cpu);
65 return 0; 69 return 0;
66} 70}
67 71
68static int tegra30_power_up_cpu(unsigned int cpu) 72static int tegra30_boot_secondary(unsigned int cpu, struct task_struct *idle)
69{ 73{
70 int ret, pwrgateid; 74 int ret;
71 unsigned long timeout; 75 unsigned long timeout;
72 76
73 pwrgateid = tegra_cpu_powergate_id(cpu); 77 cpu = cpu_logical_map(cpu);
74 if (pwrgateid < 0) 78 tegra_put_cpu_in_reset(cpu);
75 return pwrgateid; 79 flowctrl_write_cpu_halt(cpu, 0);
76 80
77 /* 81 /*
78 * The power up sequence of cold boot CPU and warm boot CPU 82 * The power up sequence of cold boot CPU and warm boot CPU
@@ -85,13 +89,13 @@ static int tegra30_power_up_cpu(unsigned int cpu)
85 * the IO clamps. 89 * the IO clamps.
86 * For cold boot CPU, do not wait. After the cold boot CPU be 90 * For cold boot CPU, do not wait. After the cold boot CPU be
87 * booted, it will run to tegra_secondary_init() and set 91 * booted, it will run to tegra_secondary_init() and set
88 * tegra_cpu_init_mask which influences what tegra30_power_up_cpu() 92 * tegra_cpu_init_mask which influences what tegra30_boot_secondary()
89 * next time around. 93 * next time around.
90 */ 94 */
91 if (cpumask_test_cpu(cpu, &tegra_cpu_init_mask)) { 95 if (cpumask_test_cpu(cpu, &tegra_cpu_init_mask)) {
92 timeout = jiffies + msecs_to_jiffies(50); 96 timeout = jiffies + msecs_to_jiffies(50);
93 do { 97 do {
94 if (tegra_powergate_is_powered(pwrgateid)) 98 if (tegra_pmc_cpu_is_powered(cpu))
95 goto remove_clamps; 99 goto remove_clamps;
96 udelay(10); 100 udelay(10);
97 } while (time_before(jiffies, timeout)); 101 } while (time_before(jiffies, timeout));
@@ -103,14 +107,14 @@ static int tegra30_power_up_cpu(unsigned int cpu)
103 * be un-gated by un-toggling the power gate register 107 * be un-gated by un-toggling the power gate register
104 * manually. 108 * manually.
105 */ 109 */
106 if (!tegra_powergate_is_powered(pwrgateid)) { 110 if (!tegra_pmc_cpu_is_powered(cpu)) {
107 ret = tegra_powergate_power_on(pwrgateid); 111 ret = tegra_pmc_cpu_power_on(cpu);
108 if (ret) 112 if (ret)
109 return ret; 113 return ret;
110 114
111 /* Wait for the power to come up. */ 115 /* Wait for the power to come up. */
112 timeout = jiffies + msecs_to_jiffies(100); 116 timeout = jiffies + msecs_to_jiffies(100);
113 while (tegra_powergate_is_powered(pwrgateid)) { 117 while (tegra_pmc_cpu_is_powered(cpu)) {
114 if (time_after(jiffies, timeout)) 118 if (time_after(jiffies, timeout))
115 return -ETIMEDOUT; 119 return -ETIMEDOUT;
116 udelay(10); 120 udelay(10);
@@ -123,60 +127,26 @@ remove_clamps:
123 udelay(10); 127 udelay(10);
124 128
125 /* Remove I/O clamps. */ 129 /* Remove I/O clamps. */
126 ret = tegra_powergate_remove_clamping(pwrgateid); 130 ret = tegra_pmc_cpu_remove_clamping(cpu);
127 if (ret) 131 if (ret)
128 return ret; 132 return ret;
129 133
130 udelay(10); 134 udelay(10);
131 135
132 /* Clear flow controller CSR. */ 136 flowctrl_write_cpu_csr(cpu, 0); /* Clear flow controller CSR. */
133 flowctrl_write_cpu_csr(cpu, 0); 137 tegra_cpu_out_of_reset(cpu);
134
135 return 0; 138 return 0;
136} 139}
137 140
138static int __cpuinit tegra_boot_secondary(unsigned int cpu, struct task_struct *idle) 141static int __cpuinit tegra_boot_secondary(unsigned int cpu,
142 struct task_struct *idle)
139{ 143{
140 int status; 144 if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && tegra_chip_id == TEGRA20)
141 145 return tegra20_boot_secondary(cpu, idle);
142 cpu = cpu_logical_map(cpu); 146 if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) && tegra_chip_id == TEGRA30)
143 147 return tegra30_boot_secondary(cpu, idle);
144 /*
145 * Force the CPU into reset. The CPU must remain in reset when the
146 * flow controller state is cleared (which will cause the flow
147 * controller to stop driving reset if the CPU has been power-gated
148 * via the flow controller). This will have no effect on first boot
149 * of the CPU since it should already be in reset.
150 */
151 tegra_put_cpu_in_reset(cpu);
152
153 /*
154 * Unhalt the CPU. If the flow controller was used to power-gate the
155 * CPU this will cause the flow controller to stop driving reset.
156 * The CPU will remain in reset because the clock and reset block
157 * is now driving reset.
158 */
159 flowctrl_write_cpu_halt(cpu, 0);
160 148
161 switch (tegra_chip_id) { 149 return -EINVAL;
162 case TEGRA20:
163 status = tegra20_power_up_cpu(cpu);
164 break;
165 case TEGRA30:
166 status = tegra30_power_up_cpu(cpu);
167 break;
168 default:
169 status = -EINVAL;
170 break;
171 }
172
173 if (status)
174 goto done;
175
176 /* Take the CPU out of reset. */
177 tegra_cpu_out_of_reset(cpu);
178done:
179 return status;
180} 150}
181 151
182static void __init tegra_smp_prepare_cpus(unsigned int max_cpus) 152static 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 04a8e06f59a9..891fb70d0aa7 100644
--- a/arch/arm/mach-tegra/pm.c
+++ b/arch/arm/mach-tegra/pm.c
@@ -169,12 +169,7 @@ int tegra_cpu_do_idle(void)
169 169
170static int tegra_sleep_cpu(unsigned long v2p) 170static int tegra_sleep_cpu(unsigned long v2p)
171{ 171{
172 /* Switch to the identity mapping. */ 172 setup_mm_for_reboot();
173 cpu_switch_mm(idmap_pgd, &init_mm);
174
175 /* Flush the TLB. */
176 local_flush_tlb_all();
177
178 tegra_sleep_cpu_finish(v2p); 173 tegra_sleep_cpu_finish(v2p);
179 174
180 /* should never here */ 175 /* should never here */
diff --git a/arch/arm/mach-tegra/pmc.c b/arch/arm/mach-tegra/pmc.c
index d4fdb5fcec20..b30e921cc3a9 100644
--- a/arch/arm/mach-tegra/pmc.c
+++ b/arch/arm/mach-tegra/pmc.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved. 2 * Copyright (C) 2012,2013 NVIDIA CORPORATION. All rights reserved.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License, 5 * under the terms and conditions of the GNU General Public License,
@@ -18,57 +18,149 @@
18#include <linux/kernel.h> 18#include <linux/kernel.h>
19#include <linux/io.h> 19#include <linux/io.h>
20#include <linux/of.h> 20#include <linux/of.h>
21#include <linux/of_address.h>
21 22
22#include "iomap.h" 23#define PMC_CTRL 0x0
24#define PMC_CTRL_INTR_LOW (1 << 17)
25#define PMC_PWRGATE_TOGGLE 0x30
26#define PMC_PWRGATE_TOGGLE_START (1 << 8)
27#define PMC_REMOVE_CLAMPING 0x34
28#define PMC_PWRGATE_STATUS 0x38
23 29
24#define PMC_CTRL 0x0 30#define TEGRA_POWERGATE_PCIE 3
25#define PMC_CTRL_INTR_LOW (1 << 17) 31#define TEGRA_POWERGATE_VDEC 4
32#define TEGRA_POWERGATE_CPU1 9
33#define TEGRA_POWERGATE_CPU2 10
34#define TEGRA_POWERGATE_CPU3 11
35
36static u8 tegra_cpu_domains[] = {
37 0xFF, /* not available for CPU0 */
38 TEGRA_POWERGATE_CPU1,
39 TEGRA_POWERGATE_CPU2,
40 TEGRA_POWERGATE_CPU3,
41};
42static DEFINE_SPINLOCK(tegra_powergate_lock);
43
44static void __iomem *tegra_pmc_base;
45static bool tegra_pmc_invert_interrupt;
26 46
27static inline u32 tegra_pmc_readl(u32 reg) 47static inline u32 tegra_pmc_readl(u32 reg)
28{ 48{
29 return readl(IO_ADDRESS(TEGRA_PMC_BASE + reg)); 49 return readl(tegra_pmc_base + reg);
30} 50}
31 51
32static inline void tegra_pmc_writel(u32 val, u32 reg) 52static inline void tegra_pmc_writel(u32 val, u32 reg)
33{ 53{
34 writel(val, IO_ADDRESS(TEGRA_PMC_BASE + reg)); 54 writel(val, tegra_pmc_base + reg);
55}
56
57static int tegra_pmc_get_cpu_powerdomain_id(int cpuid)
58{
59 if (cpuid <= 0 || cpuid >= num_possible_cpus())
60 return -EINVAL;
61 return tegra_cpu_domains[cpuid];
62}
63
64static bool tegra_pmc_powergate_is_powered(int id)
65{
66 return (tegra_pmc_readl(PMC_PWRGATE_STATUS) >> id) & 1;
67}
68
69static int tegra_pmc_powergate_set(int id, bool new_state)
70{
71 bool old_state;
72 unsigned long flags;
73
74 spin_lock_irqsave(&tegra_powergate_lock, flags);
75
76 old_state = tegra_pmc_powergate_is_powered(id);
77 WARN_ON(old_state == new_state);
78
79 tegra_pmc_writel(PMC_PWRGATE_TOGGLE_START | id, PMC_PWRGATE_TOGGLE);
80
81 spin_unlock_irqrestore(&tegra_powergate_lock, flags);
82
83 return 0;
84}
85
86static int tegra_pmc_powergate_remove_clamping(int id)
87{
88 u32 mask;
89
90 /*
91 * Tegra has a bug where PCIE and VDE clamping masks are
92 * swapped relatively to the partition ids.
93 */
94 if (id == TEGRA_POWERGATE_VDEC)
95 mask = (1 << TEGRA_POWERGATE_PCIE);
96 else if (id == TEGRA_POWERGATE_PCIE)
97 mask = (1 << TEGRA_POWERGATE_VDEC);
98 else
99 mask = (1 << id);
100
101 tegra_pmc_writel(mask, PMC_REMOVE_CLAMPING);
102
103 return 0;
104}
105
106bool tegra_pmc_cpu_is_powered(int cpuid)
107{
108 int id;
109
110 id = tegra_pmc_get_cpu_powerdomain_id(cpuid);
111 if (id < 0)
112 return false;
113 return tegra_pmc_powergate_is_powered(id);
114}
115
116int tegra_pmc_cpu_power_on(int cpuid)
117{
118 int id;
119
120 id = tegra_pmc_get_cpu_powerdomain_id(cpuid);
121 if (id < 0)
122 return id;
123 return tegra_pmc_powergate_set(id, true);
124}
125
126int tegra_pmc_cpu_remove_clamping(int cpuid)
127{
128 int id;
129
130 id = tegra_pmc_get_cpu_powerdomain_id(cpuid);
131 if (id < 0)
132 return id;
133 return tegra_pmc_powergate_remove_clamping(id);
35} 134}
36 135
37#ifdef CONFIG_OF
38static const struct of_device_id matches[] __initconst = { 136static const struct of_device_id matches[] __initconst = {
137 { .compatible = "nvidia,tegra114-pmc" },
138 { .compatible = "nvidia,tegra30-pmc" },
39 { .compatible = "nvidia,tegra20-pmc" }, 139 { .compatible = "nvidia,tegra20-pmc" },
40 { } 140 { }
41}; 141};
42#endif
43 142
44void __init tegra_pmc_init(void) 143static void tegra_pmc_parse_dt(void)
45{ 144{
46 /* 145 struct device_node *np;
47 * For now, Harmony is the only board that uses the PMC, and it wants
48 * the signal inverted. Seaboard would too if it used the PMC.
49 * Hopefully by the time other boards want to use the PMC, everything
50 * will be device-tree, or they also want it inverted.
51 */
52 bool invert_interrupt = true;
53 u32 val;
54 146
55#ifdef CONFIG_OF 147 np = of_find_matching_node(NULL, matches);
56 if (of_have_populated_dt()) { 148 BUG_ON(!np);
57 struct device_node *np;
58 149
59 invert_interrupt = false; 150 tegra_pmc_base = of_iomap(np, 0);
151
152 tegra_pmc_invert_interrupt = of_property_read_bool(np,
153 "nvidia,invert-interrupt");
154}
155
156void __init tegra_pmc_init(void)
157{
158 u32 val;
60 159
61 np = of_find_matching_node(NULL, matches); 160 tegra_pmc_parse_dt();
62 if (np) {
63 if (of_find_property(np, "nvidia,invert-interrupt",
64 NULL))
65 invert_interrupt = true;
66 }
67 }
68#endif
69 161
70 val = tegra_pmc_readl(PMC_CTRL); 162 val = tegra_pmc_readl(PMC_CTRL);
71 if (invert_interrupt) 163 if (tegra_pmc_invert_interrupt)
72 val |= PMC_CTRL_INTR_LOW; 164 val |= PMC_CTRL_INTR_LOW;
73 else 165 else
74 val &= ~PMC_CTRL_INTR_LOW; 166 val &= ~PMC_CTRL_INTR_LOW;
diff --git a/arch/arm/mach-tegra/pmc.h b/arch/arm/mach-tegra/pmc.h
index 8995ee4a8768..7d44710368be 100644
--- a/arch/arm/mach-tegra/pmc.h
+++ b/arch/arm/mach-tegra/pmc.h
@@ -18,6 +18,10 @@
18#ifndef __MACH_TEGRA_PMC_H 18#ifndef __MACH_TEGRA_PMC_H
19#define __MACH_TEGRA_PMC_H 19#define __MACH_TEGRA_PMC_H
20 20
21bool tegra_pmc_cpu_is_powered(int cpuid);
22int tegra_pmc_cpu_power_on(int cpuid);
23int tegra_pmc_cpu_remove_clamping(int cpuid);
24
21void tegra_pmc_init(void); 25void tegra_pmc_init(void);
22 26
23#endif 27#endif
diff --git a/arch/arm/mach-tegra/sleep.h b/arch/arm/mach-tegra/sleep.h
index bb308eab9079..2080fb12ce26 100644
--- a/arch/arm/mach-tegra/sleep.h
+++ b/arch/arm/mach-tegra/sleep.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2010-2012, NVIDIA Corporation. All rights reserved. 2 * Copyright (c) 2010-2013, NVIDIA Corporation. All rights reserved.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License, 5 * under the terms and conditions of the GNU General Public License,
@@ -124,11 +124,11 @@ int tegra_sleep_cpu_finish(unsigned long);
124void tegra_disable_clean_inv_dcache(void); 124void tegra_disable_clean_inv_dcache(void);
125 125
126#ifdef CONFIG_HOTPLUG_CPU 126#ifdef CONFIG_HOTPLUG_CPU
127void tegra20_hotplug_init(void); 127void tegra20_hotplug_shutdown(void);
128void tegra30_hotplug_init(void); 128void tegra30_hotplug_shutdown(void);
129void tegra_hotplug_init(void);
129#else 130#else
130static inline void tegra20_hotplug_init(void) {} 131static inline void tegra_hotplug_init(void) {}
131static inline void tegra30_hotplug_init(void) {}
132#endif 132#endif
133 133
134void tegra20_cpu_shutdown(int cpu); 134void tegra20_cpu_shutdown(int cpu);
diff --git a/arch/arm/mach-tegra/board-dt-tegra20.c b/arch/arm/mach-tegra/tegra.c
index a0edf2510280..27232c901a22 100644
--- a/arch/arm/mach-tegra/board-dt-tegra20.c
+++ b/arch/arm/mach-tegra/tegra.c
@@ -1,6 +1,7 @@
1/* 1/*
2 * nVidia Tegra device tree board support 2 * NVIDIA Tegra SoC device tree board support
3 * 3 *
4 * Copyright (C) 2011, 2013, NVIDIA Corporation
4 * Copyright (C) 2010 Secret Lab Technologies, Ltd. 5 * Copyright (C) 2010 Secret Lab Technologies, Ltd.
5 * Copyright (C) 2010 Google, Inc. 6 * Copyright (C) 2010 Google, Inc.
6 * 7 *
@@ -111,7 +112,8 @@ static void __init harmony_init(void)
111 112
112static void __init paz00_init(void) 113static void __init paz00_init(void)
113{ 114{
114 tegra_paz00_wifikill_init(); 115 if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC))
116 tegra_paz00_wifikill_init();
115} 117}
116 118
117static struct { 119static struct {
@@ -137,19 +139,21 @@ static void __init tegra_dt_init_late(void)
137 } 139 }
138} 140}
139 141
140static const char *tegra20_dt_board_compat[] = { 142static const char * const tegra_dt_board_compat[] = {
143 "nvidia,tegra114",
144 "nvidia,tegra30",
141 "nvidia,tegra20", 145 "nvidia,tegra20",
142 NULL 146 NULL
143}; 147};
144 148
145DT_MACHINE_START(TEGRA_DT, "nVidia Tegra20 (Flattened Device Tree)") 149DT_MACHINE_START(TEGRA_DT, "NVIDIA Tegra SoC (Flattened Device Tree)")
146 .map_io = tegra_map_common_io, 150 .map_io = tegra_map_common_io,
147 .smp = smp_ops(tegra_smp_ops), 151 .smp = smp_ops(tegra_smp_ops),
148 .init_early = tegra20_init_early, 152 .init_early = tegra_init_early,
149 .init_irq = tegra_dt_init_irq, 153 .init_irq = tegra_dt_init_irq,
150 .init_time = clocksource_of_init, 154 .init_time = clocksource_of_init,
151 .init_machine = tegra_dt_init, 155 .init_machine = tegra_dt_init,
152 .init_late = tegra_dt_init_late, 156 .init_late = tegra_dt_init_late,
153 .restart = tegra_assert_system_reset, 157 .restart = tegra_assert_system_reset,
154 .dt_compat = tegra20_dt_board_compat, 158 .dt_compat = tegra_dt_board_compat,
155MACHINE_END 159MACHINE_END