This source file includes following definitions.
- do_memory_error
- mtm_init_nat
- mtm_init_thread
- mtm_enable_thread
- mtm_enable_core
- set_mtm_hs_ctr
1
2
3
4
5
6 #include <linux/smp.h>
7 #include <linux/init.h>
8 #include <linux/kernel.h>
9 #include <linux/io.h>
10 #include <linux/log2.h>
11 #include <asm/arcregs.h>
12 #include <plat/mtm.h>
13 #include <plat/smp.h>
14
15 #define MT_HS_CNT_MIN 0x01
16 #define MT_HS_CNT_MAX 0xFF
17 #define MT_CTRL_ST_CNT 0xF
18 #define NPS_NUM_HW_THREADS 0x10
19
20 static int mtm_hs_ctr = MT_HS_CNT_MAX;
21
22 #ifdef CONFIG_EZNPS_MEM_ERROR_ALIGN
23 int do_memory_error(unsigned long address, struct pt_regs *regs)
24 {
25 die("Invalid Mem Access", regs, address);
26
27 return 1;
28 }
29 #endif
30
31 static void mtm_init_nat(int cpu)
32 {
33 struct nps_host_reg_mtm_cfg mtm_cfg;
34 struct nps_host_reg_aux_udmc udmc;
35 int log_nat, nat = 0, i, t;
36
37
38 for (i = 0, t = cpu; i < NPS_NUM_HW_THREADS; i++, t++)
39 nat += test_bit(t, cpumask_bits(cpu_possible_mask));
40
41 log_nat = ilog2(nat);
42
43 udmc.value = read_aux_reg(CTOP_AUX_UDMC);
44 udmc.nat = log_nat;
45 write_aux_reg(CTOP_AUX_UDMC, udmc.value);
46
47 mtm_cfg.value = ioread32be(MTM_CFG(cpu));
48 mtm_cfg.nat = log_nat;
49 iowrite32be(mtm_cfg.value, MTM_CFG(cpu));
50 }
51
52 static void mtm_init_thread(int cpu)
53 {
54 int i, tries = 5;
55 struct nps_host_reg_thr_init thr_init;
56 struct nps_host_reg_thr_init_sts thr_init_sts;
57
58
59 thr_init.value = 0;
60 iowrite32be(thr_init.value, MTM_THR_INIT(cpu));
61 thr_init.thr_id = NPS_CPU_TO_THREAD_NUM(cpu);
62 thr_init.str = 1;
63 iowrite32be(thr_init.value, MTM_THR_INIT(cpu));
64
65
66 for (i = 0; i < tries; i++) {
67 thr_init_sts.value = ioread32be(MTM_THR_INIT_STS(cpu));
68 if (thr_init_sts.thr_id == thr_init.thr_id) {
69 if (thr_init_sts.bsy)
70 continue;
71 else if (thr_init_sts.err)
72 pr_warn("Failed to thread init cpu %u\n", cpu);
73 break;
74 }
75
76 pr_warn("Wrong thread id in thread init for cpu %u\n", cpu);
77 break;
78 }
79
80 if (i == tries)
81 pr_warn("Got thread init timeout for cpu %u\n", cpu);
82 }
83
84 int mtm_enable_thread(int cpu)
85 {
86 struct nps_host_reg_mtm_cfg mtm_cfg;
87
88 if (NPS_CPU_TO_THREAD_NUM(cpu) == 0)
89 return 1;
90
91
92 mtm_cfg.value = ioread32be(MTM_CFG(cpu));
93 mtm_cfg.ten |= (1 << (NPS_CPU_TO_THREAD_NUM(cpu)));
94 iowrite32be(mtm_cfg.value, MTM_CFG(cpu));
95
96 return 0;
97 }
98
99 void mtm_enable_core(unsigned int cpu)
100 {
101 int i;
102 struct nps_host_reg_aux_mt_ctrl mt_ctrl;
103 struct nps_host_reg_mtm_cfg mtm_cfg;
104 struct nps_host_reg_aux_dpc dpc;
105
106
107
108
109
110
111
112
113 dpc.ien = 1;
114 dpc.men = 1;
115 write_aux_reg(CTOP_AUX_DPC, dpc.value);
116
117 if (NPS_CPU_TO_THREAD_NUM(cpu) != 0)
118 return;
119
120
121 mtm_init_nat(cpu);
122
123
124 mtm_cfg.value = ioread32be(MTM_CFG(cpu));
125 mtm_cfg.ten = 1;
126 iowrite32be(mtm_cfg.value, MTM_CFG(cpu));
127
128
129 for (i = 1; i < NPS_NUM_HW_THREADS; i++)
130 mtm_init_thread(cpu + i);
131
132
133
134 mt_ctrl.value = 0;
135 mt_ctrl.hsen = 1;
136 mt_ctrl.hs_cnt = mtm_hs_ctr;
137 mt_ctrl.mten = 1;
138 write_aux_reg(CTOP_AUX_MT_CTRL, mt_ctrl.value);
139
140
141
142
143
144
145 cpu_relax();
146 }
147
148
149 static int __init set_mtm_hs_ctr(char *ctr_str)
150 {
151 int hs_ctr;
152 int ret;
153
154 ret = kstrtoint(ctr_str, 0, &hs_ctr);
155
156 if (ret || hs_ctr > MT_HS_CNT_MAX || hs_ctr < MT_HS_CNT_MIN) {
157 pr_err("** Invalid @nps_mtm_hs_ctr [%d] needs to be [%d:%d] (incl)\n",
158 hs_ctr, MT_HS_CNT_MIN, MT_HS_CNT_MAX);
159 return -EINVAL;
160 }
161
162 mtm_hs_ctr = hs_ctr;
163
164 return 0;
165 }
166 early_param("nps_mtm_hs_ctr", set_mtm_hs_ctr);