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 406b3a3e12SRohan McLure const 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 /* 851fd02f66SJulia Lawall * MMCRA[SDAR_MODE] specifies how the SDAR should be updated in 861fd02f66SJulia Lawall * continuous sampling mode. 8778b4416aSMadhavan Srinivasan * 8878b4416aSMadhavan Srinivasan * Incase of Power8: 891fd02f66SJulia Lawall * MMCRA[SDAR_MODE] will be programmed as "0b01" for continuous 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 111*505d3165SKajol Jain static int 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) 142*505d3165SKajol Jain result = -1; 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)) 190*505d3165SKajol 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: 2234a20ee10SKajol Jain ret = PH(LVL, L1) | LEVEL(L1) | P(SNOOP, HIT); 22479e96f8fSMadhavan Srinivasan break; 22579e96f8fSMadhavan Srinivasan case 2: 2264a20ee10SKajol Jain ret = PH(LVL, L2) | LEVEL(L2) | P(SNOOP, HIT); 22779e96f8fSMadhavan Srinivasan break; 22879e96f8fSMadhavan Srinivasan case 3: 2294a20ee10SKajol Jain ret = PH(LVL, L3) | LEVEL(L3) | P(SNOOP, HIT); 23079e96f8fSMadhavan Srinivasan break; 23179e96f8fSMadhavan Srinivasan case 4: 2326ed05a8eSKajol Jain if (cpu_has_feature(CPU_FTR_ARCH_31)) { 2336ed05a8eSKajol Jain ret = P(SNOOP, HIT); 2346ed05a8eSKajol Jain 2356ed05a8eSKajol Jain if (sub_idx == 1) 2366ed05a8eSKajol Jain ret |= PH(LVL, LOC_RAM) | LEVEL(RAM); 2376ed05a8eSKajol Jain else if (sub_idx == 2 || sub_idx == 3) 2386ed05a8eSKajol Jain ret |= P(LVL, HIT) | LEVEL(PMEM); 2396ed05a8eSKajol Jain else if (sub_idx == 4) 2406ed05a8eSKajol Jain ret |= PH(LVL, REM_RAM1) | REM | LEVEL(RAM) | P(HOPS, 2); 2416ed05a8eSKajol Jain else if (sub_idx == 5 || sub_idx == 7) 2426ed05a8eSKajol Jain ret |= P(LVL, HIT) | LEVEL(PMEM) | REM; 2436ed05a8eSKajol Jain else if (sub_idx == 6) 2446ed05a8eSKajol Jain ret |= PH(LVL, REM_RAM2) | REM | LEVEL(RAM) | P(HOPS, 3); 2456ed05a8eSKajol Jain } else { 24679e96f8fSMadhavan Srinivasan if (sub_idx <= 1) 24779e96f8fSMadhavan Srinivasan ret = PH(LVL, LOC_RAM); 24879e96f8fSMadhavan Srinivasan else if (sub_idx > 1 && sub_idx <= 2) 24979e96f8fSMadhavan Srinivasan ret = PH(LVL, REM_RAM1); 25079e96f8fSMadhavan Srinivasan else 25179e96f8fSMadhavan Srinivasan ret = PH(LVL, REM_RAM2); 25279e96f8fSMadhavan Srinivasan ret |= P(SNOOP, HIT); 2536ed05a8eSKajol Jain } 25479e96f8fSMadhavan Srinivasan break; 25579e96f8fSMadhavan Srinivasan case 5: 25626da4abfSKajol Jain if (cpu_has_feature(CPU_FTR_ARCH_31)) { 25726da4abfSKajol Jain ret = REM | P(HOPS, 0); 25826da4abfSKajol Jain 25926da4abfSKajol Jain if (sub_idx == 0 || sub_idx == 4) 26026da4abfSKajol Jain ret |= PH(LVL, L2) | LEVEL(L2) | P(SNOOP, HIT); 26126da4abfSKajol Jain else if (sub_idx == 1 || sub_idx == 5) 26226da4abfSKajol Jain ret |= PH(LVL, L2) | LEVEL(L2) | P(SNOOP, HITM); 26326da4abfSKajol Jain else if (sub_idx == 2 || sub_idx == 6) 26426da4abfSKajol Jain ret |= PH(LVL, L3) | LEVEL(L3) | P(SNOOP, HIT); 26526da4abfSKajol Jain else if (sub_idx == 3 || sub_idx == 7) 26626da4abfSKajol Jain ret |= PH(LVL, L3) | LEVEL(L3) | P(SNOOP, HITM); 26726da4abfSKajol Jain } else { 26826da4abfSKajol Jain if (sub_idx == 0) 26926da4abfSKajol Jain ret = PH(LVL, L2) | LEVEL(L2) | REM | P(SNOOP, HIT) | P(HOPS, 0); 27026da4abfSKajol Jain else if (sub_idx == 1) 27126da4abfSKajol Jain ret = PH(LVL, L2) | LEVEL(L2) | REM | P(SNOOP, HITM) | P(HOPS, 0); 27226da4abfSKajol Jain else if (sub_idx == 2 || sub_idx == 4) 27326da4abfSKajol Jain ret = PH(LVL, L3) | LEVEL(L3) | REM | P(SNOOP, HIT) | P(HOPS, 0); 27426da4abfSKajol Jain else if (sub_idx == 3 || sub_idx == 5) 27526da4abfSKajol Jain ret = PH(LVL, L3) | LEVEL(L3) | REM | P(SNOOP, HITM) | P(HOPS, 0); 27626da4abfSKajol Jain } 27779e96f8fSMadhavan Srinivasan break; 27879e96f8fSMadhavan Srinivasan case 6: 2796ed05a8eSKajol Jain if (cpu_has_feature(CPU_FTR_ARCH_31)) { 2806ed05a8eSKajol Jain if (sub_idx == 0) 2816ed05a8eSKajol Jain ret = PH(LVL, REM_CCE1) | LEVEL(ANY_CACHE) | REM | 2826ed05a8eSKajol Jain P(SNOOP, HIT) | P(HOPS, 2); 2836ed05a8eSKajol Jain else if (sub_idx == 1) 2846ed05a8eSKajol Jain ret = PH(LVL, REM_CCE1) | LEVEL(ANY_CACHE) | REM | 2856ed05a8eSKajol Jain P(SNOOP, HITM) | P(HOPS, 2); 2866ed05a8eSKajol Jain else if (sub_idx == 2) 2876ed05a8eSKajol Jain ret = PH(LVL, REM_CCE2) | LEVEL(ANY_CACHE) | REM | 2886ed05a8eSKajol Jain P(SNOOP, HIT) | P(HOPS, 3); 2896ed05a8eSKajol Jain else if (sub_idx == 3) 2906ed05a8eSKajol Jain ret = PH(LVL, REM_CCE2) | LEVEL(ANY_CACHE) | REM | 2916ed05a8eSKajol Jain P(SNOOP, HITM) | P(HOPS, 3); 2926ed05a8eSKajol Jain } else { 29379e96f8fSMadhavan Srinivasan ret = PH(LVL, REM_CCE2); 2946ed05a8eSKajol Jain if (sub_idx == 0 || sub_idx == 2) 29579e96f8fSMadhavan Srinivasan ret |= P(SNOOP, HIT); 2966ed05a8eSKajol Jain else if (sub_idx == 1 || sub_idx == 3) 29779e96f8fSMadhavan Srinivasan ret |= P(SNOOP, HITM); 2986ed05a8eSKajol Jain } 29979e96f8fSMadhavan Srinivasan break; 30079e96f8fSMadhavan Srinivasan case 7: 30179e96f8fSMadhavan Srinivasan ret = PM(LVL, L1); 30279e96f8fSMadhavan Srinivasan break; 30379e96f8fSMadhavan Srinivasan } 30479e96f8fSMadhavan Srinivasan 30579e96f8fSMadhavan Srinivasan return ret; 30679e96f8fSMadhavan Srinivasan } 30779e96f8fSMadhavan Srinivasan 30879e96f8fSMadhavan Srinivasan void isa207_get_mem_data_src(union perf_mem_data_src *dsrc, u32 flags, 30979e96f8fSMadhavan Srinivasan struct pt_regs *regs) 31079e96f8fSMadhavan Srinivasan { 31179e96f8fSMadhavan Srinivasan u64 idx; 31279e96f8fSMadhavan Srinivasan u32 sub_idx; 31379e96f8fSMadhavan Srinivasan u64 sier; 31479e96f8fSMadhavan Srinivasan u64 val; 31579e96f8fSMadhavan Srinivasan 31679e96f8fSMadhavan Srinivasan /* Skip if no SIER support */ 31779e96f8fSMadhavan Srinivasan if (!(flags & PPMU_HAS_SIER)) { 31879e96f8fSMadhavan Srinivasan dsrc->val = 0; 31979e96f8fSMadhavan Srinivasan return; 32079e96f8fSMadhavan Srinivasan } 32179e96f8fSMadhavan Srinivasan 32279e96f8fSMadhavan Srinivasan sier = mfspr(SPRN_SIER); 32379e96f8fSMadhavan Srinivasan val = (sier & ISA207_SIER_TYPE_MASK) >> ISA207_SIER_TYPE_SHIFT; 324b4ded422SAthira Rajeev if (val != 1 && val != 2 && !(val == 7 && cpu_has_feature(CPU_FTR_ARCH_31))) 325b4ded422SAthira Rajeev return; 326b4ded422SAthira Rajeev 32779e96f8fSMadhavan Srinivasan idx = (sier & ISA207_SIER_LDST_MASK) >> ISA207_SIER_LDST_SHIFT; 32879e96f8fSMadhavan Srinivasan sub_idx = (sier & ISA207_SIER_DATA_SRC_MASK) >> ISA207_SIER_DATA_SRC_SHIFT; 32979e96f8fSMadhavan Srinivasan 33079e96f8fSMadhavan Srinivasan dsrc->val = isa207_find_source(idx, sub_idx); 331b4ded422SAthira Rajeev if (val == 7) { 332b4ded422SAthira Rajeev u64 mmcra; 333b4ded422SAthira Rajeev u32 op_type; 334b4ded422SAthira Rajeev 335b4ded422SAthira Rajeev /* 336b4ded422SAthira Rajeev * Type 0b111 denotes either larx or stcx instruction. Use the 337b4ded422SAthira Rajeev * MMCRA sampling bits [57:59] along with the type value 338b4ded422SAthira Rajeev * to determine the exact instruction type. If the sampling 339b4ded422SAthira Rajeev * criteria is neither load or store, set the type as default 340b4ded422SAthira Rajeev * to NA. 341b4ded422SAthira Rajeev */ 342b4ded422SAthira Rajeev mmcra = mfspr(SPRN_MMCRA); 343b4ded422SAthira Rajeev 344b4ded422SAthira Rajeev op_type = (mmcra >> MMCRA_SAMP_ELIG_SHIFT) & MMCRA_SAMP_ELIG_MASK; 345b4ded422SAthira Rajeev switch (op_type) { 346b4ded422SAthira Rajeev case 5: 347b4ded422SAthira Rajeev dsrc->val |= P(OP, LOAD); 348b4ded422SAthira Rajeev break; 349b4ded422SAthira Rajeev case 7: 350b4ded422SAthira Rajeev dsrc->val |= P(OP, STORE); 351b4ded422SAthira Rajeev break; 352b4ded422SAthira Rajeev default: 353b4ded422SAthira Rajeev dsrc->val |= P(OP, NA); 354b4ded422SAthira Rajeev break; 355b4ded422SAthira Rajeev } 356b4ded422SAthira Rajeev } else { 35779e96f8fSMadhavan Srinivasan dsrc->val |= (val == 1) ? P(OP, LOAD) : P(OP, STORE); 35879e96f8fSMadhavan Srinivasan } 35979e96f8fSMadhavan Srinivasan } 36079e96f8fSMadhavan Srinivasan 361af31fd0cSAthira Rajeev void isa207_get_mem_weight(u64 *weight, u64 type) 362170a315fSMadhavan Srinivasan { 363af31fd0cSAthira Rajeev union perf_sample_weight *weight_fields; 364af31fd0cSAthira Rajeev u64 weight_lat; 365170a315fSMadhavan Srinivasan u64 mmcra = mfspr(SPRN_MMCRA); 366170a315fSMadhavan Srinivasan u64 exp = MMCRA_THR_CTR_EXP(mmcra); 367170a315fSMadhavan Srinivasan u64 mantissa = MMCRA_THR_CTR_MANT(mmcra); 36817cfccc9SMadhavan Srinivasan u64 sier = mfspr(SPRN_SIER); 36917cfccc9SMadhavan Srinivasan u64 val = (sier & ISA207_SIER_TYPE_MASK) >> ISA207_SIER_TYPE_SHIFT; 370170a315fSMadhavan Srinivasan 371ef0e3b65SMadhavan Srinivasan if (cpu_has_feature(CPU_FTR_ARCH_31)) 372ef0e3b65SMadhavan Srinivasan mantissa = P10_MMCRA_THR_CTR_MANT(mmcra); 373ef0e3b65SMadhavan Srinivasan 374b4ded422SAthira Rajeev if (val == 0 || (val == 7 && !cpu_has_feature(CPU_FTR_ARCH_31))) 375af31fd0cSAthira Rajeev weight_lat = 0; 37617cfccc9SMadhavan Srinivasan else 377af31fd0cSAthira Rajeev weight_lat = mantissa << (2 * exp); 378af31fd0cSAthira Rajeev 379af31fd0cSAthira Rajeev /* 380af31fd0cSAthira Rajeev * Use 64 bit weight field (full) if sample type is 381af31fd0cSAthira Rajeev * WEIGHT. 382af31fd0cSAthira Rajeev * 383af31fd0cSAthira Rajeev * if sample type is WEIGHT_STRUCT: 384af31fd0cSAthira Rajeev * - store memory latency in the lower 32 bits. 385af31fd0cSAthira Rajeev * - For ISA v3.1, use remaining two 16 bit fields of 386af31fd0cSAthira Rajeev * perf_sample_weight to store cycle counter values 387af31fd0cSAthira Rajeev * from sier2. 388af31fd0cSAthira Rajeev */ 389af31fd0cSAthira Rajeev weight_fields = (union perf_sample_weight *)weight; 390af31fd0cSAthira Rajeev if (type & PERF_SAMPLE_WEIGHT) 391af31fd0cSAthira Rajeev weight_fields->full = weight_lat; 392af31fd0cSAthira Rajeev else { 393af31fd0cSAthira Rajeev weight_fields->var1_dw = (u32)weight_lat; 394af31fd0cSAthira Rajeev if (cpu_has_feature(CPU_FTR_ARCH_31)) { 395af31fd0cSAthira Rajeev weight_fields->var2_w = P10_SIER2_FINISH_CYC(mfspr(SPRN_SIER2)); 396af31fd0cSAthira Rajeev weight_fields->var3_w = P10_SIER2_DISPATCH_CYC(mfspr(SPRN_SIER2)); 397af31fd0cSAthira Rajeev } 398af31fd0cSAthira Rajeev } 399170a315fSMadhavan Srinivasan } 40079e96f8fSMadhavan Srinivasan 40182d2c16bSKajol Jain int isa207_get_constraint(u64 event, unsigned long *maskp, unsigned long *valp, u64 event_config1) 4027ffd948fSMadhavan Srinivasan { 4037ffd948fSMadhavan Srinivasan unsigned int unit, pmc, cache, ebb; 4047ffd948fSMadhavan Srinivasan unsigned long mask, value; 4057ffd948fSMadhavan Srinivasan 4067ffd948fSMadhavan Srinivasan mask = value = 0; 4077ffd948fSMadhavan Srinivasan 408c7c3f568SMadhavan Srinivasan if (!is_event_valid(event)) 4097ffd948fSMadhavan Srinivasan return -1; 4107ffd948fSMadhavan Srinivasan 4117ffd948fSMadhavan Srinivasan pmc = (event >> EVENT_PMC_SHIFT) & EVENT_PMC_MASK; 4127ffd948fSMadhavan Srinivasan unit = (event >> EVENT_UNIT_SHIFT) & EVENT_UNIT_MASK; 413a64e697cSAthira Rajeev if (cpu_has_feature(CPU_FTR_ARCH_31)) 414a64e697cSAthira Rajeev cache = (event >> EVENT_CACHE_SEL_SHIFT) & 415a64e697cSAthira Rajeev p10_EVENT_CACHE_SEL_MASK; 416a64e697cSAthira Rajeev else 417a64e697cSAthira Rajeev cache = (event >> EVENT_CACHE_SEL_SHIFT) & 418a64e697cSAthira Rajeev EVENT_CACHE_SEL_MASK; 4197ffd948fSMadhavan Srinivasan ebb = (event >> EVENT_EBB_SHIFT) & EVENT_EBB_MASK; 4207ffd948fSMadhavan Srinivasan 4217ffd948fSMadhavan Srinivasan if (pmc) { 4227ffd948fSMadhavan Srinivasan u64 base_event; 4237ffd948fSMadhavan Srinivasan 4247ffd948fSMadhavan Srinivasan if (pmc > 6) 4257ffd948fSMadhavan Srinivasan return -1; 4267ffd948fSMadhavan Srinivasan 4277ffd948fSMadhavan Srinivasan /* Ignore Linux defined bits when checking event below */ 4287ffd948fSMadhavan Srinivasan base_event = event & ~EVENT_LINUX_MASK; 4297ffd948fSMadhavan Srinivasan 4307ffd948fSMadhavan Srinivasan if (pmc >= 5 && base_event != 0x500fa && 4317ffd948fSMadhavan Srinivasan base_event != 0x600f4) 4327ffd948fSMadhavan Srinivasan return -1; 4337ffd948fSMadhavan Srinivasan 4347ffd948fSMadhavan Srinivasan mask |= CNST_PMC_MASK(pmc); 4357ffd948fSMadhavan Srinivasan value |= CNST_PMC_VAL(pmc); 4363b6c3adbSAthira Rajeev 4373b6c3adbSAthira Rajeev /* 4383b6c3adbSAthira Rajeev * PMC5 and PMC6 are used to count cycles and instructions and 4393b6c3adbSAthira Rajeev * they do not support most of the constraint bits. Add a check 4403b6c3adbSAthira Rajeev * to exclude PMC5/6 from most of the constraints except for 4413b6c3adbSAthira Rajeev * EBB/BHRB. 4423b6c3adbSAthira Rajeev */ 4433b6c3adbSAthira Rajeev if (pmc >= 5) 4443b6c3adbSAthira Rajeev goto ebb_bhrb; 4457ffd948fSMadhavan Srinivasan } 4467ffd948fSMadhavan Srinivasan 4477ffd948fSMadhavan Srinivasan if (pmc <= 4) { 4487ffd948fSMadhavan Srinivasan /* 4497ffd948fSMadhavan Srinivasan * Add to number of counters in use. Note this includes events with 4507ffd948fSMadhavan Srinivasan * a PMC of 0 - they still need a PMC, it's just assigned later. 4517ffd948fSMadhavan Srinivasan * Don't count events on PMC 5 & 6, there is only one valid event 4527ffd948fSMadhavan Srinivasan * on each of those counters, and they are handled above. 4537ffd948fSMadhavan Srinivasan */ 4547ffd948fSMadhavan Srinivasan mask |= CNST_NC_MASK; 4557ffd948fSMadhavan Srinivasan value |= CNST_NC_VAL; 4567ffd948fSMadhavan Srinivasan } 4577ffd948fSMadhavan Srinivasan 4587ffd948fSMadhavan Srinivasan if (unit >= 6 && unit <= 9) { 459e924be7bSAthira Rajeev if (cpu_has_feature(CPU_FTR_ARCH_31)) { 460e924be7bSAthira Rajeev if (unit == 6) { 461a64e697cSAthira Rajeev mask |= CNST_L2L3_GROUP_MASK; 462a64e697cSAthira Rajeev value |= CNST_L2L3_GROUP_VAL(event >> p10_L2L3_EVENT_SHIFT); 463e924be7bSAthira Rajeev } 464a64e697cSAthira Rajeev } else if (cpu_has_feature(CPU_FTR_ARCH_300)) { 46559029136SMadhavan Srinivasan mask |= CNST_CACHE_GROUP_MASK; 46659029136SMadhavan Srinivasan value |= CNST_CACHE_GROUP_VAL(event & 0xff); 46759029136SMadhavan Srinivasan 46859029136SMadhavan Srinivasan mask |= CNST_CACHE_PMC4_MASK; 46959029136SMadhavan Srinivasan if (pmc == 4) 47059029136SMadhavan Srinivasan value |= CNST_CACHE_PMC4_VAL; 47159029136SMadhavan Srinivasan } else if (cache & 0x7) { 4727ffd948fSMadhavan Srinivasan /* 4737ffd948fSMadhavan Srinivasan * L2/L3 events contain a cache selector field, which is 4747ffd948fSMadhavan Srinivasan * supposed to be programmed into MMCRC. However MMCRC is only 4757ffd948fSMadhavan Srinivasan * HV writable, and there is no API for guest kernels to modify 4767ffd948fSMadhavan Srinivasan * it. The solution is for the hypervisor to initialise the 4777ffd948fSMadhavan Srinivasan * field to zeroes, and for us to only ever allow events that 4787ffd948fSMadhavan Srinivasan * have a cache selector of zero. The bank selector (bit 3) is 4797ffd948fSMadhavan Srinivasan * irrelevant, as long as the rest of the value is 0. 4807ffd948fSMadhavan Srinivasan */ 4817ffd948fSMadhavan Srinivasan return -1; 48259029136SMadhavan Srinivasan } 4837ffd948fSMadhavan Srinivasan 4842d46d487SMadhavan Srinivasan } else if (cpu_has_feature(CPU_FTR_ARCH_300) || (event & EVENT_IS_L1)) { 4857ffd948fSMadhavan Srinivasan mask |= CNST_L1_QUAL_MASK; 4867ffd948fSMadhavan Srinivasan value |= CNST_L1_QUAL_VAL(cache); 4877ffd948fSMadhavan Srinivasan } 4887ffd948fSMadhavan Srinivasan 489d3afd28cSAthira Rajeev if (cpu_has_feature(CPU_FTR_ARCH_31)) { 490d3afd28cSAthira Rajeev mask |= CNST_RADIX_SCOPE_GROUP_MASK; 491d3afd28cSAthira Rajeev value |= CNST_RADIX_SCOPE_GROUP_VAL(event >> p10_EVENT_RADIX_SCOPE_QUAL_SHIFT); 492d3afd28cSAthira Rajeev } 493d3afd28cSAthira Rajeev 49478b4416aSMadhavan Srinivasan if (is_event_marked(event)) { 4957ffd948fSMadhavan Srinivasan mask |= CNST_SAMPLE_MASK; 4967ffd948fSMadhavan Srinivasan value |= CNST_SAMPLE_VAL(event >> EVENT_SAMPLE_SHIFT); 4977ffd948fSMadhavan Srinivasan } 4987ffd948fSMadhavan Srinivasan 4990263bbb3SAthira Rajeev if (cpu_has_feature(CPU_FTR_ARCH_31)) { 50082d2c16bSKajol Jain if (event_is_threshold(event) && is_thresh_cmp_valid(event_config1)) { 5010263bbb3SAthira Rajeev mask |= CNST_THRESH_CTL_SEL_MASK; 5020263bbb3SAthira Rajeev value |= CNST_THRESH_CTL_SEL_VAL(event >> EVENT_THRESH_SHIFT); 50382d2c16bSKajol Jain mask |= p10_CNST_THRESH_CMP_MASK; 50482d2c16bSKajol Jain value |= p10_CNST_THRESH_CMP_VAL(p10_thresh_cmp_val(event_config1)); 505*505d3165SKajol Jain } else if (event_is_threshold(event)) 506*505d3165SKajol Jain return -1; 5070263bbb3SAthira Rajeev } else if (cpu_has_feature(CPU_FTR_ARCH_300)) { 50878a16d9fSMadhavan Srinivasan if (event_is_threshold(event) && is_thresh_cmp_valid(event)) { 50978a16d9fSMadhavan Srinivasan mask |= CNST_THRESH_MASK; 51078a16d9fSMadhavan Srinivasan value |= CNST_THRESH_VAL(event >> EVENT_THRESH_SHIFT); 51178a16d9fSMadhavan Srinivasan } 51278a16d9fSMadhavan Srinivasan } else { 5137ffd948fSMadhavan Srinivasan /* 5147ffd948fSMadhavan Srinivasan * Special case for PM_MRK_FAB_RSP_MATCH and PM_MRK_FAB_RSP_MATCH_CYC, 5157ffd948fSMadhavan Srinivasan * the threshold control bits are used for the match value. 5167ffd948fSMadhavan Srinivasan */ 5177ffd948fSMadhavan Srinivasan if (event_is_fab_match(event)) { 5187ffd948fSMadhavan Srinivasan mask |= CNST_FAB_MATCH_MASK; 5197ffd948fSMadhavan Srinivasan value |= CNST_FAB_MATCH_VAL(event >> EVENT_THR_CTL_SHIFT); 5207ffd948fSMadhavan Srinivasan } else { 52178a16d9fSMadhavan Srinivasan if (!is_thresh_cmp_valid(event)) 5227ffd948fSMadhavan Srinivasan return -1; 5237ffd948fSMadhavan Srinivasan 5247ffd948fSMadhavan Srinivasan mask |= CNST_THRESH_MASK; 5257ffd948fSMadhavan Srinivasan value |= CNST_THRESH_VAL(event >> EVENT_THRESH_SHIFT); 5267ffd948fSMadhavan Srinivasan } 52778a16d9fSMadhavan Srinivasan } 5287ffd948fSMadhavan Srinivasan 5293b6c3adbSAthira Rajeev ebb_bhrb: 5307ffd948fSMadhavan Srinivasan if (!pmc && ebb) 5317ffd948fSMadhavan Srinivasan /* EBB events must specify the PMC */ 5327ffd948fSMadhavan Srinivasan return -1; 5337ffd948fSMadhavan Srinivasan 5347ffd948fSMadhavan Srinivasan if (event & EVENT_WANTS_BHRB) { 5357ffd948fSMadhavan Srinivasan if (!ebb) 5367ffd948fSMadhavan Srinivasan /* Only EBB events can request BHRB */ 5377ffd948fSMadhavan Srinivasan return -1; 5387ffd948fSMadhavan Srinivasan 5397ffd948fSMadhavan Srinivasan mask |= CNST_IFM_MASK; 5407ffd948fSMadhavan Srinivasan value |= CNST_IFM_VAL(event >> EVENT_IFM_SHIFT); 5417ffd948fSMadhavan Srinivasan } 5427ffd948fSMadhavan Srinivasan 5437ffd948fSMadhavan Srinivasan /* 5447ffd948fSMadhavan Srinivasan * All events must agree on EBB, either all request it or none. 5457ffd948fSMadhavan Srinivasan * EBB events are pinned & exclusive, so this should never actually 5467ffd948fSMadhavan Srinivasan * hit, but we leave it as a fallback in case. 5477ffd948fSMadhavan Srinivasan */ 54810f8f961SAthira Rajeev mask |= CNST_EBB_MASK; 54910f8f961SAthira Rajeev value |= CNST_EBB_VAL(ebb); 5507ffd948fSMadhavan Srinivasan 5517ffd948fSMadhavan Srinivasan *maskp = mask; 5527ffd948fSMadhavan Srinivasan *valp = value; 5537ffd948fSMadhavan Srinivasan 5547ffd948fSMadhavan Srinivasan return 0; 5557ffd948fSMadhavan Srinivasan } 5567ffd948fSMadhavan Srinivasan 5577ffd948fSMadhavan Srinivasan int isa207_compute_mmcr(u64 event[], int n_ev, 55878d76819SAthira Rajeev unsigned int hwc[], struct mmcr_regs *mmcr, 55982d2c16bSKajol Jain struct perf_event *pevents[], u32 flags) 5607ffd948fSMadhavan Srinivasan { 5617ffd948fSMadhavan Srinivasan unsigned long mmcra, mmcr1, mmcr2, unit, combine, psel, cache, val; 562a64e697cSAthira Rajeev unsigned long mmcr3; 5637ffd948fSMadhavan Srinivasan unsigned int pmc, pmc_inuse; 5647ffd948fSMadhavan Srinivasan int i; 5657ffd948fSMadhavan Srinivasan 5667ffd948fSMadhavan Srinivasan pmc_inuse = 0; 5677ffd948fSMadhavan Srinivasan 5687ffd948fSMadhavan Srinivasan /* First pass to count resource use */ 5697ffd948fSMadhavan Srinivasan for (i = 0; i < n_ev; ++i) { 5707ffd948fSMadhavan Srinivasan pmc = (event[i] >> EVENT_PMC_SHIFT) & EVENT_PMC_MASK; 5717ffd948fSMadhavan Srinivasan if (pmc) 5727ffd948fSMadhavan Srinivasan pmc_inuse |= 1 << pmc; 5737ffd948fSMadhavan Srinivasan } 5747ffd948fSMadhavan Srinivasan 575a64e697cSAthira Rajeev mmcra = mmcr1 = mmcr2 = mmcr3 = 0; 5767ffd948fSMadhavan Srinivasan 5771cade527SAthira Rajeev /* 5781cade527SAthira Rajeev * Disable bhrb unless explicitly requested 5791cade527SAthira Rajeev * by setting MMCRA (BHRBRD) bit. 5801cade527SAthira Rajeev */ 5811cade527SAthira Rajeev if (cpu_has_feature(CPU_FTR_ARCH_31)) 5821cade527SAthira Rajeev mmcra |= MMCRA_BHRB_DISABLE; 5831cade527SAthira Rajeev 5847ffd948fSMadhavan Srinivasan /* Second pass: assign PMCs, set all MMCR1 fields */ 5857ffd948fSMadhavan Srinivasan for (i = 0; i < n_ev; ++i) { 5867ffd948fSMadhavan Srinivasan pmc = (event[i] >> EVENT_PMC_SHIFT) & EVENT_PMC_MASK; 5877ffd948fSMadhavan Srinivasan unit = (event[i] >> EVENT_UNIT_SHIFT) & EVENT_UNIT_MASK; 588c7c3f568SMadhavan Srinivasan combine = combine_from_event(event[i]); 5897ffd948fSMadhavan Srinivasan psel = event[i] & EVENT_PSEL_MASK; 5907ffd948fSMadhavan Srinivasan 5917ffd948fSMadhavan Srinivasan if (!pmc) { 5927ffd948fSMadhavan Srinivasan for (pmc = 1; pmc <= 4; ++pmc) { 5937ffd948fSMadhavan Srinivasan if (!(pmc_inuse & (1 << pmc))) 5947ffd948fSMadhavan Srinivasan break; 5957ffd948fSMadhavan Srinivasan } 5967ffd948fSMadhavan Srinivasan 5977ffd948fSMadhavan Srinivasan pmc_inuse |= 1 << pmc; 5987ffd948fSMadhavan Srinivasan } 5997ffd948fSMadhavan Srinivasan 6007ffd948fSMadhavan Srinivasan if (pmc <= 4) { 6017ffd948fSMadhavan Srinivasan mmcr1 |= unit << MMCR1_UNIT_SHIFT(pmc); 602c7c3f568SMadhavan Srinivasan mmcr1 |= combine << combine_shift(pmc); 6037ffd948fSMadhavan Srinivasan mmcr1 |= psel << MMCR1_PMCSEL_SHIFT(pmc); 6047ffd948fSMadhavan Srinivasan } 6057ffd948fSMadhavan Srinivasan 606c7c3f568SMadhavan Srinivasan /* In continuous sampling mode, update SDAR on TLB miss */ 60778b4416aSMadhavan Srinivasan mmcra_sdar_mode(event[i], &mmcra); 608c7c3f568SMadhavan Srinivasan 6092d46d487SMadhavan Srinivasan if (cpu_has_feature(CPU_FTR_ARCH_300)) { 6102d46d487SMadhavan Srinivasan cache = dc_ic_rld_quad_l1_sel(event[i]); 6112d46d487SMadhavan Srinivasan mmcr1 |= (cache) << MMCR1_DC_IC_QUAL_SHIFT; 6122d46d487SMadhavan Srinivasan } else { 6137ffd948fSMadhavan Srinivasan if (event[i] & EVENT_IS_L1) { 6142d46d487SMadhavan Srinivasan cache = dc_ic_rld_quad_l1_sel(event[i]); 6152d46d487SMadhavan Srinivasan mmcr1 |= (cache) << MMCR1_DC_IC_QUAL_SHIFT; 6162d46d487SMadhavan Srinivasan } 6177ffd948fSMadhavan Srinivasan } 6187ffd948fSMadhavan Srinivasan 619d3afd28cSAthira Rajeev /* Set RADIX_SCOPE_QUAL bit */ 620d3afd28cSAthira Rajeev if (cpu_has_feature(CPU_FTR_ARCH_31)) { 621d3afd28cSAthira Rajeev val = (event[i] >> p10_EVENT_RADIX_SCOPE_QUAL_SHIFT) & 622d3afd28cSAthira Rajeev p10_EVENT_RADIX_SCOPE_QUAL_MASK; 623d3afd28cSAthira Rajeev mmcr1 |= val << p10_MMCR1_RADIX_SCOPE_QUAL_SHIFT; 624d3afd28cSAthira Rajeev } 625d3afd28cSAthira Rajeev 62678b4416aSMadhavan Srinivasan if (is_event_marked(event[i])) { 6277ffd948fSMadhavan Srinivasan mmcra |= MMCRA_SAMPLE_ENABLE; 6287ffd948fSMadhavan Srinivasan 6297ffd948fSMadhavan Srinivasan val = (event[i] >> EVENT_SAMPLE_SHIFT) & EVENT_SAMPLE_MASK; 6307ffd948fSMadhavan Srinivasan if (val) { 6317ffd948fSMadhavan Srinivasan mmcra |= (val & 3) << MMCRA_SAMP_MODE_SHIFT; 6327ffd948fSMadhavan Srinivasan mmcra |= (val >> 2) << MMCRA_SAMP_ELIG_SHIFT; 6337ffd948fSMadhavan Srinivasan } 6347ffd948fSMadhavan Srinivasan } 6357ffd948fSMadhavan Srinivasan 6367ffd948fSMadhavan Srinivasan /* 6377ffd948fSMadhavan Srinivasan * PM_MRK_FAB_RSP_MATCH and PM_MRK_FAB_RSP_MATCH_CYC, 6387ffd948fSMadhavan Srinivasan * the threshold bits are used for the match value. 6397ffd948fSMadhavan Srinivasan */ 64078a16d9fSMadhavan Srinivasan if (!cpu_has_feature(CPU_FTR_ARCH_300) && event_is_fab_match(event[i])) { 6417ffd948fSMadhavan Srinivasan mmcr1 |= ((event[i] >> EVENT_THR_CTL_SHIFT) & 6427ffd948fSMadhavan Srinivasan EVENT_THR_CTL_MASK) << MMCR1_FAB_SHIFT; 6437ffd948fSMadhavan Srinivasan } else { 6447ffd948fSMadhavan Srinivasan val = (event[i] >> EVENT_THR_CTL_SHIFT) & EVENT_THR_CTL_MASK; 6457ffd948fSMadhavan Srinivasan mmcra |= val << MMCRA_THR_CTL_SHIFT; 6467ffd948fSMadhavan Srinivasan val = (event[i] >> EVENT_THR_SEL_SHIFT) & EVENT_THR_SEL_MASK; 6477ffd948fSMadhavan Srinivasan mmcra |= val << MMCRA_THR_SEL_SHIFT; 648a64e697cSAthira Rajeev if (!cpu_has_feature(CPU_FTR_ARCH_31)) { 649a64e697cSAthira Rajeev val = (event[i] >> EVENT_THR_CMP_SHIFT) & 650a64e697cSAthira Rajeev EVENT_THR_CMP_MASK; 651c7c3f568SMadhavan Srinivasan mmcra |= thresh_cmp_val(val); 65282d2c16bSKajol Jain } else if (flags & PPMU_HAS_ATTR_CONFIG1) { 65382d2c16bSKajol Jain val = (pevents[i]->attr.config1 >> p10_EVENT_THR_CMP_SHIFT) & 65482d2c16bSKajol Jain p10_EVENT_THR_CMP_MASK; 65582d2c16bSKajol Jain mmcra |= thresh_cmp_val(val); 6567ffd948fSMadhavan Srinivasan } 657a64e697cSAthira Rajeev } 658a64e697cSAthira Rajeev 659a64e697cSAthira Rajeev if (cpu_has_feature(CPU_FTR_ARCH_31) && (unit == 6)) { 660a64e697cSAthira Rajeev val = (event[i] >> p10_L2L3_EVENT_SHIFT) & 661a64e697cSAthira Rajeev p10_EVENT_L2L3_SEL_MASK; 662a64e697cSAthira Rajeev mmcr2 |= val << p10_L2L3_SEL_SHIFT; 663a64e697cSAthira Rajeev } 6647ffd948fSMadhavan Srinivasan 6657ffd948fSMadhavan Srinivasan if (event[i] & EVENT_WANTS_BHRB) { 6667ffd948fSMadhavan Srinivasan val = (event[i] >> EVENT_IFM_SHIFT) & EVENT_IFM_MASK; 6677ffd948fSMadhavan Srinivasan mmcra |= val << MMCRA_IFM_SHIFT; 6687ffd948fSMadhavan Srinivasan } 6697ffd948fSMadhavan Srinivasan 6701cade527SAthira Rajeev /* set MMCRA (BHRBRD) to 0 if there is user request for BHRB */ 6711cade527SAthira Rajeev if (cpu_has_feature(CPU_FTR_ARCH_31) && 6721cade527SAthira Rajeev (has_branch_stack(pevents[i]) || (event[i] & EVENT_WANTS_BHRB))) 6731cade527SAthira Rajeev mmcra &= ~MMCRA_BHRB_DISABLE; 6741cade527SAthira Rajeev 6757ffd948fSMadhavan Srinivasan if (pevents[i]->attr.exclude_user) 6767ffd948fSMadhavan Srinivasan mmcr2 |= MMCR2_FCP(pmc); 6777ffd948fSMadhavan Srinivasan 6787ffd948fSMadhavan Srinivasan if (pevents[i]->attr.exclude_hv) 6797ffd948fSMadhavan Srinivasan mmcr2 |= MMCR2_FCH(pmc); 6807ffd948fSMadhavan Srinivasan 6817ffd948fSMadhavan Srinivasan if (pevents[i]->attr.exclude_kernel) { 6827ffd948fSMadhavan Srinivasan if (cpu_has_feature(CPU_FTR_HVMODE)) 6837ffd948fSMadhavan Srinivasan mmcr2 |= MMCR2_FCH(pmc); 6847ffd948fSMadhavan Srinivasan else 6857ffd948fSMadhavan Srinivasan mmcr2 |= MMCR2_FCS(pmc); 6867ffd948fSMadhavan Srinivasan } 6877ffd948fSMadhavan Srinivasan 688a64e697cSAthira Rajeev if (cpu_has_feature(CPU_FTR_ARCH_31)) { 689a64e697cSAthira Rajeev if (pmc <= 4) { 690a64e697cSAthira Rajeev val = (event[i] >> p10_EVENT_MMCR3_SHIFT) & 691a64e697cSAthira Rajeev p10_EVENT_MMCR3_MASK; 692a64e697cSAthira Rajeev mmcr3 |= val << MMCR3_SHIFT(pmc); 693a64e697cSAthira Rajeev } 694a64e697cSAthira Rajeev } 695a64e697cSAthira Rajeev 6967ffd948fSMadhavan Srinivasan hwc[i] = pmc - 1; 6977ffd948fSMadhavan Srinivasan } 6987ffd948fSMadhavan Srinivasan 6997ffd948fSMadhavan Srinivasan /* Return MMCRx values */ 70078d76819SAthira Rajeev mmcr->mmcr0 = 0; 7017ffd948fSMadhavan Srinivasan 7027ffd948fSMadhavan Srinivasan /* pmc_inuse is 1-based */ 7037ffd948fSMadhavan Srinivasan if (pmc_inuse & 2) 70478d76819SAthira Rajeev mmcr->mmcr0 = MMCR0_PMC1CE; 7057ffd948fSMadhavan Srinivasan 7067ffd948fSMadhavan Srinivasan if (pmc_inuse & 0x7c) 70778d76819SAthira Rajeev mmcr->mmcr0 |= MMCR0_PMCjCE; 7087ffd948fSMadhavan Srinivasan 7097ffd948fSMadhavan Srinivasan /* If we're not using PMC 5 or 6, freeze them */ 7107ffd948fSMadhavan Srinivasan if (!(pmc_inuse & 0x60)) 71178d76819SAthira Rajeev mmcr->mmcr0 |= MMCR0_FC56; 7127ffd948fSMadhavan Srinivasan 71391668ab7SAthira Rajeev /* 71491668ab7SAthira Rajeev * Set mmcr0 (PMCCEXT) for p10 which 71591668ab7SAthira Rajeev * will restrict access to group B registers 71691668ab7SAthira Rajeev * when MMCR0 PMCC=0b00. 71791668ab7SAthira Rajeev */ 71891668ab7SAthira Rajeev if (cpu_has_feature(CPU_FTR_ARCH_31)) 71991668ab7SAthira Rajeev mmcr->mmcr0 |= MMCR0_PMCCEXT; 72091668ab7SAthira Rajeev 72178d76819SAthira Rajeev mmcr->mmcr1 = mmcr1; 72278d76819SAthira Rajeev mmcr->mmcra = mmcra; 72378d76819SAthira Rajeev mmcr->mmcr2 = mmcr2; 724a64e697cSAthira Rajeev mmcr->mmcr3 = mmcr3; 7257ffd948fSMadhavan Srinivasan 7267ffd948fSMadhavan Srinivasan return 0; 7277ffd948fSMadhavan Srinivasan } 7287ffd948fSMadhavan Srinivasan 72978d76819SAthira Rajeev void isa207_disable_pmc(unsigned int pmc, struct mmcr_regs *mmcr) 7307ffd948fSMadhavan Srinivasan { 7317ffd948fSMadhavan Srinivasan if (pmc <= 3) 73278d76819SAthira Rajeev mmcr->mmcr1 &= ~(0xffUL << MMCR1_PMCSEL_SHIFT(pmc + 1)); 7337ffd948fSMadhavan Srinivasan } 734efe881afSMadhavan Srinivasan 735efe881afSMadhavan Srinivasan static int find_alternative(u64 event, const unsigned int ev_alt[][MAX_ALT], int size) 736efe881afSMadhavan Srinivasan { 737efe881afSMadhavan Srinivasan int i, j; 738efe881afSMadhavan Srinivasan 739efe881afSMadhavan Srinivasan for (i = 0; i < size; ++i) { 740efe881afSMadhavan Srinivasan if (event < ev_alt[i][0]) 741efe881afSMadhavan Srinivasan break; 742efe881afSMadhavan Srinivasan 743efe881afSMadhavan Srinivasan for (j = 0; j < MAX_ALT && ev_alt[i][j]; ++j) 744efe881afSMadhavan Srinivasan if (event == ev_alt[i][j]) 745efe881afSMadhavan Srinivasan return i; 746efe881afSMadhavan Srinivasan } 747efe881afSMadhavan Srinivasan 748efe881afSMadhavan Srinivasan return -1; 749efe881afSMadhavan Srinivasan } 750efe881afSMadhavan Srinivasan 75170a7e720SMadhavan Srinivasan int isa207_get_alternatives(u64 event, u64 alt[], int size, unsigned int flags, 75270a7e720SMadhavan Srinivasan const unsigned int ev_alt[][MAX_ALT]) 753efe881afSMadhavan Srinivasan { 754efe881afSMadhavan Srinivasan int i, j, num_alt = 0; 755efe881afSMadhavan Srinivasan u64 alt_event; 756efe881afSMadhavan Srinivasan 757efe881afSMadhavan Srinivasan alt[num_alt++] = event; 758efe881afSMadhavan Srinivasan i = find_alternative(event, ev_alt, size); 759efe881afSMadhavan Srinivasan if (i >= 0) { 760efe881afSMadhavan Srinivasan /* Filter out the original event, it's already in alt[0] */ 761efe881afSMadhavan Srinivasan for (j = 0; j < MAX_ALT; ++j) { 762efe881afSMadhavan Srinivasan alt_event = ev_alt[i][j]; 763efe881afSMadhavan Srinivasan if (alt_event && alt_event != event) 764efe881afSMadhavan Srinivasan alt[num_alt++] = alt_event; 765efe881afSMadhavan Srinivasan } 766efe881afSMadhavan Srinivasan } 767efe881afSMadhavan Srinivasan 76870a7e720SMadhavan Srinivasan if (flags & PPMU_ONLY_COUNT_RUN) { 76970a7e720SMadhavan Srinivasan /* 77070a7e720SMadhavan Srinivasan * We're only counting in RUN state, so PM_CYC is equivalent to 77170a7e720SMadhavan Srinivasan * PM_RUN_CYC and PM_INST_CMPL === PM_RUN_INST_CMPL. 77270a7e720SMadhavan Srinivasan */ 77370a7e720SMadhavan Srinivasan j = num_alt; 77470a7e720SMadhavan Srinivasan for (i = 0; i < num_alt; ++i) { 77570a7e720SMadhavan Srinivasan switch (alt[i]) { 77670a7e720SMadhavan Srinivasan case 0x1e: /* PMC_CYC */ 77770a7e720SMadhavan Srinivasan alt[j++] = 0x600f4; /* PM_RUN_CYC */ 77870a7e720SMadhavan Srinivasan break; 77970a7e720SMadhavan Srinivasan case 0x600f4: 78070a7e720SMadhavan Srinivasan alt[j++] = 0x1e; 78170a7e720SMadhavan Srinivasan break; 78270a7e720SMadhavan Srinivasan case 0x2: /* PM_INST_CMPL */ 78370a7e720SMadhavan Srinivasan alt[j++] = 0x500fa; /* PM_RUN_INST_CMPL */ 78470a7e720SMadhavan Srinivasan break; 78570a7e720SMadhavan Srinivasan case 0x500fa: 78670a7e720SMadhavan Srinivasan alt[j++] = 0x2; 78770a7e720SMadhavan Srinivasan break; 78870a7e720SMadhavan Srinivasan } 78970a7e720SMadhavan Srinivasan } 79070a7e720SMadhavan Srinivasan num_alt = j; 79170a7e720SMadhavan Srinivasan } 79270a7e720SMadhavan Srinivasan 793efe881afSMadhavan Srinivasan return num_alt; 794efe881afSMadhavan Srinivasan } 795d8a1d6c5SMadhavan Srinivasan 796d8a1d6c5SMadhavan Srinivasan int isa3XX_check_attr_config(struct perf_event *ev) 797d8a1d6c5SMadhavan Srinivasan { 798d8a1d6c5SMadhavan Srinivasan u64 val, sample_mode; 799d8a1d6c5SMadhavan Srinivasan u64 event = ev->attr.config; 800d8a1d6c5SMadhavan Srinivasan 801d8a1d6c5SMadhavan Srinivasan val = (event >> EVENT_SAMPLE_SHIFT) & EVENT_SAMPLE_MASK; 802d8a1d6c5SMadhavan Srinivasan sample_mode = val & 0x3; 803d8a1d6c5SMadhavan Srinivasan 804d8a1d6c5SMadhavan Srinivasan /* 805d8a1d6c5SMadhavan Srinivasan * MMCRA[61:62] is Random Sampling Mode (SM). 806d8a1d6c5SMadhavan Srinivasan * value of 0b11 is reserved. 807d8a1d6c5SMadhavan Srinivasan */ 808d8a1d6c5SMadhavan Srinivasan if (sample_mode == 0x3) 809d8a1d6c5SMadhavan Srinivasan return -EINVAL; 810d8a1d6c5SMadhavan Srinivasan 811d8a1d6c5SMadhavan Srinivasan /* 812d8a1d6c5SMadhavan Srinivasan * Check for all reserved value 813d8a1d6c5SMadhavan Srinivasan * Source: Performance Monitoring Unit User Guide 814d8a1d6c5SMadhavan Srinivasan */ 815d8a1d6c5SMadhavan Srinivasan switch (val) { 816d8a1d6c5SMadhavan Srinivasan case 0x5: 817d8a1d6c5SMadhavan Srinivasan case 0x9: 818d8a1d6c5SMadhavan Srinivasan case 0xD: 819d8a1d6c5SMadhavan Srinivasan case 0x19: 820d8a1d6c5SMadhavan Srinivasan case 0x1D: 821d8a1d6c5SMadhavan Srinivasan case 0x1A: 822d8a1d6c5SMadhavan Srinivasan case 0x1E: 823d8a1d6c5SMadhavan Srinivasan return -EINVAL; 824d8a1d6c5SMadhavan Srinivasan } 825d8a1d6c5SMadhavan Srinivasan 826d8a1d6c5SMadhavan Srinivasan /* 827d8a1d6c5SMadhavan Srinivasan * MMCRA[48:51]/[52:55]) Threshold Start/Stop 828d8a1d6c5SMadhavan Srinivasan * Events Selection. 829d8a1d6c5SMadhavan Srinivasan * 0b11110000/0b00001111 is reserved. 830d8a1d6c5SMadhavan Srinivasan */ 831d8a1d6c5SMadhavan Srinivasan val = (event >> EVENT_THR_CTL_SHIFT) & EVENT_THR_CTL_MASK; 832d8a1d6c5SMadhavan Srinivasan if (((val & 0xF0) == 0xF0) || ((val & 0xF) == 0xF)) 833d8a1d6c5SMadhavan Srinivasan return -EINVAL; 834d8a1d6c5SMadhavan Srinivasan 835d8a1d6c5SMadhavan Srinivasan return 0; 836d8a1d6c5SMadhavan Srinivasan } 837