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)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * Copyright (C) 2007 MIPS Technologies, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *    Chris Dearman (chris@mips.com)
^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) #undef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/sched/task_stack.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/smp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/cpumask.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/compiler.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/atomic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <asm/cacheflush.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <asm/cpu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <asm/processor.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <asm/hardirq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <asm/mmu_context.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include <asm/smp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include <asm/time.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include <asm/mipsregs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #include <asm/mipsmtregs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #include <asm/mips_mt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #include <asm/amon.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) static void cmp_init_secondary(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	struct cpuinfo_mips *c __maybe_unused = &current_cpu_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	/* Assume GIC is present */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	change_c0_status(ST0_IM, STATUSF_IP2 | STATUSF_IP3 | STATUSF_IP4 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 				 STATUSF_IP5 | STATUSF_IP6 | STATUSF_IP7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	/* Enable per-cpu interrupts: platform specific */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #ifdef CONFIG_MIPS_MT_SMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	if (cpu_has_mipsmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 		cpu_set_vpe_id(c, (read_c0_tcbind() >> TCBIND_CURVPE_SHIFT) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 				  TCBIND_CURVPE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) #endif
^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) static void cmp_smp_finish(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	pr_debug("SMPCMP: CPU%d: %s\n", smp_processor_id(), __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	/* CDFIXME: remove this? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	write_c0_compare(read_c0_count() + (8 * mips_hpt_frequency / HZ));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) #ifdef CONFIG_MIPS_MT_FPAFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	/* If we have an FPU, enroll ourselves in the FPU-full mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	if (cpu_has_fpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 		cpumask_set_cpu(smp_processor_id(), &mt_fpu_cpumask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) #endif /* CONFIG_MIPS_MT_FPAFF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	local_irq_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64)  * Setup the PC, SP, and GP of a secondary processor and start it running
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65)  * smp_bootstrap is the place to resume from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66)  * __KSTK_TOS(idle) is apparently the stack pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67)  * (unsigned long)idle->thread_info the gp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) static int cmp_boot_secondary(int cpu, struct task_struct *idle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	struct thread_info *gp = task_thread_info(idle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	unsigned long sp = __KSTK_TOS(idle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	unsigned long pc = (unsigned long)&smp_bootstrap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	unsigned long a0 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	pr_debug("SMPCMP: CPU%d: %s cpu %d\n", smp_processor_id(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 		__func__, cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	/* Needed? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	flush_icache_range((unsigned long)gp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 			   (unsigned long)(gp + sizeof(struct thread_info)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	amon_cpu_start(cpu, pc, sp, (unsigned long)gp, a0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90)  * Common setup before any secondaries are started
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) void __init cmp_smp_setup(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	int ncpu = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	pr_debug("SMPCMP: CPU%d: %s\n", smp_processor_id(), __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) #ifdef CONFIG_MIPS_MT_FPAFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	/* If we have an FPU, enroll ourselves in the FPU-full mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	if (cpu_has_fpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 		cpumask_set_cpu(0, &mt_fpu_cpumask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #endif /* CONFIG_MIPS_MT_FPAFF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	for (i = 1; i < NR_CPUS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 		if (amon_cpu_avail(i)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 			set_cpu_possible(i, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 			__cpu_number_map[i]	= ++ncpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 			__cpu_logical_map[ncpu] = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	if (cpu_has_mipsmt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 		unsigned int nvpe = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #ifdef CONFIG_MIPS_MT_SMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 		unsigned int mvpconf0 = read_c0_mvpconf0();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 		nvpe = ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		smp_num_siblings = nvpe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	pr_info("Detected %i available secondary CPU(s)\n", ncpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) void __init cmp_prepare_cpus(unsigned int max_cpus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	pr_debug("SMPCMP: CPU%d: %s max_cpus=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 		 smp_processor_id(), __func__, max_cpus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) #ifdef CONFIG_MIPS_MT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	 * FIXME: some of these options are per-system, some per-core and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	 * some per-cpu
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	mips_mt_set_cpuoptions();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) const struct plat_smp_ops cmp_smp_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	.send_ipi_single	= mips_smp_send_ipi_single,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	.send_ipi_mask		= mips_smp_send_ipi_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	.init_secondary		= cmp_init_secondary,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	.smp_finish		= cmp_smp_finish,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	.boot_secondary		= cmp_boot_secondary,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	.smp_setup		= cmp_smp_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	.prepare_cpus		= cmp_prepare_cpus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) };