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
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * General MIPS MT support routines, usable in AP/SP and SMVP.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * Copyright (C) 2005 Mips Technologies, Inc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/security.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <asm/cpu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <asm/processor.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/atomic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <asm/hardirq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <asm/mmu_context.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <asm/mipsmtregs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <asm/r4kcache.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <asm/cacheflush.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) int vpelimit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) static int __init maxvpes(char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	get_option(&str, &vpelimit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) __setup("maxvpes=", maxvpes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) int tclimit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) static int __init maxtcs(char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	get_option(&str, &tclimit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) __setup("maxtcs=", maxtcs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46)  * Dump new MIPS MT state for the core. Does not leave TCs halted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47)  * Takes an argument which taken to be a pre-call MVPControl value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) void mips_mt_regdump(unsigned long mvpctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	unsigned long vpflags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	unsigned long mvpconf0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	int nvpe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	int ntc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	int tc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	unsigned long haltval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	unsigned long tcstatval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	vpflags = dvpe();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	printk("=== MIPS MT State Dump ===\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	printk("-- Global State --\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	printk("   MVPControl Passed: %08lx\n", mvpctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	printk("   MVPControl Read: %08lx\n", vpflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	printk("   MVPConf0 : %08lx\n", (mvpconf0 = read_c0_mvpconf0()));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	nvpe = ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	ntc = ((mvpconf0 & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	printk("-- per-VPE State --\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	for (i = 0; i < nvpe; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 		for (tc = 0; tc < ntc; tc++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 			settc(tc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 			if ((read_tc_c0_tcbind() & TCBIND_CURVPE) == i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 				printk("  VPE %d\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 				printk("   VPEControl : %08lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 				       read_vpe_c0_vpecontrol());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 				printk("   VPEConf0 : %08lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 				       read_vpe_c0_vpeconf0());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 				printk("   VPE%d.Status : %08lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 				       i, read_vpe_c0_status());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 				printk("   VPE%d.EPC : %08lx %pS\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 				       i, read_vpe_c0_epc(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 				       (void *) read_vpe_c0_epc());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 				printk("   VPE%d.Cause : %08lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 				       i, read_vpe_c0_cause());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 				printk("   VPE%d.Config7 : %08lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 				       i, read_vpe_c0_config7());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 				break; /* Next VPE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	printk("-- per-TC State --\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	for (tc = 0; tc < ntc; tc++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 		settc(tc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		if (read_tc_c0_tcbind() == read_c0_tcbind()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 			/* Are we dumping ourself?  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 			haltval = 0; /* Then we're not halted, and mustn't be */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 			tcstatval = flags; /* And pre-dump TCStatus is flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 			printk("  TC %d (current TC with VPE EPC above)\n", tc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 			haltval = read_tc_c0_tchalt();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 			write_tc_c0_tchalt(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 			tcstatval = read_tc_c0_tcstatus();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 			printk("  TC %d\n", tc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		printk("   TCStatus : %08lx\n", tcstatval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 		printk("   TCBind : %08lx\n", read_tc_c0_tcbind());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 		printk("   TCRestart : %08lx %pS\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 		       read_tc_c0_tcrestart(), (void *) read_tc_c0_tcrestart());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 		printk("   TCHalt : %08lx\n", haltval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 		printk("   TCContext : %08lx\n", read_tc_c0_tccontext());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 		if (!haltval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 			write_tc_c0_tchalt(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	printk("===========================\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	evpe(vpflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) static int mt_opt_rpsctl = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) static int mt_opt_nblsu = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) static int mt_opt_forceconfig7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) static int mt_opt_config7 = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) static int __init rpsctl_set(char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	get_option(&str, &mt_opt_rpsctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) __setup("rpsctl=", rpsctl_set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) static int __init nblsu_set(char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	get_option(&str, &mt_opt_nblsu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) __setup("nblsu=", nblsu_set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) static int __init config7_set(char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	get_option(&str, &mt_opt_config7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	mt_opt_forceconfig7 = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) __setup("config7=", config7_set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) static unsigned int itc_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) static int __init set_itc_base(char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	get_option(&str, &itc_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) __setup("itcbase=", set_itc_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) void mips_mt_set_cpuoptions(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	unsigned int oconfig7 = read_c0_config7();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	unsigned int nconfig7 = oconfig7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	if (mt_opt_rpsctl >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 		printk("34K return prediction stack override set to %d.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 			mt_opt_rpsctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 		if (mt_opt_rpsctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 			nconfig7 |= (1 << 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 			nconfig7 &= ~(1 << 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	if (mt_opt_nblsu >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 		printk("34K ALU/LSU sync override set to %d.\n", mt_opt_nblsu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 		if (mt_opt_nblsu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 			nconfig7 |= (1 << 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 			nconfig7 &= ~(1 << 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	if (mt_opt_forceconfig7) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 		printk("CP0.Config7 forced to 0x%08x.\n", mt_opt_config7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 		nconfig7 = mt_opt_config7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	if (oconfig7 != nconfig7) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 		__asm__ __volatile("sync");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 		write_c0_config7(nconfig7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 		ehb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 		printk("Config7: 0x%08x\n", read_c0_config7());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	if (itc_base != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 		 * Configure ITC mapping.  This code is very
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 		 * specific to the 34K core family, which uses
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 		 * a special mode bit ("ITC") in the ErrCtl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 		 * register to enable access to ITC control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 		 * registers via cache "tag" operations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 		unsigned long ectlval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 		unsigned long itcblkgrn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 		/* ErrCtl register is known as "ecc" to Linux */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 		ectlval = read_c0_ecc();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 		write_c0_ecc(ectlval | (0x1 << 26));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 		ehb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) #define INDEX_0 (0x80000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) #define INDEX_8 (0x80000008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 		/* Read "cache tag" for Dcache pseudo-index 8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 		cache_op(Index_Load_Tag_D, INDEX_8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 		ehb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 		itcblkgrn = read_c0_dtaglo();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 		itcblkgrn &= 0xfffe0000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 		/* Set for 128 byte pitch of ITC cells */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 		itcblkgrn |= 0x00000c00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 		/* Stage in Tag register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 		write_c0_dtaglo(itcblkgrn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 		ehb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 		/* Write out to ITU with CACHE op */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 		cache_op(Index_Store_Tag_D, INDEX_8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 		/* Now set base address, and turn ITC on with 0x1 bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 		write_c0_dtaglo((itc_base & 0xfffffc00) | 0x1 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 		ehb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 		/* Write out to ITU with CACHE op */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 		cache_op(Index_Store_Tag_D, INDEX_0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 		write_c0_ecc(ectlval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 		ehb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 		printk("Mapped %ld ITC cells starting at 0x%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 			((itcblkgrn & 0x7fe00000) >> 20), itc_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) struct class *mt_class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) static int __init mt_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	struct class *mtc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	mtc = class_create(THIS_MODULE, "mt");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	if (IS_ERR(mtc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 		return PTR_ERR(mtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	mt_class = mtc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) subsys_initcall(mt_init);