1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Freescale Embedded oprofile support, based on ppc64 oprofile support 4 * Copyright (C) 2004 Anton Blanchard <anton@au.ibm.com>, IBM 5 * 6 * Copyright (c) 2004, 2010 Freescale Semiconductor, Inc 7 * 8 * Author: Andy Fleming 9 * Maintainer: Kumar Gala <galak@kernel.crashing.org> 10 */ 11 12#include <linux/oprofile.h> 13#include <linux/smp.h> 14#include <asm/ptrace.h> 15#include <asm/processor.h> 16#include <asm/cputable.h> 17#include <asm/reg_fsl_emb.h> 18#include <asm/page.h> 19#include <asm/pmc.h> 20#include <asm/oprofile_impl.h> 21 22static unsigned long reset_value[OP_MAX_COUNTER]; 23 24static int num_counters; 25static int oprofile_running; 26 27static inline u32 get_pmlca(int ctr) 28{ 29 u32 pmlca; 30 31 switch (ctr) { 32 case 0: 33 pmlca = mfpmr(PMRN_PMLCA0); 34 break; 35 case 1: 36 pmlca = mfpmr(PMRN_PMLCA1); 37 break; 38 case 2: 39 pmlca = mfpmr(PMRN_PMLCA2); 40 break; 41 case 3: 42 pmlca = mfpmr(PMRN_PMLCA3); 43 break; 44 case 4: 45 pmlca = mfpmr(PMRN_PMLCA4); 46 break; 47 case 5: 48 pmlca = mfpmr(PMRN_PMLCA5); 49 break; 50 default: 51 panic("Bad ctr number\n"); 52 } 53 54 return pmlca; 55} 56 57static inline void set_pmlca(int ctr, u32 pmlca) 58{ 59 switch (ctr) { 60 case 0: 61 mtpmr(PMRN_PMLCA0, pmlca); 62 break; 63 case 1: 64 mtpmr(PMRN_PMLCA1, pmlca); 65 break; 66 case 2: 67 mtpmr(PMRN_PMLCA2, pmlca); 68 break; 69 case 3: 70 mtpmr(PMRN_PMLCA3, pmlca); 71 break; 72 case 4: 73 mtpmr(PMRN_PMLCA4, pmlca); 74 break; 75 case 5: 76 mtpmr(PMRN_PMLCA5, pmlca); 77 break; 78 default: 79 panic("Bad ctr number\n"); 80 } 81} 82 83static inline unsigned int ctr_read(unsigned int i) 84{ 85 switch(i) { 86 case 0: 87 return mfpmr(PMRN_PMC0); 88 case 1: 89 return mfpmr(PMRN_PMC1); 90 case 2: 91 return mfpmr(PMRN_PMC2); 92 case 3: 93 return mfpmr(PMRN_PMC3); 94 case 4: 95 return mfpmr(PMRN_PMC4); 96 case 5: 97 return mfpmr(PMRN_PMC5); 98 default: 99 return 0; 100 } 101} 102 103static inline void ctr_write(unsigned int i, unsigned int val) 104{ 105 switch(i) { 106 case 0: 107 mtpmr(PMRN_PMC0, val); 108 break; 109 case 1: 110 mtpmr(PMRN_PMC1, val); 111 break; 112 case 2: 113 mtpmr(PMRN_PMC2, val); 114 break; 115 case 3: 116 mtpmr(PMRN_PMC3, val); 117 break; 118 case 4: 119 mtpmr(PMRN_PMC4, val); 120 break; 121 case 5: 122 mtpmr(PMRN_PMC5, val); 123 break; 124 default: 125 break; 126 } 127} 128 129 130static void init_pmc_stop(int ctr) 131{ 132 u32 pmlca = (PMLCA_FC | PMLCA_FCS | PMLCA_FCU | 133 PMLCA_FCM1 | PMLCA_FCM0); 134 u32 pmlcb = 0; 135 136 switch (ctr) { 137 case 0: 138 mtpmr(PMRN_PMLCA0, pmlca); 139 mtpmr(PMRN_PMLCB0, pmlcb); 140 break; 141 case 1: 142 mtpmr(PMRN_PMLCA1, pmlca); 143 mtpmr(PMRN_PMLCB1, pmlcb); 144 break; 145 case 2: 146 mtpmr(PMRN_PMLCA2, pmlca); 147 mtpmr(PMRN_PMLCB2, pmlcb); 148 break; 149 case 3: 150 mtpmr(PMRN_PMLCA3, pmlca); 151 mtpmr(PMRN_PMLCB3, pmlcb); 152 break; 153 case 4: 154 mtpmr(PMRN_PMLCA4, pmlca); 155 mtpmr(PMRN_PMLCB4, pmlcb); 156 break; 157 case 5: 158 mtpmr(PMRN_PMLCA5, pmlca); 159 mtpmr(PMRN_PMLCB5, pmlcb); 160 break; 161 default: 162 panic("Bad ctr number!\n"); 163 } 164} 165 166static void set_pmc_event(int ctr, int event) 167{ 168 u32 pmlca; 169 170 pmlca = get_pmlca(ctr); 171 172 pmlca = (pmlca & ~PMLCA_EVENT_MASK) | 173 ((event << PMLCA_EVENT_SHIFT) & 174 PMLCA_EVENT_MASK); 175 176 set_pmlca(ctr, pmlca); 177} 178 179static void set_pmc_user_kernel(int ctr, int user, int kernel) 180{ 181 u32 pmlca; 182 183 pmlca = get_pmlca(ctr); 184 185 if(user) 186 pmlca &= ~PMLCA_FCU; 187 else 188 pmlca |= PMLCA_FCU; 189 190 if(kernel) 191 pmlca &= ~PMLCA_FCS; 192 else 193 pmlca |= PMLCA_FCS; 194 195 set_pmlca(ctr, pmlca); 196} 197 198static void set_pmc_marked(int ctr, int mark0, int mark1) 199{ 200 u32 pmlca = get_pmlca(ctr); 201 202 if(mark0) 203 pmlca &= ~PMLCA_FCM0; 204 else 205 pmlca |= PMLCA_FCM0; 206 207 if(mark1) 208 pmlca &= ~PMLCA_FCM1; 209 else 210 pmlca |= PMLCA_FCM1; 211 212 set_pmlca(ctr, pmlca); 213} 214 215static void pmc_start_ctr(int ctr, int enable) 216{ 217 u32 pmlca = get_pmlca(ctr); 218 219 pmlca &= ~PMLCA_FC; 220 221 if (enable) 222 pmlca |= PMLCA_CE; 223 else 224 pmlca &= ~PMLCA_CE; 225 226 set_pmlca(ctr, pmlca); 227} 228 229static void pmc_start_ctrs(int enable) 230{ 231 u32 pmgc0 = mfpmr(PMRN_PMGC0); 232 233 pmgc0 &= ~PMGC0_FAC; 234 pmgc0 |= PMGC0_FCECE; 235 236 if (enable) 237 pmgc0 |= PMGC0_PMIE; 238 else 239 pmgc0 &= ~PMGC0_PMIE; 240 241 mtpmr(PMRN_PMGC0, pmgc0); 242} 243 244static void pmc_stop_ctrs(void) 245{ 246 u32 pmgc0 = mfpmr(PMRN_PMGC0); 247 248 pmgc0 |= PMGC0_FAC; 249 250 pmgc0 &= ~(PMGC0_PMIE | PMGC0_FCECE); 251 252 mtpmr(PMRN_PMGC0, pmgc0); 253} 254 255static int fsl_emb_cpu_setup(struct op_counter_config *ctr) 256{ 257 int i; 258 259 /* freeze all counters */ 260 pmc_stop_ctrs(); 261 262 for (i = 0;i < num_counters;i++) { 263 init_pmc_stop(i); 264 265 set_pmc_event(i, ctr[i].event); 266 267 set_pmc_user_kernel(i, ctr[i].user, ctr[i].kernel); 268 } 269 270 return 0; 271} 272 273static int fsl_emb_reg_setup(struct op_counter_config *ctr, 274 struct op_system_config *sys, 275 int num_ctrs) 276{ 277 int i; 278 279 num_counters = num_ctrs; 280 281 /* Our counters count up, and "count" refers to 282 * how much before the next interrupt, and we interrupt 283 * on overflow. So we calculate the starting value 284 * which will give us "count" until overflow. 285 * Then we set the events on the enabled counters */ 286 for (i = 0; i < num_counters; ++i) 287 reset_value[i] = 0x80000000UL - ctr[i].count; 288 289 return 0; 290} 291 292static int fsl_emb_start(struct op_counter_config *ctr) 293{ 294 int i; 295 296 mtmsr(mfmsr() | MSR_PMM); 297 298 for (i = 0; i < num_counters; ++i) { 299 if (ctr[i].enabled) { 300 ctr_write(i, reset_value[i]); 301 /* Set each enabled counter to only 302 * count when the Mark bit is *not* set */ 303 set_pmc_marked(i, 1, 0); 304 pmc_start_ctr(i, 1); 305 } else { 306 ctr_write(i, 0); 307 308 /* Set the ctr to be stopped */ 309 pmc_start_ctr(i, 0); 310 } 311 } 312 313 /* Clear the freeze bit, and enable the interrupt. 314 * The counters won't actually start until the rfi clears 315 * the PMM bit */ 316 pmc_start_ctrs(1); 317 318 oprofile_running = 1; 319 320 pr_debug("start on cpu %d, pmgc0 %x\n", smp_processor_id(), 321 mfpmr(PMRN_PMGC0)); 322 323 return 0; 324} 325 326static void fsl_emb_stop(void) 327{ 328 /* freeze counters */ 329 pmc_stop_ctrs(); 330 331 oprofile_running = 0; 332 333 pr_debug("stop on cpu %d, pmgc0 %x\n", smp_processor_id(), 334 mfpmr(PMRN_PMGC0)); 335 336 mb(); 337} 338 339 340static void fsl_emb_handle_interrupt(struct pt_regs *regs, 341 struct op_counter_config *ctr) 342{ 343 unsigned long pc; 344 int is_kernel; 345 int val; 346 int i; 347 348 pc = regs->nip; 349 is_kernel = is_kernel_addr(pc); 350 351 for (i = 0; i < num_counters; ++i) { 352 val = ctr_read(i); 353 if (val < 0) { 354 if (oprofile_running && ctr[i].enabled) { 355 oprofile_add_ext_sample(pc, regs, i, is_kernel); 356 ctr_write(i, reset_value[i]); 357 } else { 358 ctr_write(i, 0); 359 } 360 } 361 } 362 363 /* The freeze bit was set by the interrupt. */ 364 /* Clear the freeze bit, and reenable the interrupt. The 365 * counters won't actually start until the rfi clears the PMM 366 * bit. The PMM bit should not be set until after the interrupt 367 * is cleared to avoid it getting lost in some hypervisor 368 * environments. 369 */ 370 mtmsr(mfmsr() | MSR_PMM); 371 pmc_start_ctrs(1); 372} 373 374struct op_powerpc_model op_model_fsl_emb = { 375 .reg_setup = fsl_emb_reg_setup, 376 .cpu_setup = fsl_emb_cpu_setup, 377 .start = fsl_emb_start, 378 .stop = fsl_emb_stop, 379 .handle_interrupt = fsl_emb_handle_interrupt, 380}; 381