root/arch/arc/plat-eznps/mtm.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. do_memory_error
  2. mtm_init_nat
  3. mtm_init_thread
  4. mtm_enable_thread
  5. mtm_enable_core
  6. set_mtm_hs_ctr

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Copyright(c) 2015 EZchip Technologies.
   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         /* Iterate core threads and update nat */
  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         /* Set thread init register */
  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         /* Poll till thread init is done */
  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         /* Enable thread in mtm */
  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          * Initializing dpc register in each CPU.
 108          * Overwriting the init value of the DPC
 109          * register so that CMEM and FMT virtual address
 110          * spaces are accessible, and Data Plane HW
 111          * facilities are enabled.
 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         /* Initialize Number of Active Threads */
 121         mtm_init_nat(cpu);
 122 
 123         /* Initialize mtm_cfg */
 124         mtm_cfg.value = ioread32be(MTM_CFG(cpu));
 125         mtm_cfg.ten = 1;
 126         iowrite32be(mtm_cfg.value, MTM_CFG(cpu));
 127 
 128         /* Initialize all other threads in core */
 129         for (i = 1; i < NPS_NUM_HW_THREADS; i++)
 130                 mtm_init_thread(cpu + i);
 131 
 132 
 133         /* Enable HW schedule, stall counter, mtm */
 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          * HW scheduling mechanism will start working
 142          * Only after call to instruction "schd.rw".
 143          * cpu_relax() calls "schd.rw" instruction.
 144          */
 145         cpu_relax();
 146 }
 147 
 148 /* Verify and set the value of the mtm hs counter */
 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);

/* [<][>][^][v][top][bottom][index][help] */