2 * Copyright(c) 2015 EZchip Technologies.
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * The full GNU General Public License is included in this distribution in
14 * the file called "COPYING".
17 #include <linux/smp.h>
19 #include <linux/log2.h>
20 #include <asm/arcregs.h>
24 #define MT_CTRL_HS_CNT 0xFF
25 #define MT_CTRL_ST_CNT 0xF
26 #define NPS_NUM_HW_THREADS 0x10
28 static void mtm_init_nat(int cpu
)
30 struct nps_host_reg_mtm_cfg mtm_cfg
;
31 struct nps_host_reg_aux_udmc udmc
;
32 int log_nat
, nat
= 0, i
, t
;
34 /* Iterate core threads and update nat */
35 for (i
= 0, t
= cpu
; i
< NPS_NUM_HW_THREADS
; i
++, t
++)
36 nat
+= test_bit(t
, cpumask_bits(cpu_possible_mask
));
40 udmc
.value
= read_aux_reg(CTOP_AUX_UDMC
);
42 write_aux_reg(CTOP_AUX_UDMC
, udmc
.value
);
44 mtm_cfg
.value
= ioread32be(MTM_CFG(cpu
));
45 mtm_cfg
.nat
= log_nat
;
46 iowrite32be(mtm_cfg
.value
, MTM_CFG(cpu
));
49 static void mtm_init_thread(int cpu
)
52 struct nps_host_reg_thr_init thr_init
;
53 struct nps_host_reg_thr_init_sts thr_init_sts
;
55 /* Set thread init register */
57 iowrite32be(thr_init
.value
, MTM_THR_INIT(cpu
));
58 thr_init
.thr_id
= NPS_CPU_TO_THREAD_NUM(cpu
);
60 iowrite32be(thr_init
.value
, MTM_THR_INIT(cpu
));
62 /* Poll till thread init is done */
63 for (i
= 0; i
< tries
; i
++) {
64 thr_init_sts
.value
= ioread32be(MTM_THR_INIT_STS(cpu
));
65 if (thr_init_sts
.thr_id
== thr_init
.thr_id
) {
68 else if (thr_init_sts
.err
)
69 pr_warn("Failed to thread init cpu %u\n", cpu
);
73 pr_warn("Wrong thread id in thread init for cpu %u\n", cpu
);
78 pr_warn("Got thread init timeout for cpu %u\n", cpu
);
81 int mtm_enable_thread(int cpu
)
83 struct nps_host_reg_mtm_cfg mtm_cfg
;
85 if (NPS_CPU_TO_THREAD_NUM(cpu
) == 0)
88 /* Enable thread in mtm */
89 mtm_cfg
.value
= ioread32be(MTM_CFG(cpu
));
90 mtm_cfg
.ten
|= (1 << (NPS_CPU_TO_THREAD_NUM(cpu
)));
91 iowrite32be(mtm_cfg
.value
, MTM_CFG(cpu
));
96 void mtm_enable_core(unsigned int cpu
)
99 struct nps_host_reg_aux_mt_ctrl mt_ctrl
;
100 struct nps_host_reg_mtm_cfg mtm_cfg
;
102 if (NPS_CPU_TO_THREAD_NUM(cpu
) != 0)
105 /* Initialize Number of Active Threads */
108 /* Initialize mtm_cfg */
109 mtm_cfg
.value
= ioread32be(MTM_CFG(cpu
));
111 iowrite32be(mtm_cfg
.value
, MTM_CFG(cpu
));
113 /* Initialize all other threads in core */
114 for (i
= 1; i
< NPS_NUM_HW_THREADS
; i
++)
115 mtm_init_thread(cpu
+ i
);
118 /* Enable HW schedule, stall counter, mtm */
121 mt_ctrl
.hs_cnt
= MT_CTRL_HS_CNT
;
123 mt_ctrl
.st_cnt
= MT_CTRL_ST_CNT
;
125 write_aux_reg(CTOP_AUX_MT_CTRL
, mt_ctrl
.value
);
128 * HW scheduling mechanism will start working
129 * Only after call to instruction "schd.rw".
130 * cpu_relax() calls "schd.rw" instruction.