Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

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