12874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later 27ffd948fSMadhavan Srinivasan /* 37ffd948fSMadhavan Srinivasan * Common Performance counter support functions for PowerISA v2.07 processors. 47ffd948fSMadhavan Srinivasan * 57ffd948fSMadhavan Srinivasan * Copyright 2009 Paul Mackerras, IBM Corporation. 67ffd948fSMadhavan Srinivasan * Copyright 2013 Michael Ellerman, IBM Corporation. 77ffd948fSMadhavan Srinivasan * Copyright 2016 Madhavan Srinivasan, IBM Corporation. 87ffd948fSMadhavan Srinivasan */ 97ffd948fSMadhavan Srinivasan #include "isa207-common.h" 107ffd948fSMadhavan Srinivasan 1160b00025SMadhavan Srinivasan PMU_FORMAT_ATTR(event, "config:0-49"); 1260b00025SMadhavan Srinivasan PMU_FORMAT_ATTR(pmcxsel, "config:0-7"); 1360b00025SMadhavan Srinivasan PMU_FORMAT_ATTR(mark, "config:8"); 1460b00025SMadhavan Srinivasan PMU_FORMAT_ATTR(combine, "config:11"); 1560b00025SMadhavan Srinivasan PMU_FORMAT_ATTR(unit, "config:12-15"); 1660b00025SMadhavan Srinivasan PMU_FORMAT_ATTR(pmc, "config:16-19"); 1760b00025SMadhavan Srinivasan PMU_FORMAT_ATTR(cache_sel, "config:20-23"); 1860b00025SMadhavan Srinivasan PMU_FORMAT_ATTR(sample_mode, "config:24-28"); 1960b00025SMadhavan Srinivasan PMU_FORMAT_ATTR(thresh_sel, "config:29-31"); 2060b00025SMadhavan Srinivasan PMU_FORMAT_ATTR(thresh_stop, "config:32-35"); 2160b00025SMadhavan Srinivasan PMU_FORMAT_ATTR(thresh_start, "config:36-39"); 2260b00025SMadhavan Srinivasan PMU_FORMAT_ATTR(thresh_cmp, "config:40-49"); 2360b00025SMadhavan Srinivasan 24107dadb0SBixuan Cui static struct attribute *isa207_pmu_format_attr[] = { 2560b00025SMadhavan Srinivasan &format_attr_event.attr, 2660b00025SMadhavan Srinivasan &format_attr_pmcxsel.attr, 2760b00025SMadhavan Srinivasan &format_attr_mark.attr, 2860b00025SMadhavan Srinivasan &format_attr_combine.attr, 2960b00025SMadhavan Srinivasan &format_attr_unit.attr, 3060b00025SMadhavan Srinivasan &format_attr_pmc.attr, 3160b00025SMadhavan Srinivasan &format_attr_cache_sel.attr, 3260b00025SMadhavan Srinivasan &format_attr_sample_mode.attr, 3360b00025SMadhavan Srinivasan &format_attr_thresh_sel.attr, 3460b00025SMadhavan Srinivasan &format_attr_thresh_stop.attr, 3560b00025SMadhavan Srinivasan &format_attr_thresh_start.attr, 3660b00025SMadhavan Srinivasan &format_attr_thresh_cmp.attr, 3760b00025SMadhavan Srinivasan NULL, 3860b00025SMadhavan Srinivasan }; 3960b00025SMadhavan Srinivasan 4060b00025SMadhavan Srinivasan struct attribute_group isa207_pmu_format_group = { 4160b00025SMadhavan Srinivasan .name = "format", 4260b00025SMadhavan Srinivasan .attrs = isa207_pmu_format_attr, 4360b00025SMadhavan Srinivasan }; 4460b00025SMadhavan Srinivasan 457ffd948fSMadhavan Srinivasan static inline bool event_is_fab_match(u64 event) 467ffd948fSMadhavan Srinivasan { 477ffd948fSMadhavan Srinivasan /* Only check pmc, unit and pmcxsel, ignore the edge bit (0) */ 487ffd948fSMadhavan Srinivasan event &= 0xff0fe; 497ffd948fSMadhavan Srinivasan 507ffd948fSMadhavan Srinivasan /* PM_MRK_FAB_RSP_MATCH & PM_MRK_FAB_RSP_MATCH_CYC */ 517ffd948fSMadhavan Srinivasan return (event == 0x30056 || event == 0x4f052); 527ffd948fSMadhavan Srinivasan } 537ffd948fSMadhavan Srinivasan 54c7c3f568SMadhavan Srinivasan static bool is_event_valid(u64 event) 55c7c3f568SMadhavan Srinivasan { 56c7c3f568SMadhavan Srinivasan u64 valid_mask = EVENT_VALID_MASK; 57c7c3f568SMadhavan Srinivasan 58a64e697cSAthira Rajeev if (cpu_has_feature(CPU_FTR_ARCH_31)) 59a64e697cSAthira Rajeev valid_mask = p10_EVENT_VALID_MASK; 60a64e697cSAthira Rajeev else if (cpu_has_feature(CPU_FTR_ARCH_300)) 61c7c3f568SMadhavan Srinivasan valid_mask = p9_EVENT_VALID_MASK; 62c7c3f568SMadhavan Srinivasan 63c7c3f568SMadhavan Srinivasan return !(event & ~valid_mask); 64c7c3f568SMadhavan Srinivasan } 65c7c3f568SMadhavan Srinivasan 6678b4416aSMadhavan Srinivasan static inline bool is_event_marked(u64 event) 67c7c3f568SMadhavan Srinivasan { 6878b4416aSMadhavan Srinivasan if (event & EVENT_IS_MARKED) 6978b4416aSMadhavan Srinivasan return true; 70c7c3f568SMadhavan Srinivasan 7178b4416aSMadhavan Srinivasan return false; 7278b4416aSMadhavan Srinivasan } 7378b4416aSMadhavan Srinivasan 74a64e697cSAthira Rajeev static unsigned long sdar_mod_val(u64 event) 75a64e697cSAthira Rajeev { 76a64e697cSAthira Rajeev if (cpu_has_feature(CPU_FTR_ARCH_31)) 77a64e697cSAthira Rajeev return p10_SDAR_MODE(event); 78a64e697cSAthira Rajeev 79a64e697cSAthira Rajeev return p9_SDAR_MODE(event); 80a64e697cSAthira Rajeev } 81a64e697cSAthira Rajeev 8278b4416aSMadhavan Srinivasan static void mmcra_sdar_mode(u64 event, unsigned long *mmcra) 8378b4416aSMadhavan Srinivasan { 8478b4416aSMadhavan Srinivasan /* 8578b4416aSMadhavan Srinivasan * MMCRA[SDAR_MODE] specifices how the SDAR should be updated in 8678b4416aSMadhavan Srinivasan * continous sampling mode. 8778b4416aSMadhavan Srinivasan * 8878b4416aSMadhavan Srinivasan * Incase of Power8: 8978b4416aSMadhavan Srinivasan * MMCRA[SDAR_MODE] will be programmed as "0b01" for continous sampling 9078b4416aSMadhavan Srinivasan * mode and will be un-changed when setting MMCRA[63] (Marked events). 9178b4416aSMadhavan Srinivasan * 92a64e697cSAthira Rajeev * Incase of Power9/power10: 9378b4416aSMadhavan Srinivasan * Marked event: MMCRA[SDAR_MODE] will be set to 0b00 ('No Updates'), 9478b4416aSMadhavan Srinivasan * or if group already have any marked events. 9578b4416aSMadhavan Srinivasan * For rest 9678b4416aSMadhavan Srinivasan * MMCRA[SDAR_MODE] will be set from event code. 9720dd4c62SMadhavan Srinivasan * If sdar_mode from event is zero, default to 0b01. Hardware 9820dd4c62SMadhavan Srinivasan * requires that we set a non-zero value. 9978b4416aSMadhavan Srinivasan */ 10078b4416aSMadhavan Srinivasan if (cpu_has_feature(CPU_FTR_ARCH_300)) { 10178b4416aSMadhavan Srinivasan if (is_event_marked(event) || (*mmcra & MMCRA_SAMPLE_ENABLE)) 10278b4416aSMadhavan Srinivasan *mmcra &= MMCRA_SDAR_MODE_NO_UPDATES; 103a64e697cSAthira Rajeev else if (sdar_mod_val(event)) 104a64e697cSAthira Rajeev *mmcra |= sdar_mod_val(event) << MMCRA_SDAR_MODE_SHIFT; 10520dd4c62SMadhavan Srinivasan else 1067aa345d8SMadhavan Srinivasan *mmcra |= MMCRA_SDAR_MODE_DCACHE; 10778b4416aSMadhavan Srinivasan } else 10878b4416aSMadhavan Srinivasan *mmcra |= MMCRA_SDAR_MODE_TLB; 109c7c3f568SMadhavan Srinivasan } 110c7c3f568SMadhavan Srinivasan 11182d2c16bSKajol Jain static u64 p10_thresh_cmp_val(u64 value) 11282d2c16bSKajol Jain { 11382d2c16bSKajol Jain int exp = 0; 11482d2c16bSKajol Jain u64 result = value; 11582d2c16bSKajol Jain 11682d2c16bSKajol Jain if (!value) 11782d2c16bSKajol Jain return value; 11882d2c16bSKajol Jain 11982d2c16bSKajol Jain /* 12082d2c16bSKajol Jain * Incase of P10, thresh_cmp value is not part of raw event code 12182d2c16bSKajol Jain * and provided via attr.config1 parameter. To program threshold in MMCRA, 12282d2c16bSKajol Jain * take a 18 bit number N and shift right 2 places and increment 12382d2c16bSKajol Jain * the exponent E by 1 until the upper 10 bits of N are zero. 12482d2c16bSKajol Jain * Write E to the threshold exponent and write the lower 8 bits of N 12582d2c16bSKajol Jain * to the threshold mantissa. 12682d2c16bSKajol Jain * The max threshold that can be written is 261120. 12782d2c16bSKajol Jain */ 12882d2c16bSKajol Jain if (cpu_has_feature(CPU_FTR_ARCH_31)) { 12982d2c16bSKajol Jain if (value > 261120) 13082d2c16bSKajol Jain value = 261120; 13182d2c16bSKajol Jain while ((64 - __builtin_clzl(value)) > 8) { 13282d2c16bSKajol Jain exp++; 13382d2c16bSKajol Jain value >>= 2; 13482d2c16bSKajol Jain } 13582d2c16bSKajol Jain 13682d2c16bSKajol Jain /* 13782d2c16bSKajol Jain * Note that it is invalid to write a mantissa with the 13882d2c16bSKajol Jain * upper 2 bits of mantissa being zero, unless the 13982d2c16bSKajol Jain * exponent is also zero. 14082d2c16bSKajol Jain */ 14182d2c16bSKajol Jain if (!(value & 0xC0) && exp) 14282d2c16bSKajol Jain result = 0; 14382d2c16bSKajol Jain else 14482d2c16bSKajol Jain result = (exp << 8) | value; 14582d2c16bSKajol Jain } 14682d2c16bSKajol Jain return result; 14782d2c16bSKajol Jain } 14882d2c16bSKajol Jain 149c7c3f568SMadhavan Srinivasan static u64 thresh_cmp_val(u64 value) 150c7c3f568SMadhavan Srinivasan { 15182d2c16bSKajol Jain if (cpu_has_feature(CPU_FTR_ARCH_31)) 15282d2c16bSKajol Jain value = p10_thresh_cmp_val(value); 15382d2c16bSKajol Jain 15482d2c16bSKajol Jain /* 15582d2c16bSKajol Jain * Since location of threshold compare bits in MMCRA 15682d2c16bSKajol Jain * is different for p8, using different shift value. 15782d2c16bSKajol Jain */ 1582bf1071aSNicholas Piggin if (cpu_has_feature(CPU_FTR_ARCH_300)) 159c7c3f568SMadhavan Srinivasan return value << p9_MMCRA_THR_CMP_SHIFT; 16082d2c16bSKajol Jain else 161c7c3f568SMadhavan Srinivasan return value << MMCRA_THR_CMP_SHIFT; 162c7c3f568SMadhavan Srinivasan } 163c7c3f568SMadhavan Srinivasan 164c7c3f568SMadhavan Srinivasan static unsigned long combine_from_event(u64 event) 165c7c3f568SMadhavan Srinivasan { 1662bf1071aSNicholas Piggin if (cpu_has_feature(CPU_FTR_ARCH_300)) 167c7c3f568SMadhavan Srinivasan return p9_EVENT_COMBINE(event); 168c7c3f568SMadhavan Srinivasan 169c7c3f568SMadhavan Srinivasan return EVENT_COMBINE(event); 170c7c3f568SMadhavan Srinivasan } 171c7c3f568SMadhavan Srinivasan 172c7c3f568SMadhavan Srinivasan static unsigned long combine_shift(unsigned long pmc) 173c7c3f568SMadhavan Srinivasan { 1742bf1071aSNicholas Piggin if (cpu_has_feature(CPU_FTR_ARCH_300)) 175c7c3f568SMadhavan Srinivasan return p9_MMCR1_COMBINE_SHIFT(pmc); 176c7c3f568SMadhavan Srinivasan 177c7c3f568SMadhavan Srinivasan return MMCR1_COMBINE_SHIFT(pmc); 178c7c3f568SMadhavan Srinivasan } 179c7c3f568SMadhavan Srinivasan 18078a16d9fSMadhavan Srinivasan static inline bool event_is_threshold(u64 event) 18178a16d9fSMadhavan Srinivasan { 18278a16d9fSMadhavan Srinivasan return (event >> EVENT_THR_SEL_SHIFT) & EVENT_THR_SEL_MASK; 18378a16d9fSMadhavan Srinivasan } 18478a16d9fSMadhavan Srinivasan 18578a16d9fSMadhavan Srinivasan static bool is_thresh_cmp_valid(u64 event) 18678a16d9fSMadhavan Srinivasan { 18778a16d9fSMadhavan Srinivasan unsigned int cmp, exp; 18878a16d9fSMadhavan Srinivasan 18982d2c16bSKajol Jain if (cpu_has_feature(CPU_FTR_ARCH_31)) 19082d2c16bSKajol Jain return p10_thresh_cmp_val(event) != 0; 19182d2c16bSKajol Jain 19278a16d9fSMadhavan Srinivasan /* 19378a16d9fSMadhavan Srinivasan * Check the mantissa upper two bits are not zero, unless the 19478a16d9fSMadhavan Srinivasan * exponent is also zero. See the THRESH_CMP_MANTISSA doc. 19578a16d9fSMadhavan Srinivasan */ 196a64e697cSAthira Rajeev 19778a16d9fSMadhavan Srinivasan cmp = (event >> EVENT_THR_CMP_SHIFT) & EVENT_THR_CMP_MASK; 19878a16d9fSMadhavan Srinivasan exp = cmp >> 7; 19978a16d9fSMadhavan Srinivasan 20078a16d9fSMadhavan Srinivasan if (exp && (cmp & 0x60) == 0) 20178a16d9fSMadhavan Srinivasan return false; 20278a16d9fSMadhavan Srinivasan 20378a16d9fSMadhavan Srinivasan return true; 20478a16d9fSMadhavan Srinivasan } 20578a16d9fSMadhavan Srinivasan 2062d46d487SMadhavan Srinivasan static unsigned int dc_ic_rld_quad_l1_sel(u64 event) 2072d46d487SMadhavan Srinivasan { 2082d46d487SMadhavan Srinivasan unsigned int cache; 2092d46d487SMadhavan Srinivasan 2102d46d487SMadhavan Srinivasan cache = (event >> EVENT_CACHE_SEL_SHIFT) & MMCR1_DC_IC_QUAL_MASK; 2112d46d487SMadhavan Srinivasan return cache; 2122d46d487SMadhavan Srinivasan } 2132d46d487SMadhavan Srinivasan 21479e96f8fSMadhavan Srinivasan static inline u64 isa207_find_source(u64 idx, u32 sub_idx) 21579e96f8fSMadhavan Srinivasan { 21679e96f8fSMadhavan Srinivasan u64 ret = PERF_MEM_NA; 21779e96f8fSMadhavan Srinivasan 21879e96f8fSMadhavan Srinivasan switch(idx) { 21979e96f8fSMadhavan Srinivasan case 0: 22079e96f8fSMadhavan Srinivasan /* Nothing to do */ 22179e96f8fSMadhavan Srinivasan break; 22279e96f8fSMadhavan Srinivasan case 1: 22379e96f8fSMadhavan Srinivasan ret = PH(LVL, L1); 22479e96f8fSMadhavan Srinivasan break; 22579e96f8fSMadhavan Srinivasan case 2: 22679e96f8fSMadhavan Srinivasan ret = PH(LVL, L2); 22779e96f8fSMadhavan Srinivasan break; 22879e96f8fSMadhavan Srinivasan case 3: 22979e96f8fSMadhavan Srinivasan ret = PH(LVL, L3); 23079e96f8fSMadhavan Srinivasan break; 23179e96f8fSMadhavan Srinivasan case 4: 23279e96f8fSMadhavan Srinivasan if (sub_idx <= 1) 23379e96f8fSMadhavan Srinivasan ret = PH(LVL, LOC_RAM); 23479e96f8fSMadhavan Srinivasan else if (sub_idx > 1 && sub_idx <= 2) 23579e96f8fSMadhavan Srinivasan ret = PH(LVL, REM_RAM1); 23679e96f8fSMadhavan Srinivasan else 23779e96f8fSMadhavan Srinivasan ret = PH(LVL, REM_RAM2); 23879e96f8fSMadhavan Srinivasan ret |= P(SNOOP, HIT); 23979e96f8fSMadhavan Srinivasan break; 24079e96f8fSMadhavan Srinivasan case 5: 24179e96f8fSMadhavan Srinivasan ret = PH(LVL, REM_CCE1); 24279e96f8fSMadhavan Srinivasan if ((sub_idx == 0) || (sub_idx == 2) || (sub_idx == 4)) 24379e96f8fSMadhavan Srinivasan ret |= P(SNOOP, HIT); 24479e96f8fSMadhavan Srinivasan else if ((sub_idx == 1) || (sub_idx == 3) || (sub_idx == 5)) 24579e96f8fSMadhavan Srinivasan ret |= P(SNOOP, HITM); 24679e96f8fSMadhavan Srinivasan break; 24779e96f8fSMadhavan Srinivasan case 6: 24879e96f8fSMadhavan Srinivasan ret = PH(LVL, REM_CCE2); 24979e96f8fSMadhavan Srinivasan if ((sub_idx == 0) || (sub_idx == 2)) 25079e96f8fSMadhavan Srinivasan ret |= P(SNOOP, HIT); 25179e96f8fSMadhavan Srinivasan else if ((sub_idx == 1) || (sub_idx == 3)) 25279e96f8fSMadhavan Srinivasan ret |= P(SNOOP, HITM); 25379e96f8fSMadhavan Srinivasan break; 25479e96f8fSMadhavan Srinivasan case 7: 25579e96f8fSMadhavan Srinivasan ret = PM(LVL, L1); 25679e96f8fSMadhavan Srinivasan break; 25779e96f8fSMadhavan Srinivasan } 25879e96f8fSMadhavan Srinivasan 25979e96f8fSMadhavan Srinivasan return ret; 26079e96f8fSMadhavan Srinivasan } 26179e96f8fSMadhavan Srinivasan 26279e96f8fSMadhavan Srinivasan void isa207_get_mem_data_src(union perf_mem_data_src *dsrc, u32 flags, 26379e96f8fSMadhavan Srinivasan struct pt_regs *regs) 26479e96f8fSMadhavan Srinivasan { 26579e96f8fSMadhavan Srinivasan u64 idx; 26679e96f8fSMadhavan Srinivasan u32 sub_idx; 26779e96f8fSMadhavan Srinivasan u64 sier; 26879e96f8fSMadhavan Srinivasan u64 val; 26979e96f8fSMadhavan Srinivasan 27079e96f8fSMadhavan Srinivasan /* Skip if no SIER support */ 27179e96f8fSMadhavan Srinivasan if (!(flags & PPMU_HAS_SIER)) { 27279e96f8fSMadhavan Srinivasan dsrc->val = 0; 27379e96f8fSMadhavan Srinivasan return; 27479e96f8fSMadhavan Srinivasan } 27579e96f8fSMadhavan Srinivasan 27679e96f8fSMadhavan Srinivasan sier = mfspr(SPRN_SIER); 27779e96f8fSMadhavan Srinivasan val = (sier & ISA207_SIER_TYPE_MASK) >> ISA207_SIER_TYPE_SHIFT; 27879e96f8fSMadhavan Srinivasan if (val == 1 || val == 2) { 27979e96f8fSMadhavan Srinivasan idx = (sier & ISA207_SIER_LDST_MASK) >> ISA207_SIER_LDST_SHIFT; 28079e96f8fSMadhavan Srinivasan sub_idx = (sier & ISA207_SIER_DATA_SRC_MASK) >> ISA207_SIER_DATA_SRC_SHIFT; 28179e96f8fSMadhavan Srinivasan 28279e96f8fSMadhavan Srinivasan dsrc->val = isa207_find_source(idx, sub_idx); 28379e96f8fSMadhavan Srinivasan dsrc->val |= (val == 1) ? P(OP, LOAD) : P(OP, STORE); 28479e96f8fSMadhavan Srinivasan } 28579e96f8fSMadhavan Srinivasan } 28679e96f8fSMadhavan Srinivasan 287170a315fSMadhavan Srinivasan void isa207_get_mem_weight(u64 *weight) 288170a315fSMadhavan Srinivasan { 289170a315fSMadhavan Srinivasan u64 mmcra = mfspr(SPRN_MMCRA); 290170a315fSMadhavan Srinivasan u64 exp = MMCRA_THR_CTR_EXP(mmcra); 291170a315fSMadhavan Srinivasan u64 mantissa = MMCRA_THR_CTR_MANT(mmcra); 29217cfccc9SMadhavan Srinivasan u64 sier = mfspr(SPRN_SIER); 29317cfccc9SMadhavan Srinivasan u64 val = (sier & ISA207_SIER_TYPE_MASK) >> ISA207_SIER_TYPE_SHIFT; 294170a315fSMadhavan Srinivasan 295ef0e3b65SMadhavan Srinivasan if (cpu_has_feature(CPU_FTR_ARCH_31)) 296ef0e3b65SMadhavan Srinivasan mantissa = P10_MMCRA_THR_CTR_MANT(mmcra); 297ef0e3b65SMadhavan Srinivasan 29817cfccc9SMadhavan Srinivasan if (val == 0 || val == 7) 29917cfccc9SMadhavan Srinivasan *weight = 0; 30017cfccc9SMadhavan Srinivasan else 301170a315fSMadhavan Srinivasan *weight = mantissa << (2 * exp); 302170a315fSMadhavan Srinivasan } 30379e96f8fSMadhavan Srinivasan 30482d2c16bSKajol Jain int isa207_get_constraint(u64 event, unsigned long *maskp, unsigned long *valp, u64 event_config1) 3057ffd948fSMadhavan Srinivasan { 3067ffd948fSMadhavan Srinivasan unsigned int unit, pmc, cache, ebb; 3077ffd948fSMadhavan Srinivasan unsigned long mask, value; 3087ffd948fSMadhavan Srinivasan 3097ffd948fSMadhavan Srinivasan mask = value = 0; 3107ffd948fSMadhavan Srinivasan 311c7c3f568SMadhavan Srinivasan if (!is_event_valid(event)) 3127ffd948fSMadhavan Srinivasan return -1; 3137ffd948fSMadhavan Srinivasan 3147ffd948fSMadhavan Srinivasan pmc = (event >> EVENT_PMC_SHIFT) & EVENT_PMC_MASK; 3157ffd948fSMadhavan Srinivasan unit = (event >> EVENT_UNIT_SHIFT) & EVENT_UNIT_MASK; 316a64e697cSAthira Rajeev if (cpu_has_feature(CPU_FTR_ARCH_31)) 317a64e697cSAthira Rajeev cache = (event >> EVENT_CACHE_SEL_SHIFT) & 318a64e697cSAthira Rajeev p10_EVENT_CACHE_SEL_MASK; 319a64e697cSAthira Rajeev else 320a64e697cSAthira Rajeev cache = (event >> EVENT_CACHE_SEL_SHIFT) & 321a64e697cSAthira Rajeev EVENT_CACHE_SEL_MASK; 3227ffd948fSMadhavan Srinivasan ebb = (event >> EVENT_EBB_SHIFT) & EVENT_EBB_MASK; 3237ffd948fSMadhavan Srinivasan 3247ffd948fSMadhavan Srinivasan if (pmc) { 3257ffd948fSMadhavan Srinivasan u64 base_event; 3267ffd948fSMadhavan Srinivasan 3277ffd948fSMadhavan Srinivasan if (pmc > 6) 3287ffd948fSMadhavan Srinivasan return -1; 3297ffd948fSMadhavan Srinivasan 3307ffd948fSMadhavan Srinivasan /* Ignore Linux defined bits when checking event below */ 3317ffd948fSMadhavan Srinivasan base_event = event & ~EVENT_LINUX_MASK; 3327ffd948fSMadhavan Srinivasan 3337ffd948fSMadhavan Srinivasan if (pmc >= 5 && base_event != 0x500fa && 3347ffd948fSMadhavan Srinivasan base_event != 0x600f4) 3357ffd948fSMadhavan Srinivasan return -1; 3367ffd948fSMadhavan Srinivasan 3377ffd948fSMadhavan Srinivasan mask |= CNST_PMC_MASK(pmc); 3387ffd948fSMadhavan Srinivasan value |= CNST_PMC_VAL(pmc); 3393b6c3adbSAthira Rajeev 3403b6c3adbSAthira Rajeev /* 3413b6c3adbSAthira Rajeev * PMC5 and PMC6 are used to count cycles and instructions and 3423b6c3adbSAthira Rajeev * they do not support most of the constraint bits. Add a check 3433b6c3adbSAthira Rajeev * to exclude PMC5/6 from most of the constraints except for 3443b6c3adbSAthira Rajeev * EBB/BHRB. 3453b6c3adbSAthira Rajeev */ 3463b6c3adbSAthira Rajeev if (pmc >= 5) 3473b6c3adbSAthira Rajeev goto ebb_bhrb; 3487ffd948fSMadhavan Srinivasan } 3497ffd948fSMadhavan Srinivasan 3507ffd948fSMadhavan Srinivasan if (pmc <= 4) { 3517ffd948fSMadhavan Srinivasan /* 3527ffd948fSMadhavan Srinivasan * Add to number of counters in use. Note this includes events with 3537ffd948fSMadhavan Srinivasan * a PMC of 0 - they still need a PMC, it's just assigned later. 3547ffd948fSMadhavan Srinivasan * Don't count events on PMC 5 & 6, there is only one valid event 3557ffd948fSMadhavan Srinivasan * on each of those counters, and they are handled above. 3567ffd948fSMadhavan Srinivasan */ 3577ffd948fSMadhavan Srinivasan mask |= CNST_NC_MASK; 3587ffd948fSMadhavan Srinivasan value |= CNST_NC_VAL; 3597ffd948fSMadhavan Srinivasan } 3607ffd948fSMadhavan Srinivasan 3617ffd948fSMadhavan Srinivasan if (unit >= 6 && unit <= 9) { 362e924be7bSAthira Rajeev if (cpu_has_feature(CPU_FTR_ARCH_31)) { 363e924be7bSAthira Rajeev if (unit == 6) { 364a64e697cSAthira Rajeev mask |= CNST_L2L3_GROUP_MASK; 365a64e697cSAthira Rajeev value |= CNST_L2L3_GROUP_VAL(event >> p10_L2L3_EVENT_SHIFT); 366e924be7bSAthira Rajeev } 367a64e697cSAthira Rajeev } else if (cpu_has_feature(CPU_FTR_ARCH_300)) { 36859029136SMadhavan Srinivasan mask |= CNST_CACHE_GROUP_MASK; 36959029136SMadhavan Srinivasan value |= CNST_CACHE_GROUP_VAL(event & 0xff); 37059029136SMadhavan Srinivasan 37159029136SMadhavan Srinivasan mask |= CNST_CACHE_PMC4_MASK; 37259029136SMadhavan Srinivasan if (pmc == 4) 37359029136SMadhavan Srinivasan value |= CNST_CACHE_PMC4_VAL; 37459029136SMadhavan Srinivasan } else if (cache & 0x7) { 3757ffd948fSMadhavan Srinivasan /* 3767ffd948fSMadhavan Srinivasan * L2/L3 events contain a cache selector field, which is 3777ffd948fSMadhavan Srinivasan * supposed to be programmed into MMCRC. However MMCRC is only 3787ffd948fSMadhavan Srinivasan * HV writable, and there is no API for guest kernels to modify 3797ffd948fSMadhavan Srinivasan * it. The solution is for the hypervisor to initialise the 3807ffd948fSMadhavan Srinivasan * field to zeroes, and for us to only ever allow events that 3817ffd948fSMadhavan Srinivasan * have a cache selector of zero. The bank selector (bit 3) is 3827ffd948fSMadhavan Srinivasan * irrelevant, as long as the rest of the value is 0. 3837ffd948fSMadhavan Srinivasan */ 3847ffd948fSMadhavan Srinivasan return -1; 38559029136SMadhavan Srinivasan } 3867ffd948fSMadhavan Srinivasan 3872d46d487SMadhavan Srinivasan } else if (cpu_has_feature(CPU_FTR_ARCH_300) || (event & EVENT_IS_L1)) { 3887ffd948fSMadhavan Srinivasan mask |= CNST_L1_QUAL_MASK; 3897ffd948fSMadhavan Srinivasan value |= CNST_L1_QUAL_VAL(cache); 3907ffd948fSMadhavan Srinivasan } 3917ffd948fSMadhavan Srinivasan 392d3afd28cSAthira Rajeev if (cpu_has_feature(CPU_FTR_ARCH_31)) { 393d3afd28cSAthira Rajeev mask |= CNST_RADIX_SCOPE_GROUP_MASK; 394d3afd28cSAthira Rajeev value |= CNST_RADIX_SCOPE_GROUP_VAL(event >> p10_EVENT_RADIX_SCOPE_QUAL_SHIFT); 395d3afd28cSAthira Rajeev } 396d3afd28cSAthira Rajeev 39778b4416aSMadhavan Srinivasan if (is_event_marked(event)) { 3987ffd948fSMadhavan Srinivasan mask |= CNST_SAMPLE_MASK; 3997ffd948fSMadhavan Srinivasan value |= CNST_SAMPLE_VAL(event >> EVENT_SAMPLE_SHIFT); 4007ffd948fSMadhavan Srinivasan } 4017ffd948fSMadhavan Srinivasan 4020263bbb3SAthira Rajeev if (cpu_has_feature(CPU_FTR_ARCH_31)) { 40382d2c16bSKajol Jain if (event_is_threshold(event) && is_thresh_cmp_valid(event_config1)) { 4040263bbb3SAthira Rajeev mask |= CNST_THRESH_CTL_SEL_MASK; 4050263bbb3SAthira Rajeev value |= CNST_THRESH_CTL_SEL_VAL(event >> EVENT_THRESH_SHIFT); 40682d2c16bSKajol Jain mask |= p10_CNST_THRESH_CMP_MASK; 40782d2c16bSKajol Jain value |= p10_CNST_THRESH_CMP_VAL(p10_thresh_cmp_val(event_config1)); 4080263bbb3SAthira Rajeev } 4090263bbb3SAthira Rajeev } else if (cpu_has_feature(CPU_FTR_ARCH_300)) { 41078a16d9fSMadhavan Srinivasan if (event_is_threshold(event) && is_thresh_cmp_valid(event)) { 41178a16d9fSMadhavan Srinivasan mask |= CNST_THRESH_MASK; 41278a16d9fSMadhavan Srinivasan value |= CNST_THRESH_VAL(event >> EVENT_THRESH_SHIFT); 41378a16d9fSMadhavan Srinivasan } 41478a16d9fSMadhavan Srinivasan } else { 4157ffd948fSMadhavan Srinivasan /* 4167ffd948fSMadhavan Srinivasan * Special case for PM_MRK_FAB_RSP_MATCH and PM_MRK_FAB_RSP_MATCH_CYC, 4177ffd948fSMadhavan Srinivasan * the threshold control bits are used for the match value. 4187ffd948fSMadhavan Srinivasan */ 4197ffd948fSMadhavan Srinivasan if (event_is_fab_match(event)) { 4207ffd948fSMadhavan Srinivasan mask |= CNST_FAB_MATCH_MASK; 4217ffd948fSMadhavan Srinivasan value |= CNST_FAB_MATCH_VAL(event >> EVENT_THR_CTL_SHIFT); 4227ffd948fSMadhavan Srinivasan } else { 42378a16d9fSMadhavan Srinivasan if (!is_thresh_cmp_valid(event)) 4247ffd948fSMadhavan Srinivasan return -1; 4257ffd948fSMadhavan Srinivasan 4267ffd948fSMadhavan Srinivasan mask |= CNST_THRESH_MASK; 4277ffd948fSMadhavan Srinivasan value |= CNST_THRESH_VAL(event >> EVENT_THRESH_SHIFT); 4287ffd948fSMadhavan Srinivasan } 42978a16d9fSMadhavan Srinivasan } 4307ffd948fSMadhavan Srinivasan 4313b6c3adbSAthira Rajeev ebb_bhrb: 4327ffd948fSMadhavan Srinivasan if (!pmc && ebb) 4337ffd948fSMadhavan Srinivasan /* EBB events must specify the PMC */ 4347ffd948fSMadhavan Srinivasan return -1; 4357ffd948fSMadhavan Srinivasan 4367ffd948fSMadhavan Srinivasan if (event & EVENT_WANTS_BHRB) { 4377ffd948fSMadhavan Srinivasan if (!ebb) 4387ffd948fSMadhavan Srinivasan /* Only EBB events can request BHRB */ 4397ffd948fSMadhavan Srinivasan return -1; 4407ffd948fSMadhavan Srinivasan 4417ffd948fSMadhavan Srinivasan mask |= CNST_IFM_MASK; 4427ffd948fSMadhavan Srinivasan value |= CNST_IFM_VAL(event >> EVENT_IFM_SHIFT); 4437ffd948fSMadhavan Srinivasan } 4447ffd948fSMadhavan Srinivasan 4457ffd948fSMadhavan Srinivasan /* 4467ffd948fSMadhavan Srinivasan * All events must agree on EBB, either all request it or none. 4477ffd948fSMadhavan Srinivasan * EBB events are pinned & exclusive, so this should never actually 4487ffd948fSMadhavan Srinivasan * hit, but we leave it as a fallback in case. 4497ffd948fSMadhavan Srinivasan */ 45010f8f961SAthira Rajeev mask |= CNST_EBB_MASK; 45110f8f961SAthira Rajeev value |= CNST_EBB_VAL(ebb); 4527ffd948fSMadhavan Srinivasan 4537ffd948fSMadhavan Srinivasan *maskp = mask; 4547ffd948fSMadhavan Srinivasan *valp = value; 4557ffd948fSMadhavan Srinivasan 4567ffd948fSMadhavan Srinivasan return 0; 4577ffd948fSMadhavan Srinivasan } 4587ffd948fSMadhavan Srinivasan 4597ffd948fSMadhavan Srinivasan int isa207_compute_mmcr(u64 event[], int n_ev, 46078d76819SAthira Rajeev unsigned int hwc[], struct mmcr_regs *mmcr, 46182d2c16bSKajol Jain struct perf_event *pevents[], u32 flags) 4627ffd948fSMadhavan Srinivasan { 4637ffd948fSMadhavan Srinivasan unsigned long mmcra, mmcr1, mmcr2, unit, combine, psel, cache, val; 464a64e697cSAthira Rajeev unsigned long mmcr3; 4657ffd948fSMadhavan Srinivasan unsigned int pmc, pmc_inuse; 4667ffd948fSMadhavan Srinivasan int i; 4677ffd948fSMadhavan Srinivasan 4687ffd948fSMadhavan Srinivasan pmc_inuse = 0; 4697ffd948fSMadhavan Srinivasan 4707ffd948fSMadhavan Srinivasan /* First pass to count resource use */ 4717ffd948fSMadhavan Srinivasan for (i = 0; i < n_ev; ++i) { 4727ffd948fSMadhavan Srinivasan pmc = (event[i] >> EVENT_PMC_SHIFT) & EVENT_PMC_MASK; 4737ffd948fSMadhavan Srinivasan if (pmc) 4747ffd948fSMadhavan Srinivasan pmc_inuse |= 1 << pmc; 4757ffd948fSMadhavan Srinivasan } 4767ffd948fSMadhavan Srinivasan 477a64e697cSAthira Rajeev mmcra = mmcr1 = mmcr2 = mmcr3 = 0; 4787ffd948fSMadhavan Srinivasan 4791cade527SAthira Rajeev /* 4801cade527SAthira Rajeev * Disable bhrb unless explicitly requested 4811cade527SAthira Rajeev * by setting MMCRA (BHRBRD) bit. 4821cade527SAthira Rajeev */ 4831cade527SAthira Rajeev if (cpu_has_feature(CPU_FTR_ARCH_31)) 4841cade527SAthira Rajeev mmcra |= MMCRA_BHRB_DISABLE; 4851cade527SAthira Rajeev 4867ffd948fSMadhavan Srinivasan /* Second pass: assign PMCs, set all MMCR1 fields */ 4877ffd948fSMadhavan Srinivasan for (i = 0; i < n_ev; ++i) { 4887ffd948fSMadhavan Srinivasan pmc = (event[i] >> EVENT_PMC_SHIFT) & EVENT_PMC_MASK; 4897ffd948fSMadhavan Srinivasan unit = (event[i] >> EVENT_UNIT_SHIFT) & EVENT_UNIT_MASK; 490c7c3f568SMadhavan Srinivasan combine = combine_from_event(event[i]); 4917ffd948fSMadhavan Srinivasan psel = event[i] & EVENT_PSEL_MASK; 4927ffd948fSMadhavan Srinivasan 4937ffd948fSMadhavan Srinivasan if (!pmc) { 4947ffd948fSMadhavan Srinivasan for (pmc = 1; pmc <= 4; ++pmc) { 4957ffd948fSMadhavan Srinivasan if (!(pmc_inuse & (1 << pmc))) 4967ffd948fSMadhavan Srinivasan break; 4977ffd948fSMadhavan Srinivasan } 4987ffd948fSMadhavan Srinivasan 4997ffd948fSMadhavan Srinivasan pmc_inuse |= 1 << pmc; 5007ffd948fSMadhavan Srinivasan } 5017ffd948fSMadhavan Srinivasan 5027ffd948fSMadhavan Srinivasan if (pmc <= 4) { 5037ffd948fSMadhavan Srinivasan mmcr1 |= unit << MMCR1_UNIT_SHIFT(pmc); 504c7c3f568SMadhavan Srinivasan mmcr1 |= combine << combine_shift(pmc); 5057ffd948fSMadhavan Srinivasan mmcr1 |= psel << MMCR1_PMCSEL_SHIFT(pmc); 5067ffd948fSMadhavan Srinivasan } 5077ffd948fSMadhavan Srinivasan 508c7c3f568SMadhavan Srinivasan /* In continuous sampling mode, update SDAR on TLB miss */ 50978b4416aSMadhavan Srinivasan mmcra_sdar_mode(event[i], &mmcra); 510c7c3f568SMadhavan Srinivasan 5112d46d487SMadhavan Srinivasan if (cpu_has_feature(CPU_FTR_ARCH_300)) { 5122d46d487SMadhavan Srinivasan cache = dc_ic_rld_quad_l1_sel(event[i]); 5132d46d487SMadhavan Srinivasan mmcr1 |= (cache) << MMCR1_DC_IC_QUAL_SHIFT; 5142d46d487SMadhavan Srinivasan } else { 5157ffd948fSMadhavan Srinivasan if (event[i] & EVENT_IS_L1) { 5162d46d487SMadhavan Srinivasan cache = dc_ic_rld_quad_l1_sel(event[i]); 5172d46d487SMadhavan Srinivasan mmcr1 |= (cache) << MMCR1_DC_IC_QUAL_SHIFT; 5182d46d487SMadhavan Srinivasan } 5197ffd948fSMadhavan Srinivasan } 5207ffd948fSMadhavan Srinivasan 521d3afd28cSAthira Rajeev /* Set RADIX_SCOPE_QUAL bit */ 522d3afd28cSAthira Rajeev if (cpu_has_feature(CPU_FTR_ARCH_31)) { 523d3afd28cSAthira Rajeev val = (event[i] >> p10_EVENT_RADIX_SCOPE_QUAL_SHIFT) & 524d3afd28cSAthira Rajeev p10_EVENT_RADIX_SCOPE_QUAL_MASK; 525d3afd28cSAthira Rajeev mmcr1 |= val << p10_MMCR1_RADIX_SCOPE_QUAL_SHIFT; 526d3afd28cSAthira Rajeev } 527d3afd28cSAthira Rajeev 52878b4416aSMadhavan Srinivasan if (is_event_marked(event[i])) { 5297ffd948fSMadhavan Srinivasan mmcra |= MMCRA_SAMPLE_ENABLE; 5307ffd948fSMadhavan Srinivasan 5317ffd948fSMadhavan Srinivasan val = (event[i] >> EVENT_SAMPLE_SHIFT) & EVENT_SAMPLE_MASK; 5327ffd948fSMadhavan Srinivasan if (val) { 5337ffd948fSMadhavan Srinivasan mmcra |= (val & 3) << MMCRA_SAMP_MODE_SHIFT; 5347ffd948fSMadhavan Srinivasan mmcra |= (val >> 2) << MMCRA_SAMP_ELIG_SHIFT; 5357ffd948fSMadhavan Srinivasan } 5367ffd948fSMadhavan Srinivasan } 5377ffd948fSMadhavan Srinivasan 5387ffd948fSMadhavan Srinivasan /* 5397ffd948fSMadhavan Srinivasan * PM_MRK_FAB_RSP_MATCH and PM_MRK_FAB_RSP_MATCH_CYC, 5407ffd948fSMadhavan Srinivasan * the threshold bits are used for the match value. 5417ffd948fSMadhavan Srinivasan */ 54278a16d9fSMadhavan Srinivasan if (!cpu_has_feature(CPU_FTR_ARCH_300) && event_is_fab_match(event[i])) { 5437ffd948fSMadhavan Srinivasan mmcr1 |= ((event[i] >> EVENT_THR_CTL_SHIFT) & 5447ffd948fSMadhavan Srinivasan EVENT_THR_CTL_MASK) << MMCR1_FAB_SHIFT; 5457ffd948fSMadhavan Srinivasan } else { 5467ffd948fSMadhavan Srinivasan val = (event[i] >> EVENT_THR_CTL_SHIFT) & EVENT_THR_CTL_MASK; 5477ffd948fSMadhavan Srinivasan mmcra |= val << MMCRA_THR_CTL_SHIFT; 5487ffd948fSMadhavan Srinivasan val = (event[i] >> EVENT_THR_SEL_SHIFT) & EVENT_THR_SEL_MASK; 5497ffd948fSMadhavan Srinivasan mmcra |= val << MMCRA_THR_SEL_SHIFT; 550a64e697cSAthira Rajeev if (!cpu_has_feature(CPU_FTR_ARCH_31)) { 551a64e697cSAthira Rajeev val = (event[i] >> EVENT_THR_CMP_SHIFT) & 552a64e697cSAthira Rajeev EVENT_THR_CMP_MASK; 553c7c3f568SMadhavan Srinivasan mmcra |= thresh_cmp_val(val); 55482d2c16bSKajol Jain } else if (flags & PPMU_HAS_ATTR_CONFIG1) { 55582d2c16bSKajol Jain val = (pevents[i]->attr.config1 >> p10_EVENT_THR_CMP_SHIFT) & 55682d2c16bSKajol Jain p10_EVENT_THR_CMP_MASK; 55782d2c16bSKajol Jain mmcra |= thresh_cmp_val(val); 5587ffd948fSMadhavan Srinivasan } 559a64e697cSAthira Rajeev } 560a64e697cSAthira Rajeev 561a64e697cSAthira Rajeev if (cpu_has_feature(CPU_FTR_ARCH_31) && (unit == 6)) { 562a64e697cSAthira Rajeev val = (event[i] >> p10_L2L3_EVENT_SHIFT) & 563a64e697cSAthira Rajeev p10_EVENT_L2L3_SEL_MASK; 564a64e697cSAthira Rajeev mmcr2 |= val << p10_L2L3_SEL_SHIFT; 565a64e697cSAthira Rajeev } 5667ffd948fSMadhavan Srinivasan 5677ffd948fSMadhavan Srinivasan if (event[i] & EVENT_WANTS_BHRB) { 5687ffd948fSMadhavan Srinivasan val = (event[i] >> EVENT_IFM_SHIFT) & EVENT_IFM_MASK; 5697ffd948fSMadhavan Srinivasan mmcra |= val << MMCRA_IFM_SHIFT; 5707ffd948fSMadhavan Srinivasan } 5717ffd948fSMadhavan Srinivasan 5721cade527SAthira Rajeev /* set MMCRA (BHRBRD) to 0 if there is user request for BHRB */ 5731cade527SAthira Rajeev if (cpu_has_feature(CPU_FTR_ARCH_31) && 5741cade527SAthira Rajeev (has_branch_stack(pevents[i]) || (event[i] & EVENT_WANTS_BHRB))) 5751cade527SAthira Rajeev mmcra &= ~MMCRA_BHRB_DISABLE; 5761cade527SAthira Rajeev 5777ffd948fSMadhavan Srinivasan if (pevents[i]->attr.exclude_user) 5787ffd948fSMadhavan Srinivasan mmcr2 |= MMCR2_FCP(pmc); 5797ffd948fSMadhavan Srinivasan 5807ffd948fSMadhavan Srinivasan if (pevents[i]->attr.exclude_hv) 5817ffd948fSMadhavan Srinivasan mmcr2 |= MMCR2_FCH(pmc); 5827ffd948fSMadhavan Srinivasan 5837ffd948fSMadhavan Srinivasan if (pevents[i]->attr.exclude_kernel) { 5847ffd948fSMadhavan Srinivasan if (cpu_has_feature(CPU_FTR_HVMODE)) 5857ffd948fSMadhavan Srinivasan mmcr2 |= MMCR2_FCH(pmc); 5867ffd948fSMadhavan Srinivasan else 5877ffd948fSMadhavan Srinivasan mmcr2 |= MMCR2_FCS(pmc); 5887ffd948fSMadhavan Srinivasan } 5897ffd948fSMadhavan Srinivasan 590a64e697cSAthira Rajeev if (cpu_has_feature(CPU_FTR_ARCH_31)) { 591a64e697cSAthira Rajeev if (pmc <= 4) { 592a64e697cSAthira Rajeev val = (event[i] >> p10_EVENT_MMCR3_SHIFT) & 593a64e697cSAthira Rajeev p10_EVENT_MMCR3_MASK; 594a64e697cSAthira Rajeev mmcr3 |= val << MMCR3_SHIFT(pmc); 595a64e697cSAthira Rajeev } 596a64e697cSAthira Rajeev } 597a64e697cSAthira Rajeev 5987ffd948fSMadhavan Srinivasan hwc[i] = pmc - 1; 5997ffd948fSMadhavan Srinivasan } 6007ffd948fSMadhavan Srinivasan 6017ffd948fSMadhavan Srinivasan /* Return MMCRx values */ 60278d76819SAthira Rajeev mmcr->mmcr0 = 0; 6037ffd948fSMadhavan Srinivasan 6047ffd948fSMadhavan Srinivasan /* pmc_inuse is 1-based */ 6057ffd948fSMadhavan Srinivasan if (pmc_inuse & 2) 60678d76819SAthira Rajeev mmcr->mmcr0 = MMCR0_PMC1CE; 6077ffd948fSMadhavan Srinivasan 6087ffd948fSMadhavan Srinivasan if (pmc_inuse & 0x7c) 60978d76819SAthira Rajeev mmcr->mmcr0 |= MMCR0_PMCjCE; 6107ffd948fSMadhavan Srinivasan 6117ffd948fSMadhavan Srinivasan /* If we're not using PMC 5 or 6, freeze them */ 6127ffd948fSMadhavan Srinivasan if (!(pmc_inuse & 0x60)) 61378d76819SAthira Rajeev mmcr->mmcr0 |= MMCR0_FC56; 6147ffd948fSMadhavan Srinivasan 61591668ab7SAthira Rajeev /* 61691668ab7SAthira Rajeev * Set mmcr0 (PMCCEXT) for p10 which 61791668ab7SAthira Rajeev * will restrict access to group B registers 61891668ab7SAthira Rajeev * when MMCR0 PMCC=0b00. 61991668ab7SAthira Rajeev */ 62091668ab7SAthira Rajeev if (cpu_has_feature(CPU_FTR_ARCH_31)) 62191668ab7SAthira Rajeev mmcr->mmcr0 |= MMCR0_PMCCEXT; 62291668ab7SAthira Rajeev 62378d76819SAthira Rajeev mmcr->mmcr1 = mmcr1; 62478d76819SAthira Rajeev mmcr->mmcra = mmcra; 62578d76819SAthira Rajeev mmcr->mmcr2 = mmcr2; 626a64e697cSAthira Rajeev mmcr->mmcr3 = mmcr3; 6277ffd948fSMadhavan Srinivasan 6287ffd948fSMadhavan Srinivasan return 0; 6297ffd948fSMadhavan Srinivasan } 6307ffd948fSMadhavan Srinivasan 63178d76819SAthira Rajeev void isa207_disable_pmc(unsigned int pmc, struct mmcr_regs *mmcr) 6327ffd948fSMadhavan Srinivasan { 6337ffd948fSMadhavan Srinivasan if (pmc <= 3) 63478d76819SAthira Rajeev mmcr->mmcr1 &= ~(0xffUL << MMCR1_PMCSEL_SHIFT(pmc + 1)); 6357ffd948fSMadhavan Srinivasan } 636efe881afSMadhavan Srinivasan 637efe881afSMadhavan Srinivasan static int find_alternative(u64 event, const unsigned int ev_alt[][MAX_ALT], int size) 638efe881afSMadhavan Srinivasan { 639efe881afSMadhavan Srinivasan int i, j; 640efe881afSMadhavan Srinivasan 641efe881afSMadhavan Srinivasan for (i = 0; i < size; ++i) { 642efe881afSMadhavan Srinivasan if (event < ev_alt[i][0]) 643efe881afSMadhavan Srinivasan break; 644efe881afSMadhavan Srinivasan 645efe881afSMadhavan Srinivasan for (j = 0; j < MAX_ALT && ev_alt[i][j]; ++j) 646efe881afSMadhavan Srinivasan if (event == ev_alt[i][j]) 647efe881afSMadhavan Srinivasan return i; 648efe881afSMadhavan Srinivasan } 649efe881afSMadhavan Srinivasan 650efe881afSMadhavan Srinivasan return -1; 651efe881afSMadhavan Srinivasan } 652efe881afSMadhavan Srinivasan 65370a7e720SMadhavan Srinivasan int isa207_get_alternatives(u64 event, u64 alt[], int size, unsigned int flags, 65470a7e720SMadhavan Srinivasan const unsigned int ev_alt[][MAX_ALT]) 655efe881afSMadhavan Srinivasan { 656efe881afSMadhavan Srinivasan int i, j, num_alt = 0; 657efe881afSMadhavan Srinivasan u64 alt_event; 658efe881afSMadhavan Srinivasan 659efe881afSMadhavan Srinivasan alt[num_alt++] = event; 660efe881afSMadhavan Srinivasan i = find_alternative(event, ev_alt, size); 661efe881afSMadhavan Srinivasan if (i >= 0) { 662efe881afSMadhavan Srinivasan /* Filter out the original event, it's already in alt[0] */ 663efe881afSMadhavan Srinivasan for (j = 0; j < MAX_ALT; ++j) { 664efe881afSMadhavan Srinivasan alt_event = ev_alt[i][j]; 665efe881afSMadhavan Srinivasan if (alt_event && alt_event != event) 666efe881afSMadhavan Srinivasan alt[num_alt++] = alt_event; 667efe881afSMadhavan Srinivasan } 668efe881afSMadhavan Srinivasan } 669efe881afSMadhavan Srinivasan 67070a7e720SMadhavan Srinivasan if (flags & PPMU_ONLY_COUNT_RUN) { 67170a7e720SMadhavan Srinivasan /* 67270a7e720SMadhavan Srinivasan * We're only counting in RUN state, so PM_CYC is equivalent to 67370a7e720SMadhavan Srinivasan * PM_RUN_CYC and PM_INST_CMPL === PM_RUN_INST_CMPL. 67470a7e720SMadhavan Srinivasan */ 67570a7e720SMadhavan Srinivasan j = num_alt; 67670a7e720SMadhavan Srinivasan for (i = 0; i < num_alt; ++i) { 67770a7e720SMadhavan Srinivasan switch (alt[i]) { 67870a7e720SMadhavan Srinivasan case 0x1e: /* PMC_CYC */ 67970a7e720SMadhavan Srinivasan alt[j++] = 0x600f4; /* PM_RUN_CYC */ 68070a7e720SMadhavan Srinivasan break; 68170a7e720SMadhavan Srinivasan case 0x600f4: 68270a7e720SMadhavan Srinivasan alt[j++] = 0x1e; 68370a7e720SMadhavan Srinivasan break; 68470a7e720SMadhavan Srinivasan case 0x2: /* PM_INST_CMPL */ 68570a7e720SMadhavan Srinivasan alt[j++] = 0x500fa; /* PM_RUN_INST_CMPL */ 68670a7e720SMadhavan Srinivasan break; 68770a7e720SMadhavan Srinivasan case 0x500fa: 68870a7e720SMadhavan Srinivasan alt[j++] = 0x2; 68970a7e720SMadhavan Srinivasan break; 69070a7e720SMadhavan Srinivasan } 69170a7e720SMadhavan Srinivasan } 69270a7e720SMadhavan Srinivasan num_alt = j; 69370a7e720SMadhavan Srinivasan } 69470a7e720SMadhavan Srinivasan 695efe881afSMadhavan Srinivasan return num_alt; 696efe881afSMadhavan Srinivasan } 697*d8a1d6c5SMadhavan Srinivasan 698*d8a1d6c5SMadhavan Srinivasan int isa3XX_check_attr_config(struct perf_event *ev) 699*d8a1d6c5SMadhavan Srinivasan { 700*d8a1d6c5SMadhavan Srinivasan u64 val, sample_mode; 701*d8a1d6c5SMadhavan Srinivasan u64 event = ev->attr.config; 702*d8a1d6c5SMadhavan Srinivasan 703*d8a1d6c5SMadhavan Srinivasan val = (event >> EVENT_SAMPLE_SHIFT) & EVENT_SAMPLE_MASK; 704*d8a1d6c5SMadhavan Srinivasan sample_mode = val & 0x3; 705*d8a1d6c5SMadhavan Srinivasan 706*d8a1d6c5SMadhavan Srinivasan /* 707*d8a1d6c5SMadhavan Srinivasan * MMCRA[61:62] is Random Sampling Mode (SM). 708*d8a1d6c5SMadhavan Srinivasan * value of 0b11 is reserved. 709*d8a1d6c5SMadhavan Srinivasan */ 710*d8a1d6c5SMadhavan Srinivasan if (sample_mode == 0x3) 711*d8a1d6c5SMadhavan Srinivasan return -EINVAL; 712*d8a1d6c5SMadhavan Srinivasan 713*d8a1d6c5SMadhavan Srinivasan /* 714*d8a1d6c5SMadhavan Srinivasan * Check for all reserved value 715*d8a1d6c5SMadhavan Srinivasan * Source: Performance Monitoring Unit User Guide 716*d8a1d6c5SMadhavan Srinivasan */ 717*d8a1d6c5SMadhavan Srinivasan switch (val) { 718*d8a1d6c5SMadhavan Srinivasan case 0x5: 719*d8a1d6c5SMadhavan Srinivasan case 0x9: 720*d8a1d6c5SMadhavan Srinivasan case 0xD: 721*d8a1d6c5SMadhavan Srinivasan case 0x19: 722*d8a1d6c5SMadhavan Srinivasan case 0x1D: 723*d8a1d6c5SMadhavan Srinivasan case 0x1A: 724*d8a1d6c5SMadhavan Srinivasan case 0x1E: 725*d8a1d6c5SMadhavan Srinivasan return -EINVAL; 726*d8a1d6c5SMadhavan Srinivasan } 727*d8a1d6c5SMadhavan Srinivasan 728*d8a1d6c5SMadhavan Srinivasan /* 729*d8a1d6c5SMadhavan Srinivasan * MMCRA[48:51]/[52:55]) Threshold Start/Stop 730*d8a1d6c5SMadhavan Srinivasan * Events Selection. 731*d8a1d6c5SMadhavan Srinivasan * 0b11110000/0b00001111 is reserved. 732*d8a1d6c5SMadhavan Srinivasan */ 733*d8a1d6c5SMadhavan Srinivasan val = (event >> EVENT_THR_CTL_SHIFT) & EVENT_THR_CTL_MASK; 734*d8a1d6c5SMadhavan Srinivasan if (((val & 0xF0) == 0xF0) || ((val & 0xF) == 0xF)) 735*d8a1d6c5SMadhavan Srinivasan return -EINVAL; 736*d8a1d6c5SMadhavan Srinivasan 737*d8a1d6c5SMadhavan Srinivasan return 0; 738*d8a1d6c5SMadhavan Srinivasan } 739