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 ret = tegra_pmc_cpu_power_on(cpu); 112 if (ret) 113 return ret; 114 115 remove_clamps: 116 /* CPU partition is powered. Enable the CPU clock. */ 117 tegra_enable_cpu_clock(cpu); 118 udelay(10); 119 120 /* Remove I/O clamps. */ 121 ret = tegra_pmc_cpu_remove_clamping(cpu); 122 if (ret) 123 return ret; 124 125 udelay(10); 126 127 flowctrl_write_cpu_csr(cpu, 0); /* Clear flow controller CSR. */ 128 tegra_cpu_out_of_reset(cpu); 129 return 0; 130 } 131 132 static int tegra114_boot_secondary(unsigned int cpu, struct task_struct *idle) 133 { 134 int ret = 0; 135 136 cpu = cpu_logical_map(cpu); 137 138 if (cpumask_test_cpu(cpu, &tegra_cpu_init_mask)) { 139 /* 140 * Warm boot flow 141 * The flow controller in charge of the power state and 142 * control for each CPU. 143 */ 144 /* set SCLK as event trigger for flow controller */ 145 flowctrl_write_cpu_csr(cpu, 1); 146 flowctrl_write_cpu_halt(cpu, 147 FLOW_CTRL_WAITEVENT | FLOW_CTRL_SCLK_RESUME); 148 } else { 149 /* 150 * Cold boot flow 151 * The CPU is powered up by toggling PMC directly. It will 152 * also initial power state in flow controller. After that, 153 * the CPU's power state is maintained by flow controller. 154 */ 155 ret = tegra_pmc_cpu_power_on(cpu); 156 } 157 158 return ret; 159 } 160 161 static int tegra_boot_secondary(unsigned int cpu, 162 struct task_struct *idle) 163 { 164 if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && tegra_get_chip_id() == TEGRA20) 165 return tegra20_boot_secondary(cpu, idle); 166 if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) && tegra_get_chip_id() == TEGRA30) 167 return tegra30_boot_secondary(cpu, idle); 168 if (IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) && tegra_get_chip_id() == TEGRA114) 169 return tegra114_boot_secondary(cpu, idle); 170 if (IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC) && tegra_get_chip_id() == TEGRA124) 171 return tegra114_boot_secondary(cpu, idle); 172 173 return -EINVAL; 174 } 175 176 static void __init tegra_smp_prepare_cpus(unsigned int max_cpus) 177 { 178 /* Always mark the boot CPU (CPU0) as initialized. */ 179 cpumask_set_cpu(0, &tegra_cpu_init_mask); 180 181 if (scu_a9_has_base()) 182 scu_enable(IO_ADDRESS(scu_a9_get_base())); 183 } 184 185 const struct smp_operations tegra_smp_ops __initconst = { 186 .smp_prepare_cpus = tegra_smp_prepare_cpus, 187 .smp_secondary_init = tegra_secondary_init, 188 .smp_boot_secondary = tegra_boot_secondary, 189 #ifdef CONFIG_HOTPLUG_CPU 190 .cpu_kill = tegra_cpu_kill, 191 .cpu_die = tegra_cpu_die, 192 #endif 193 }; 194