1 /* 2 * linux/arch/arm/mach-tegra/platsmp.c 3 * 4 * Copyright (C) 2002 ARM Ltd. 5 * All Rights Reserved 6 * 7 * Copyright (C) 2009 Palm 8 * All Rights Reserved 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License version 2 as 12 * published by the Free Software Foundation. 13 */ 14 15 #include <linux/clk/tegra.h> 16 #include <linux/delay.h> 17 #include <linux/device.h> 18 #include <linux/errno.h> 19 #include <linux/init.h> 20 #include <linux/io.h> 21 #include <linux/jiffies.h> 22 #include <linux/smp.h> 23 24 #include <soc/tegra/fuse.h> 25 #include <soc/tegra/pmc.h> 26 27 #include <asm/cacheflush.h> 28 #include <asm/mach-types.h> 29 #include <asm/smp_plat.h> 30 #include <asm/smp_scu.h> 31 32 #include "common.h" 33 #include "flowctrl.h" 34 #include "iomap.h" 35 #include "reset.h" 36 37 static cpumask_t tegra_cpu_init_mask; 38 39 static void tegra_secondary_init(unsigned int cpu) 40 { 41 cpumask_set_cpu(cpu, &tegra_cpu_init_mask); 42 } 43 44 45 static int tegra20_boot_secondary(unsigned int cpu, struct task_struct *idle) 46 { 47 cpu = cpu_logical_map(cpu); 48 49 /* 50 * Force the CPU into reset. The CPU must remain in reset when 51 * the flow controller state is cleared (which will cause the 52 * flow controller to stop driving reset if the CPU has been 53 * power-gated via the flow controller). This will have no 54 * effect on first boot of the CPU since it should already be 55 * in reset. 56 */ 57 tegra_put_cpu_in_reset(cpu); 58 59 /* 60 * Unhalt the CPU. If the flow controller was used to 61 * power-gate the CPU this will cause the flow controller to 62 * stop driving reset. The CPU will remain in reset because the 63 * clock and reset block is now driving reset. 64 */ 65 flowctrl_write_cpu_halt(cpu, 0); 66 67 tegra_enable_cpu_clock(cpu); 68 flowctrl_write_cpu_csr(cpu, 0); /* Clear flow controller CSR. */ 69 tegra_cpu_out_of_reset(cpu); 70 return 0; 71 } 72 73 static int tegra30_boot_secondary(unsigned int cpu, struct task_struct *idle) 74 { 75 int ret; 76 unsigned long timeout; 77 78 cpu = cpu_logical_map(cpu); 79 tegra_put_cpu_in_reset(cpu); 80 flowctrl_write_cpu_halt(cpu, 0); 81 82 /* 83 * The power up sequence of cold boot CPU and warm boot CPU 84 * was different. 85 * 86 * For warm boot CPU that was resumed from CPU hotplug, the 87 * power will be resumed automatically after un-halting the 88 * flow controller of the warm boot CPU. We need to wait for 89 * the confirmaiton that the CPU is powered then removing 90 * the IO clamps. 91 * For cold boot CPU, do not wait. After the cold boot CPU be 92 * booted, it will run to tegra_secondary_init() and set 93 * tegra_cpu_init_mask which influences what tegra30_boot_secondary() 94 * next time around. 95 */ 96 if (cpumask_test_cpu(cpu, &tegra_cpu_init_mask)) { 97 timeout = jiffies + msecs_to_jiffies(50); 98 do { 99 if (tegra_pmc_cpu_is_powered(cpu)) 100 goto remove_clamps; 101 udelay(10); 102 } while (time_before(jiffies, timeout)); 103 } 104 105 /* 106 * The power status of the cold boot CPU is power gated as 107 * default. To power up the cold boot CPU, the power should 108 * be un-gated by un-toggling the power gate register 109 * manually. 110 */ 111 if (!tegra_pmc_cpu_is_powered(cpu)) { 112 ret = tegra_pmc_cpu_power_on(cpu); 113 if (ret) 114 return ret; 115 116 /* Wait for the power to come up. */ 117 timeout = jiffies + msecs_to_jiffies(100); 118 while (!tegra_pmc_cpu_is_powered(cpu)) { 119 if (time_after(jiffies, timeout)) 120 return -ETIMEDOUT; 121 udelay(10); 122 } 123 } 124 125 remove_clamps: 126 /* CPU partition is powered. Enable the CPU clock. */ 127 tegra_enable_cpu_clock(cpu); 128 udelay(10); 129 130 /* Remove I/O clamps. */ 131 ret = tegra_pmc_cpu_remove_clamping(cpu); 132 if (ret) 133 return ret; 134 135 udelay(10); 136 137 flowctrl_write_cpu_csr(cpu, 0); /* Clear flow controller CSR. */ 138 tegra_cpu_out_of_reset(cpu); 139 return 0; 140 } 141 142 static int tegra114_boot_secondary(unsigned int cpu, struct task_struct *idle) 143 { 144 int ret = 0; 145 146 cpu = cpu_logical_map(cpu); 147 148 if (cpumask_test_cpu(cpu, &tegra_cpu_init_mask)) { 149 /* 150 * Warm boot flow 151 * The flow controller in charge of the power state and 152 * control for each CPU. 153 */ 154 /* set SCLK as event trigger for flow controller */ 155 flowctrl_write_cpu_csr(cpu, 1); 156 flowctrl_write_cpu_halt(cpu, 157 FLOW_CTRL_WAITEVENT | FLOW_CTRL_SCLK_RESUME); 158 } else { 159 /* 160 * Cold boot flow 161 * The CPU is powered up by toggling PMC directly. It will 162 * also initial power state in flow controller. After that, 163 * the CPU's power state is maintained by flow controller. 164 */ 165 ret = tegra_pmc_cpu_power_on(cpu); 166 } 167 168 return ret; 169 } 170 171 static int tegra_boot_secondary(unsigned int cpu, 172 struct task_struct *idle) 173 { 174 if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && tegra_get_chip_id() == TEGRA20) 175 return tegra20_boot_secondary(cpu, idle); 176 if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) && tegra_get_chip_id() == TEGRA30) 177 return tegra30_boot_secondary(cpu, idle); 178 if (IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) && tegra_get_chip_id() == TEGRA114) 179 return tegra114_boot_secondary(cpu, idle); 180 if (IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC) && tegra_get_chip_id() == TEGRA124) 181 return tegra114_boot_secondary(cpu, idle); 182 183 return -EINVAL; 184 } 185 186 static void __init tegra_smp_prepare_cpus(unsigned int max_cpus) 187 { 188 /* Always mark the boot CPU (CPU0) as initialized. */ 189 cpumask_set_cpu(0, &tegra_cpu_init_mask); 190 191 if (scu_a9_has_base()) 192 scu_enable(IO_ADDRESS(scu_a9_get_base())); 193 } 194 195 struct smp_operations tegra_smp_ops __initdata = { 196 .smp_prepare_cpus = tegra_smp_prepare_cpus, 197 .smp_secondary_init = tegra_secondary_init, 198 .smp_boot_secondary = tegra_boot_secondary, 199 #ifdef CONFIG_HOTPLUG_CPU 200 .cpu_kill = tegra_cpu_kill, 201 .cpu_die = tegra_cpu_die, 202 #endif 203 }; 204