--- zzzz-none-000/linux-3.10.107/arch/arm/mach-tegra/platsmp.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/arch/arm/mach-tegra/platsmp.c 2021-02-04 17:41:59.000000000 +0000 @@ -11,31 +11,32 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ -#include -#include + +#include #include #include +#include +#include +#include #include #include -#include -#include + +#include +#include #include #include -#include #include - -#include "fuse.h" -#include "flowctrl.h" -#include "reset.h" -#include "pmc.h" +#include #include "common.h" +#include "flowctrl.h" #include "iomap.h" +#include "reset.h" static cpumask_t tegra_cpu_init_mask; -static void __cpuinit tegra_secondary_init(unsigned int cpu) +static void tegra_secondary_init(unsigned int cpu) { cpumask_set_cpu(cpu, &tegra_cpu_init_mask); } @@ -114,7 +115,7 @@ /* Wait for the power to come up. */ timeout = jiffies + msecs_to_jiffies(100); - while (tegra_pmc_cpu_is_powered(cpu)) { + while (!tegra_pmc_cpu_is_powered(cpu)) { if (time_after(jiffies, timeout)) return -ETIMEDOUT; udelay(10); @@ -140,18 +141,43 @@ static int tegra114_boot_secondary(unsigned int cpu, struct task_struct *idle) { + int ret = 0; + cpu = cpu_logical_map(cpu); - return tegra_pmc_cpu_power_on(cpu); + + if (cpumask_test_cpu(cpu, &tegra_cpu_init_mask)) { + /* + * Warm boot flow + * The flow controller in charge of the power state and + * control for each CPU. + */ + /* set SCLK as event trigger for flow controller */ + flowctrl_write_cpu_csr(cpu, 1); + flowctrl_write_cpu_halt(cpu, + FLOW_CTRL_WAITEVENT | FLOW_CTRL_SCLK_RESUME); + } else { + /* + * Cold boot flow + * The CPU is powered up by toggling PMC directly. It will + * also initial power state in flow controller. After that, + * the CPU's power state is maintained by flow controller. + */ + ret = tegra_pmc_cpu_power_on(cpu); + } + + return ret; } -static int __cpuinit tegra_boot_secondary(unsigned int cpu, +static int tegra_boot_secondary(unsigned int cpu, struct task_struct *idle) { - if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && tegra_chip_id == TEGRA20) + if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && tegra_get_chip_id() == TEGRA20) return tegra20_boot_secondary(cpu, idle); - if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) && tegra_chip_id == TEGRA30) + if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) && tegra_get_chip_id() == TEGRA30) return tegra30_boot_secondary(cpu, idle); - if (IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) && tegra_chip_id == TEGRA114) + if (IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) && tegra_get_chip_id() == TEGRA114) + return tegra114_boot_secondary(cpu, idle); + if (IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC) && tegra_get_chip_id() == TEGRA124) return tegra114_boot_secondary(cpu, idle); return -EINVAL;