diff options
Diffstat (limited to 'drivers/gator/driver/gator_events_scorpion.c')
-rw-r--r-- | drivers/gator/driver/gator_events_scorpion.c | 678 |
1 files changed, 0 insertions, 678 deletions
diff --git a/drivers/gator/driver/gator_events_scorpion.c b/drivers/gator/driver/gator_events_scorpion.c deleted file mode 100644 index 477e7c98948..00000000000 --- a/drivers/gator/driver/gator_events_scorpion.c +++ /dev/null @@ -1,678 +0,0 @@ -/** - * Copyright (C) ARM Limited 2011-2012. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include "gator.h" - -// gator_events_perf_pmu.c is used if perf is supported -#if GATOR_NO_PERF_SUPPORT - -static const char *pmnc_name; -static int pmnc_counters; - -// Per-CPU PMNC: config reg -#define PMNC_E (1 << 0) /* Enable all counters */ -#define PMNC_P (1 << 1) /* Reset all counters */ -#define PMNC_C (1 << 2) /* Cycle counter reset */ -#define PMNC_D (1 << 3) /* CCNT counts every 64th cpu cycle */ -#define PMNC_X (1 << 4) /* Export to ETM */ -#define PMNC_DP (1 << 5) /* Disable CCNT if non-invasive debug*/ -#define PMNC_MASK 0x3f /* Mask for writable bits */ - -// ccnt reg -#define CCNT_REG (1 << 31) - -#define CCNT 0 -#define CNT0 1 -#define CNTMAX (4+1) - -static unsigned long pmnc_enabled[CNTMAX]; -static unsigned long pmnc_event[CNTMAX]; -static unsigned long pmnc_key[CNTMAX]; - -static DEFINE_PER_CPU(int[CNTMAX], perfPrev); -static DEFINE_PER_CPU(int[CNTMAX * 2], perfCnt); - -enum scorpion_perf_types { - SCORPION_ICACHE_EXPL_INV = 0x4c, - SCORPION_ICACHE_MISS = 0x4d, - SCORPION_ICACHE_ACCESS = 0x4e, - SCORPION_ICACHE_CACHEREQ_L2 = 0x4f, - SCORPION_ICACHE_NOCACHE_L2 = 0x50, - SCORPION_HIQUP_NOPED = 0x51, - SCORPION_DATA_ABORT = 0x52, - SCORPION_IRQ = 0x53, - SCORPION_FIQ = 0x54, - SCORPION_ALL_EXCPT = 0x55, - SCORPION_UNDEF = 0x56, - SCORPION_SVC = 0x57, - SCORPION_SMC = 0x58, - SCORPION_PREFETCH_ABORT = 0x59, - SCORPION_INDEX_CHECK = 0x5a, - SCORPION_NULL_CHECK = 0x5b, - SCORPION_EXPL_ICIALLU = 0x5c, - SCORPION_IMPL_ICIALLU = 0x5d, - SCORPION_NONICIALLU_BTAC_INV = 0x5e, - SCORPION_ICIMVAU_IMPL_ICIALLU = 0x5f, - SCORPION_SPIPE_ONLY_CYCLES = 0x60, - SCORPION_XPIPE_ONLY_CYCLES = 0x61, - SCORPION_DUAL_CYCLES = 0x62, - SCORPION_DISPATCH_ANY_CYCLES = 0x63, - SCORPION_FIFO_FULLBLK_CMT = 0x64, - SCORPION_FAIL_COND_INST = 0x65, - SCORPION_PASS_COND_INST = 0x66, - SCORPION_ALLOW_VU_CLK = 0x67, - SCORPION_VU_IDLE = 0x68, - SCORPION_ALLOW_L2_CLK = 0x69, - SCORPION_L2_IDLE = 0x6a, - SCORPION_DTLB_IMPL_INV_SCTLR_DACR = 0x6b, - SCORPION_DTLB_EXPL_INV = 0x6c, - SCORPION_DTLB_MISS = 0x6d, - SCORPION_DTLB_ACCESS = 0x6e, - SCORPION_ITLB_MISS = 0x6f, - SCORPION_ITLB_IMPL_INV = 0x70, - SCORPION_ITLB_EXPL_INV = 0x71, - SCORPION_UTLB_D_MISS = 0x72, - SCORPION_UTLB_D_ACCESS = 0x73, - SCORPION_UTLB_I_MISS = 0x74, - SCORPION_UTLB_I_ACCESS = 0x75, - SCORPION_UTLB_INV_ASID = 0x76, - SCORPION_UTLB_INV_MVA = 0x77, - SCORPION_UTLB_INV_ALL = 0x78, - SCORPION_S2_HOLD_RDQ_UNAVAIL = 0x79, - SCORPION_S2_HOLD = 0x7a, - SCORPION_S2_HOLD_DEV_OP = 0x7b, - SCORPION_S2_HOLD_ORDER = 0x7c, - SCORPION_S2_HOLD_BARRIER = 0x7d, - SCORPION_VIU_DUAL_CYCLE = 0x7e, - SCORPION_VIU_SINGLE_CYCLE = 0x7f, - SCORPION_VX_PIPE_WAR_STALL_CYCLES = 0x80, - SCORPION_VX_PIPE_WAW_STALL_CYCLES = 0x81, - SCORPION_VX_PIPE_RAW_STALL_CYCLES = 0x82, - SCORPION_VX_PIPE_LOAD_USE_STALL = 0x83, - SCORPION_VS_PIPE_WAR_STALL_CYCLES = 0x84, - SCORPION_VS_PIPE_WAW_STALL_CYCLES = 0x85, - SCORPION_VS_PIPE_RAW_STALL_CYCLES = 0x86, - SCORPION_EXCEPTIONS_INV_OPERATION = 0x87, - SCORPION_EXCEPTIONS_DIV_BY_ZERO = 0x88, - SCORPION_COND_INST_FAIL_VX_PIPE = 0x89, - SCORPION_COND_INST_FAIL_VS_PIPE = 0x8a, - SCORPION_EXCEPTIONS_OVERFLOW = 0x8b, - SCORPION_EXCEPTIONS_UNDERFLOW = 0x8c, - SCORPION_EXCEPTIONS_DENORM = 0x8d, -#ifdef CONFIG_ARCH_MSM_SCORPIONMP - SCORPIONMP_NUM_BARRIERS = 0x8e, - SCORPIONMP_BARRIER_CYCLES = 0x8f, -#else - SCORPION_BANK_AB_HIT = 0x8e, - SCORPION_BANK_AB_ACCESS = 0x8f, - SCORPION_BANK_CD_HIT = 0x90, - SCORPION_BANK_CD_ACCESS = 0x91, - SCORPION_BANK_AB_DSIDE_HIT = 0x92, - SCORPION_BANK_AB_DSIDE_ACCESS = 0x93, - SCORPION_BANK_CD_DSIDE_HIT = 0x94, - SCORPION_BANK_CD_DSIDE_ACCESS = 0x95, - SCORPION_BANK_AB_ISIDE_HIT = 0x96, - SCORPION_BANK_AB_ISIDE_ACCESS = 0x97, - SCORPION_BANK_CD_ISIDE_HIT = 0x98, - SCORPION_BANK_CD_ISIDE_ACCESS = 0x99, - SCORPION_ISIDE_RD_WAIT = 0x9a, - SCORPION_DSIDE_RD_WAIT = 0x9b, - SCORPION_BANK_BYPASS_WRITE = 0x9c, - SCORPION_BANK_AB_NON_CASTOUT = 0x9d, - SCORPION_BANK_AB_L2_CASTOUT = 0x9e, - SCORPION_BANK_CD_NON_CASTOUT = 0x9f, - SCORPION_BANK_CD_L2_CASTOUT = 0xa0, -#endif - MSM_MAX_EVT -}; - -struct scorp_evt { - u32 evt_type; - u32 val; - u8 grp; - u32 evt_type_act; -}; - -static const struct scorp_evt sc_evt[] = { - {SCORPION_ICACHE_EXPL_INV, 0x80000500, 0, 0x4d}, - {SCORPION_ICACHE_MISS, 0x80050000, 0, 0x4e}, - {SCORPION_ICACHE_ACCESS, 0x85000000, 0, 0x4f}, - {SCORPION_ICACHE_CACHEREQ_L2, 0x86000000, 0, 0x4f}, - {SCORPION_ICACHE_NOCACHE_L2, 0x87000000, 0, 0x4f}, - {SCORPION_HIQUP_NOPED, 0x80080000, 0, 0x4e}, - {SCORPION_DATA_ABORT, 0x8000000a, 0, 0x4c}, - {SCORPION_IRQ, 0x80000a00, 0, 0x4d}, - {SCORPION_FIQ, 0x800a0000, 0, 0x4e}, - {SCORPION_ALL_EXCPT, 0x8a000000, 0, 0x4f}, - {SCORPION_UNDEF, 0x8000000b, 0, 0x4c}, - {SCORPION_SVC, 0x80000b00, 0, 0x4d}, - {SCORPION_SMC, 0x800b0000, 0, 0x4e}, - {SCORPION_PREFETCH_ABORT, 0x8b000000, 0, 0x4f}, - {SCORPION_INDEX_CHECK, 0x8000000c, 0, 0x4c}, - {SCORPION_NULL_CHECK, 0x80000c00, 0, 0x4d}, - {SCORPION_EXPL_ICIALLU, 0x8000000d, 0, 0x4c}, - {SCORPION_IMPL_ICIALLU, 0x80000d00, 0, 0x4d}, - {SCORPION_NONICIALLU_BTAC_INV, 0x800d0000, 0, 0x4e}, - {SCORPION_ICIMVAU_IMPL_ICIALLU, 0x8d000000, 0, 0x4f}, - - {SCORPION_SPIPE_ONLY_CYCLES, 0x80000600, 1, 0x51}, - {SCORPION_XPIPE_ONLY_CYCLES, 0x80060000, 1, 0x52}, - {SCORPION_DUAL_CYCLES, 0x86000000, 1, 0x53}, - {SCORPION_DISPATCH_ANY_CYCLES, 0x89000000, 1, 0x53}, - {SCORPION_FIFO_FULLBLK_CMT, 0x8000000d, 1, 0x50}, - {SCORPION_FAIL_COND_INST, 0x800d0000, 1, 0x52}, - {SCORPION_PASS_COND_INST, 0x8d000000, 1, 0x53}, - {SCORPION_ALLOW_VU_CLK, 0x8000000e, 1, 0x50}, - {SCORPION_VU_IDLE, 0x80000e00, 1, 0x51}, - {SCORPION_ALLOW_L2_CLK, 0x800e0000, 1, 0x52}, - {SCORPION_L2_IDLE, 0x8e000000, 1, 0x53}, - - {SCORPION_DTLB_IMPL_INV_SCTLR_DACR, 0x80000001, 2, 0x54}, - {SCORPION_DTLB_EXPL_INV, 0x80000100, 2, 0x55}, - {SCORPION_DTLB_MISS, 0x80010000, 2, 0x56}, - {SCORPION_DTLB_ACCESS, 0x81000000, 2, 0x57}, - {SCORPION_ITLB_MISS, 0x80000200, 2, 0x55}, - {SCORPION_ITLB_IMPL_INV, 0x80020000, 2, 0x56}, - {SCORPION_ITLB_EXPL_INV, 0x82000000, 2, 0x57}, - {SCORPION_UTLB_D_MISS, 0x80000003, 2, 0x54}, - {SCORPION_UTLB_D_ACCESS, 0x80000300, 2, 0x55}, - {SCORPION_UTLB_I_MISS, 0x80030000, 2, 0x56}, - {SCORPION_UTLB_I_ACCESS, 0x83000000, 2, 0x57}, - {SCORPION_UTLB_INV_ASID, 0x80000400, 2, 0x55}, - {SCORPION_UTLB_INV_MVA, 0x80040000, 2, 0x56}, - {SCORPION_UTLB_INV_ALL, 0x84000000, 2, 0x57}, - {SCORPION_S2_HOLD_RDQ_UNAVAIL, 0x80000800, 2, 0x55}, - {SCORPION_S2_HOLD, 0x88000000, 2, 0x57}, - {SCORPION_S2_HOLD_DEV_OP, 0x80000900, 2, 0x55}, - {SCORPION_S2_HOLD_ORDER, 0x80090000, 2, 0x56}, - {SCORPION_S2_HOLD_BARRIER, 0x89000000, 2, 0x57}, - - {SCORPION_VIU_DUAL_CYCLE, 0x80000001, 4, 0x5c}, - {SCORPION_VIU_SINGLE_CYCLE, 0x80000100, 4, 0x5d}, - {SCORPION_VX_PIPE_WAR_STALL_CYCLES, 0x80000005, 4, 0x5c}, - {SCORPION_VX_PIPE_WAW_STALL_CYCLES, 0x80000500, 4, 0x5d}, - {SCORPION_VX_PIPE_RAW_STALL_CYCLES, 0x80050000, 4, 0x5e}, - {SCORPION_VX_PIPE_LOAD_USE_STALL, 0x80000007, 4, 0x5c}, - {SCORPION_VS_PIPE_WAR_STALL_CYCLES, 0x80000008, 4, 0x5c}, - {SCORPION_VS_PIPE_WAW_STALL_CYCLES, 0x80000800, 4, 0x5d}, - {SCORPION_VS_PIPE_RAW_STALL_CYCLES, 0x80080000, 4, 0x5e}, - {SCORPION_EXCEPTIONS_INV_OPERATION, 0x8000000b, 4, 0x5c}, - {SCORPION_EXCEPTIONS_DIV_BY_ZERO, 0x80000b00, 4, 0x5d}, - {SCORPION_COND_INST_FAIL_VX_PIPE, 0x800b0000, 4, 0x5e}, - {SCORPION_COND_INST_FAIL_VS_PIPE, 0x8b000000, 4, 0x5f}, - {SCORPION_EXCEPTIONS_OVERFLOW, 0x8000000c, 4, 0x5c}, - {SCORPION_EXCEPTIONS_UNDERFLOW, 0x80000c00, 4, 0x5d}, - {SCORPION_EXCEPTIONS_DENORM, 0x8c000000, 4, 0x5f}, - -#ifdef CONFIG_ARCH_MSM_SCORPIONMP - {SCORPIONMP_NUM_BARRIERS, 0x80000e00, 3, 0x59}, - {SCORPIONMP_BARRIER_CYCLES, 0x800e0000, 3, 0x5a}, -#else - {SCORPION_BANK_AB_HIT, 0x80000001, 3, 0x58}, - {SCORPION_BANK_AB_ACCESS, 0x80000100, 3, 0x59}, - {SCORPION_BANK_CD_HIT, 0x80010000, 3, 0x5a}, - {SCORPION_BANK_CD_ACCESS, 0x81000000, 3, 0x5b}, - {SCORPION_BANK_AB_DSIDE_HIT, 0x80000002, 3, 0x58}, - {SCORPION_BANK_AB_DSIDE_ACCESS, 0x80000200, 3, 0x59}, - {SCORPION_BANK_CD_DSIDE_HIT, 0x80020000, 3, 0x5a}, - {SCORPION_BANK_CD_DSIDE_ACCESS, 0x82000000, 3, 0x5b}, - {SCORPION_BANK_AB_ISIDE_HIT, 0x80000003, 3, 0x58}, - {SCORPION_BANK_AB_ISIDE_ACCESS, 0x80000300, 3, 0x59}, - {SCORPION_BANK_CD_ISIDE_HIT, 0x80030000, 3, 0x5a}, - {SCORPION_BANK_CD_ISIDE_ACCESS, 0x83000000, 3, 0x5b}, - {SCORPION_ISIDE_RD_WAIT, 0x80000009, 3, 0x58}, - {SCORPION_DSIDE_RD_WAIT, 0x80090000, 3, 0x5a}, - {SCORPION_BANK_BYPASS_WRITE, 0x8000000a, 3, 0x58}, - {SCORPION_BANK_AB_NON_CASTOUT, 0x8000000c, 3, 0x58}, - {SCORPION_BANK_AB_L2_CASTOUT, 0x80000c00, 3, 0x59}, - {SCORPION_BANK_CD_NON_CASTOUT, 0x800c0000, 3, 0x5a}, - {SCORPION_BANK_CD_L2_CASTOUT, 0x8c000000, 3, 0x5b}, -#endif -}; - -static inline void scorpion_pmnc_write(u32 val) -{ - val &= PMNC_MASK; - asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r" (val)); -} - -static inline u32 scorpion_pmnc_read(void) -{ - u32 val; - asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r" (val)); - return val; -} - -static inline u32 scorpion_ccnt_read(void) -{ - u32 val; - asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (val)); - return val; -} - -static inline u32 scorpion_cntn_read(void) -{ - u32 val; - asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (val)); - return val; -} - -static inline u32 scorpion_pmnc_enable_counter(unsigned int cnt) -{ - u32 val; - - if (cnt >= CNTMAX) { - pr_err("gator: CPU%u enabling wrong PMNC counter %d\n", smp_processor_id(), cnt); - return -1; - } - - if (cnt == CCNT) - val = CCNT_REG; - else - val = (1 << (cnt - CNT0)); - - asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (val)); - - return cnt; -} - -static inline u32 scorpion_pmnc_disable_counter(unsigned int cnt) -{ - u32 val; - - if (cnt >= CNTMAX) { - pr_err("gator: CPU%u disabling wrong PMNC counter %d\n", smp_processor_id(), cnt); - return -1; - } - - if (cnt == CCNT) - val = CCNT_REG; - else - val = (1 << (cnt - CNT0)); - - asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (val)); - - return cnt; -} - -static inline int scorpion_pmnc_select_counter(unsigned int cnt) -{ - u32 val; - - if ((cnt == CCNT) || (cnt >= CNTMAX)) { - pr_err("gator: CPU%u selecting wrong PMNC counter %d\n", smp_processor_id(), cnt); - return -1; - } - - val = (cnt - CNT0); - asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (val)); - - return cnt; -} - -static u32 scorpion_read_lpm0(void) -{ - u32 val; - asm volatile("mrc p15, 0, %0, c15, c0, 0" : "=r" (val)); - return val; -} - -static void scorpion_write_lpm0(u32 val) -{ - asm volatile("mcr p15, 0, %0, c15, c0, 0" : : "r" (val)); -} - -static u32 scorpion_read_lpm1(void) -{ - u32 val; - asm volatile("mrc p15, 1, %0, c15, c0, 0" : "=r" (val)); - return val; -} - -static void scorpion_write_lpm1(u32 val) -{ - asm volatile("mcr p15, 1, %0, c15, c0, 0" : : "r" (val)); -} - -static u32 scorpion_read_lpm2(void) -{ - u32 val; - asm volatile("mrc p15, 2, %0, c15, c0, 0" : "=r" (val)); - return val; -} - -static void scorpion_write_lpm2(u32 val) -{ - asm volatile("mcr p15, 2, %0, c15, c0, 0" : : "r" (val)); -} - -static u32 scorpion_read_l2lpm(void) -{ - u32 val; - asm volatile("mrc p15, 3, %0, c15, c2, 0" : "=r" (val)); - return val; -} - -static void scorpion_write_l2lpm(u32 val) -{ - asm volatile("mcr p15, 3, %0, c15, c2, 0" : : "r" (val)); -} - -static u32 scorpion_read_vlpm(void) -{ - u32 val; - asm volatile("mrc p10, 7, %0, c11, c0, 0" : "=r" (val)); - return val; -} - -static void scorpion_write_vlpm(u32 val) -{ - asm volatile("mcr p10, 7, %0, c11, c0, 0" : : "r" (val)); -} - -struct scorpion_access_funcs { - u32 (*read) (void); - void (*write) (u32); -}; - -struct scorpion_access_funcs scor_func[] = { - {scorpion_read_lpm0, scorpion_write_lpm0}, - {scorpion_read_lpm1, scorpion_write_lpm1}, - {scorpion_read_lpm2, scorpion_write_lpm2}, - {scorpion_read_l2lpm, scorpion_write_l2lpm}, - {scorpion_read_vlpm, scorpion_write_vlpm}, -}; - -u32 venum_orig_val; -u32 fp_orig_val; - -static void scorpion_pre_vlpm(void) -{ - u32 venum_new_val; - u32 fp_new_val; - - /* CPACR Enable CP10 access*/ - asm volatile("mrc p15, 0, %0, c1, c0, 2" : "=r" (venum_orig_val)); - venum_new_val = venum_orig_val | 0x00300000; - asm volatile("mcr p15, 0, %0, c1, c0, 2" : : "r" (venum_new_val)); - /* Enable FPEXC */ - asm volatile("mrc p10, 7, %0, c8, c0, 0" : "=r" (fp_orig_val)); - fp_new_val = fp_orig_val | 0x40000000; - asm volatile("mcr p10, 7, %0, c8, c0, 0" : : "r" (fp_new_val)); -} - -static void scorpion_post_vlpm(void) -{ - /* Restore FPEXC*/ - asm volatile("mcr p10, 7, %0, c8, c0, 0" : : "r" (fp_orig_val)); - /* Restore CPACR*/ - asm volatile("mcr p15, 0, %0, c1, c0, 2" : : "r" (venum_orig_val)); -} - -#define COLMN0MASK 0x000000ff -#define COLMN1MASK 0x0000ff00 -#define COLMN2MASK 0x00ff0000 -static u32 scorpion_get_columnmask(u32 setval) -{ - if (setval & COLMN0MASK) - return 0xffffff00; - else if (setval & COLMN1MASK) - return 0xffff00ff; - else if (setval & COLMN2MASK) - return 0xff00ffff; - else - return 0x80ffffff; -} - -static void scorpion_evt_setup(u32 gr, u32 setval) -{ - u32 val; - if (gr == 4) - scorpion_pre_vlpm(); - val = scorpion_get_columnmask(setval) & scor_func[gr].read(); - val = val | setval; - scor_func[gr].write(val); - if (gr == 4) - scorpion_post_vlpm(); -} - -static int get_scorpion_evtinfo(unsigned int evt_type, struct scorp_evt *evtinfo) -{ - u32 idx; - if ((evt_type < 0x4c) || (evt_type >= MSM_MAX_EVT)) - return 0; - idx = evt_type - 0x4c; - if (sc_evt[idx].evt_type == evt_type) { - evtinfo->val = sc_evt[idx].val; - evtinfo->grp = sc_evt[idx].grp; - evtinfo->evt_type_act = sc_evt[idx].evt_type_act; - return 1; - } - return 0; -} - -static inline void scorpion_pmnc_write_evtsel(unsigned int cnt, u32 val) -{ - if (scorpion_pmnc_select_counter(cnt) == cnt) { - if (val < 0x40) { - asm volatile("mcr p15, 0, %0, c9, c13, 1" : : "r" (val)); - } else { - u32 zero = 0; - struct scorp_evt evtinfo; - // extract evtinfo.grp and evtinfo.tevt_type_act from val - if (get_scorpion_evtinfo(val, &evtinfo) == 0) return; - asm volatile("mcr p15, 0, %0, c9, c13, 1" : : "r" (evtinfo.evt_type_act)); - asm volatile("mcr p15, 0, %0, c9, c15, 0" : : "r" (zero)); - scorpion_evt_setup(evtinfo.grp, val); - } - } -} - -static void scorpion_pmnc_reset_counter(unsigned int cnt) -{ - u32 val = 0; - - if (cnt == CCNT) { - scorpion_pmnc_disable_counter(cnt); - - asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" (val)); - - if (pmnc_enabled[cnt] != 0) - scorpion_pmnc_enable_counter(cnt); - - } else if (cnt >= CNTMAX) { - pr_err("gator: CPU%u resetting wrong PMNC counter %d\n", smp_processor_id(), cnt); - } else { - scorpion_pmnc_disable_counter(cnt); - - if (scorpion_pmnc_select_counter(cnt) == cnt) - asm volatile("mcr p15, 0, %0, c9, c13, 2" : : "r" (val)); - - if (pmnc_enabled[cnt] != 0) - scorpion_pmnc_enable_counter(cnt); - } -} - -static int gator_events_scorpion_create_files(struct super_block *sb, struct dentry *root) -{ - struct dentry *dir; - int i; - - for (i = 0; i < pmnc_counters; i++) { - char buf[40]; - if (i == 0) { - snprintf(buf, sizeof buf, "%s_ccnt", pmnc_name); - } else { - snprintf(buf, sizeof buf, "%s_cnt%d", pmnc_name, i-1); - } - dir = gatorfs_mkdir(sb, root, buf); - if (!dir) { - return -1; - } - gatorfs_create_ulong(sb, dir, "enabled", &pmnc_enabled[i]); - gatorfs_create_ro_ulong(sb, dir, "key", &pmnc_key[i]); - if (i > 0) { - gatorfs_create_ulong(sb, dir, "event", &pmnc_event[i]); - } - } - - return 0; -} - -static int gator_events_scorpion_online(int** buffer) -{ - unsigned int cnt, len = 0, cpu = smp_processor_id(); - - if (scorpion_pmnc_read() & PMNC_E) { - scorpion_pmnc_write(scorpion_pmnc_read() & ~PMNC_E); - } - - /* Initialize & Reset PMNC: C bit and P bit */ - scorpion_pmnc_write(PMNC_P | PMNC_C); - - for (cnt = CCNT; cnt < CNTMAX; cnt++) { - unsigned long event; - - per_cpu(perfPrev, smp_processor_id())[cnt] = 0; - - if (!pmnc_enabled[cnt]) - continue; - - // disable counter - scorpion_pmnc_disable_counter(cnt); - - event = pmnc_event[cnt] & 255; - - // Set event (if destined for PMNx counters), We don't need to set the event if it's a cycle count - if (cnt != CCNT) - scorpion_pmnc_write_evtsel(cnt, event); - - // reset counter - scorpion_pmnc_reset_counter(cnt); - - // Enable counter, do not enable interrupt for this counter - scorpion_pmnc_enable_counter(cnt); - } - - // enable - scorpion_pmnc_write(scorpion_pmnc_read() | PMNC_E); - - // read the counters and toss the invalid data, return zero instead - for (cnt = 0; cnt < pmnc_counters; cnt++) { - if (pmnc_enabled[cnt]) { - int value; - if (cnt == CCNT) { - value = scorpion_ccnt_read(); - } else if (scorpion_pmnc_select_counter(cnt) == cnt) { - value = scorpion_cntn_read(); - } else { - value = 0; - } - scorpion_pmnc_reset_counter(cnt); - per_cpu(perfPrev, cpu)[cnt] = 0; - per_cpu(perfCnt, cpu)[len++] = pmnc_key[cnt]; - per_cpu(perfCnt, cpu)[len++] = 0; - } - } - - if (buffer) - *buffer = per_cpu(perfCnt, cpu); - - return len; -} - -static int gator_events_scorpion_offline(int** buffer) -{ - scorpion_pmnc_write(scorpion_pmnc_read() & ~PMNC_E); - return 0; -} - -static void gator_events_scorpion_stop(void) -{ - unsigned int cnt; - - for (cnt = CCNT; cnt < CNTMAX; cnt++) { - pmnc_enabled[cnt] = 0; - pmnc_event[cnt] = 0; - } -} - -static int gator_events_scorpion_read(int **buffer) -{ - int cnt, len = 0; - int cpu = smp_processor_id(); - - for (cnt = 0; cnt < pmnc_counters; cnt++) { - if (pmnc_enabled[cnt]) { - int value; - if (cnt == CCNT) { - value = scorpion_ccnt_read(); - } else if (scorpion_pmnc_select_counter(cnt) == cnt) { - value = scorpion_cntn_read(); - } else { - value = 0; - } - scorpion_pmnc_reset_counter(cnt); - if (value != per_cpu(perfPrev, cpu)[cnt]) { - per_cpu(perfPrev, cpu)[cnt] = value; - per_cpu(perfCnt, cpu)[len++] = pmnc_key[cnt]; - per_cpu(perfCnt, cpu)[len++] = value; - } - } - } - - if (buffer) - *buffer = per_cpu(perfCnt, cpu); - - return len; -} - -static struct gator_interface gator_events_scorpion_interface = { - .create_files = gator_events_scorpion_create_files, - .stop = gator_events_scorpion_stop, - .online = gator_events_scorpion_online, - .offline = gator_events_scorpion_offline, - .read = gator_events_scorpion_read, -}; - -int gator_events_scorpion_init(void) -{ - unsigned int cnt; - - switch (gator_cpuid()) { - case SCORPION: - pmnc_name = "Scorpion"; - pmnc_counters = 4; - break; - case SCORPIONMP: - pmnc_name = "ScorpionMP"; - pmnc_counters = 4; - break; - default: - return -1; - } - - pmnc_counters++; // CNT[n] + CCNT - - for (cnt = CCNT; cnt < CNTMAX; cnt++) { - pmnc_enabled[cnt] = 0; - pmnc_event[cnt] = 0; - pmnc_key[cnt] = gator_events_get_key(); - } - - return gator_events_install(&gator_events_scorpion_interface); -} - -gator_events_init(gator_events_scorpion_init); - -#else -int gator_events_scorpion_init(void) -{ - return -1; -} -#endif |