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 #include <linux/init.h> 15 #include <linux/errno.h> 16 #include <linux/delay.h> 17 #include <linux/device.h> 18 #include <linux/jiffies.h> 19 #include <linux/smp.h> 20 #include <linux/io.h> 21 #include <linux/clk/tegra.h> 22 23 #include <asm/cacheflush.h> 24 #include <asm/mach-types.h> 25 #include <asm/smp_scu.h> 26 #include <asm/smp_plat.h> 27 28 #include "fuse.h" 29 #include "flowctrl.h" 30 #include "reset.h" 31 #include "pmc.h" 32 33 #include "common.h" 34 #include "iomap.h" 35 36 static cpumask_t tegra_cpu_init_mask; 37 38 static void tegra_secondary_init(unsigned int cpu) 39 { 40 cpumask_set_cpu(cpu, &tegra_cpu_init_mask); 41 } 42 43 44 static int tegra20_boot_secondary(unsigned int cpu, struct task_struct *idle) 45 { 46 cpu = cpu_logical_map(cpu); 47 48 /* 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); 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); 69 return 0; 70 } 71 72 static int tegra30_boot_secondary(unsigned int cpu, struct task_struct *idle) 73 { 74 int ret; 75 unsigned long timeout; 76 77 cpu = cpu_logical_map(cpu); 78 tegra_put_cpu_in_reset(cpu); 79 flowctrl_write_cpu_halt(cpu, 0); 80 81 /* 82 * The power up sequence of cold boot CPU and warm boot CPU 83 * was different. 84 * 85 * For warm boot CPU that was resumed from CPU hotplug, the 86 * power will be resumed automatically after un-halting the 87 * flow controller of the warm boot CPU. We need to wait for 88 * the confirmaiton that the CPU is powered then removing 89 * the IO clamps. 90 * For cold boot CPU, do not wait. After the cold boot CPU be 91 * booted, it will run to tegra_secondary_init() and set 92 * tegra_cpu_init_mask which influences what tegra30_boot_secondary() 93 * next time around. 94 */ 95 if (cpumask_test_cpu(cpu, &tegra_cpu_init_mask)) { 96 timeout = jiffies + msecs_to_jiffies(50); 97 do { 98 if (tegra_pmc_cpu_is_powered(cpu)) 99 goto remove_clamps; 100 udelay(10); 101 } while (time_before(jiffies, timeout)); 102 } 103 104 /* 105 * The power status of the cold boot CPU is power gated as 106 * default. To power up the cold boot CPU, the power should 107 * be un-gated by un-toggling the power gate register 108 * manually. 109 */ 110 if (!tegra_pmc_cpu_is_powered(cpu)) { 111 ret = tegra_pmc_cpu_power_on(cpu); 112 if (ret) 113 return ret; 114 115 /* Wait for the power to come up. */ 116 timeout = jiffies + msecs_to_jiffies(100); 117 while (tegra_pmc_cpu_is_powered(cpu)) { 118 if (time_after(jiffies, timeout)) 119 return -ETIMEDOUT; 120 udelay(10); 121 } 122 } 123 124 remove_clamps: 125 /* CPU partition is powered. Enable the CPU clock. */ 126 tegra_enable_cpu_clock(cpu); 127 udelay(10); 128 129 /* Remove I/O clamps. */ 130 ret = tegra_pmc_cpu_remove_clamping(cpu); 131 if (ret) 132 return ret; 133 134 udelay(10); 135 136 flowctrl_write_cpu_csr(cpu, 0); /* Clear flow controller CSR. */ 137 tegra_cpu_out_of_reset(cpu); 138 return 0; 139 } 140 141 static int tegra114_boot_secondary(unsigned int cpu, struct task_struct *idle) 142 { 143 int ret = 0; 144 145 cpu = cpu_logical_map(cpu); 146 147 if (cpumask_test_cpu(cpu, &tegra_cpu_init_mask)) { 148 /* 149 * Warm boot flow 150 * The flow controller in charge of the power state and 151 * control for each CPU. 152 */ 153 /* set SCLK as event trigger for flow controller */ 154 flowctrl_write_cpu_csr(cpu, 1); 155 flowctrl_write_cpu_halt(cpu, 156 FLOW_CTRL_WAITEVENT | FLOW_CTRL_SCLK_RESUME); 157 } else { 158 /* 159 * Cold boot flow 160 * The CPU is powered up by toggling PMC directly. It will 161 * also initial power state in flow controller. After that, 162 * the CPU's power state is maintained by flow controller. 163 */ 164 ret = tegra_pmc_cpu_power_on(cpu); 165 } 166 167 return ret; 168 } 169 170 static int tegra_boot_secondary(unsigned int cpu, 171 struct task_struct *idle) 172 { 173 if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && tegra_chip_id == TEGRA20) 174 return tegra20_boot_secondary(cpu, idle); 175 if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) && tegra_chip_id == TEGRA30) 176 return tegra30_boot_secondary(cpu, idle); 177 if (IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) && tegra_chip_id == TEGRA114) 178 return tegra114_boot_secondary(cpu, idle); 179 if (IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC) && tegra_chip_id == TEGRA124) 180 return tegra114_boot_secondary(cpu, idle); 181 182 return -EINVAL; 183 } 184 185 static void __init tegra_smp_prepare_cpus(unsigned int max_cpus) 186 { 187 /* Always mark the boot CPU (CPU0) as initialized. */ 188 cpumask_set_cpu(0, &tegra_cpu_init_mask); 189 190 if (scu_a9_has_base()) 191 scu_enable(IO_ADDRESS(scu_a9_get_base())); 192 } 193 194 struct smp_operations tegra_smp_ops __initdata = { 195 .smp_prepare_cpus = tegra_smp_prepare_cpus, 196 .smp_secondary_init = tegra_secondary_init, 197 .smp_boot_secondary = tegra_boot_secondary, 198 #ifdef CONFIG_HOTPLUG_CPU 199 .cpu_kill = tegra_cpu_kill, 200 .cpu_die = tegra_cpu_die, 201 #endif 202 }; 203