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-axxia/platsmp.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5)  * Copyright (C) 2012 LSI Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/smp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/of_address.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <asm/cacheflush.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) /* Syscon register offsets for releasing cores from reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #define SC_CRIT_WRITE_KEY	0x1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define SC_RST_CPU_HOLD		0x1010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)  * Write the kernel entry point for secondary CPUs to the specified address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) static void write_release_addr(u32 release_phys)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) 	u32 *virt = (u32 *) phys_to_virt(release_phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) 	writel_relaxed(__pa_symbol(secondary_startup), virt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) 	/* Make sure this store is visible to other CPUs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) 	smp_wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) 	__cpuc_flush_dcache_area(virt, sizeof(u32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) static int axxia_boot_secondary(unsigned int cpu, struct task_struct *idle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) 	struct device_node *syscon_np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) 	void __iomem *syscon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) 	u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) 	syscon_np = of_find_compatible_node(NULL, NULL, "lsi,axxia-syscon");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) 	if (!syscon_np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) 		return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) 	syscon = of_iomap(syscon_np, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) 	if (!syscon)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) 	tmp = readl(syscon + SC_RST_CPU_HOLD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) 	writel(0xab, syscon + SC_CRIT_WRITE_KEY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) 	tmp &= ~(1 << cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) 	writel(tmp, syscon + SC_RST_CPU_HOLD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) static void __init axxia_smp_prepare_cpus(unsigned int max_cpus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) 	int cpu_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) 	int cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) 	 * Initialise the present map, which describes the set of CPUs actually
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) 	 * populated at the present time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) 	for_each_possible_cpu(cpu) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) 		struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) 		u32 release_phys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) 		np = of_get_cpu_node(cpu, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) 		if (!np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) 		if (of_property_read_u32(np, "cpu-release-addr", &release_phys))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) 		if (cpu_count < max_cpus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) 			set_cpu_present(cpu, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) 			cpu_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) 		if (release_phys != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) 			write_release_addr(release_phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) static const struct smp_operations axxia_smp_ops __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) 	.smp_prepare_cpus	= axxia_smp_prepare_cpus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) 	.smp_boot_secondary	= axxia_boot_secondary,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) CPU_METHOD_OF_DECLARE(axxia_smp, "lsi,syscon-release", &axxia_smp_ops);