diff options
Diffstat (limited to 'arch/powerpc/kernel/ppc970-pmu.c')
-rw-r--r-- | arch/powerpc/kernel/ppc970-pmu.c | 63 |
1 files changed, 40 insertions, 23 deletions
diff --git a/arch/powerpc/kernel/ppc970-pmu.c b/arch/powerpc/kernel/ppc970-pmu.c index ba0a357a89f4..6637c87fe70e 100644 --- a/arch/powerpc/kernel/ppc970-pmu.c +++ b/arch/powerpc/kernel/ppc970-pmu.c | |||
@@ -10,7 +10,9 @@ | |||
10 | */ | 10 | */ |
11 | #include <linux/string.h> | 11 | #include <linux/string.h> |
12 | #include <linux/perf_counter.h> | 12 | #include <linux/perf_counter.h> |
13 | #include <linux/string.h> | ||
13 | #include <asm/reg.h> | 14 | #include <asm/reg.h> |
15 | #include <asm/cputable.h> | ||
14 | 16 | ||
15 | /* | 17 | /* |
16 | * Bits in event code for PPC970 | 18 | * Bits in event code for PPC970 |
@@ -183,7 +185,7 @@ static int p970_marked_instr_event(u64 event) | |||
183 | } | 185 | } |
184 | 186 | ||
185 | /* Masks and values for using events from the various units */ | 187 | /* Masks and values for using events from the various units */ |
186 | static u64 unit_cons[PM_LASTUNIT+1][2] = { | 188 | static unsigned long unit_cons[PM_LASTUNIT+1][2] = { |
187 | [PM_FPU] = { 0xc80000000000ull, 0x040000000000ull }, | 189 | [PM_FPU] = { 0xc80000000000ull, 0x040000000000ull }, |
188 | [PM_VPU] = { 0xc80000000000ull, 0xc40000000000ull }, | 190 | [PM_VPU] = { 0xc80000000000ull, 0xc40000000000ull }, |
189 | [PM_ISU] = { 0x080000000000ull, 0x020000000000ull }, | 191 | [PM_ISU] = { 0x080000000000ull, 0x020000000000ull }, |
@@ -192,10 +194,11 @@ static u64 unit_cons[PM_LASTUNIT+1][2] = { | |||
192 | [PM_STS] = { 0x380000000000ull, 0x310000000000ull }, | 194 | [PM_STS] = { 0x380000000000ull, 0x310000000000ull }, |
193 | }; | 195 | }; |
194 | 196 | ||
195 | static int p970_get_constraint(u64 event, u64 *maskp, u64 *valp) | 197 | static int p970_get_constraint(u64 event, unsigned long *maskp, |
198 | unsigned long *valp) | ||
196 | { | 199 | { |
197 | int pmc, byte, unit, sh, spcsel; | 200 | int pmc, byte, unit, sh, spcsel; |
198 | u64 mask = 0, value = 0; | 201 | unsigned long mask = 0, value = 0; |
199 | int grp = -1; | 202 | int grp = -1; |
200 | 203 | ||
201 | pmc = (event >> PM_PMC_SH) & PM_PMC_MSK; | 204 | pmc = (event >> PM_PMC_SH) & PM_PMC_MSK; |
@@ -222,7 +225,7 @@ static int p970_get_constraint(u64 event, u64 *maskp, u64 *valp) | |||
222 | grp = byte & 1; | 225 | grp = byte & 1; |
223 | /* Set byte lane select field */ | 226 | /* Set byte lane select field */ |
224 | mask |= 0xfULL << (28 - 4 * byte); | 227 | mask |= 0xfULL << (28 - 4 * byte); |
225 | value |= (u64)unit << (28 - 4 * byte); | 228 | value |= (unsigned long)unit << (28 - 4 * byte); |
226 | } | 229 | } |
227 | if (grp == 0) { | 230 | if (grp == 0) { |
228 | /* increment PMC1/2/5/6 field */ | 231 | /* increment PMC1/2/5/6 field */ |
@@ -236,7 +239,7 @@ static int p970_get_constraint(u64 event, u64 *maskp, u64 *valp) | |||
236 | spcsel = (event >> PM_SPCSEL_SH) & PM_SPCSEL_MSK; | 239 | spcsel = (event >> PM_SPCSEL_SH) & PM_SPCSEL_MSK; |
237 | if (spcsel) { | 240 | if (spcsel) { |
238 | mask |= 3ull << 48; | 241 | mask |= 3ull << 48; |
239 | value |= (u64)spcsel << 48; | 242 | value |= (unsigned long)spcsel << 48; |
240 | } | 243 | } |
241 | *maskp = mask; | 244 | *maskp = mask; |
242 | *valp = value; | 245 | *valp = value; |
@@ -257,9 +260,9 @@ static int p970_get_alternatives(u64 event, unsigned int flags, u64 alt[]) | |||
257 | } | 260 | } |
258 | 261 | ||
259 | static int p970_compute_mmcr(u64 event[], int n_ev, | 262 | static int p970_compute_mmcr(u64 event[], int n_ev, |
260 | unsigned int hwc[], u64 mmcr[]) | 263 | unsigned int hwc[], unsigned long mmcr[]) |
261 | { | 264 | { |
262 | u64 mmcr0 = 0, mmcr1 = 0, mmcra = 0; | 265 | unsigned long mmcr0 = 0, mmcr1 = 0, mmcra = 0; |
263 | unsigned int pmc, unit, byte, psel; | 266 | unsigned int pmc, unit, byte, psel; |
264 | unsigned int ttm, grp; | 267 | unsigned int ttm, grp; |
265 | unsigned int pmc_inuse = 0; | 268 | unsigned int pmc_inuse = 0; |
@@ -320,7 +323,7 @@ static int p970_compute_mmcr(u64 event[], int n_ev, | |||
320 | continue; | 323 | continue; |
321 | ttm = unitmap[i]; | 324 | ttm = unitmap[i]; |
322 | ++ttmuse[(ttm >> 2) & 1]; | 325 | ++ttmuse[(ttm >> 2) & 1]; |
323 | mmcr1 |= (u64)(ttm & ~4) << MMCR1_TTM1SEL_SH; | 326 | mmcr1 |= (unsigned long)(ttm & ~4) << MMCR1_TTM1SEL_SH; |
324 | } | 327 | } |
325 | /* Check only one unit per TTMx */ | 328 | /* Check only one unit per TTMx */ |
326 | if (ttmuse[0] > 1 || ttmuse[1] > 1) | 329 | if (ttmuse[0] > 1 || ttmuse[1] > 1) |
@@ -340,7 +343,8 @@ static int p970_compute_mmcr(u64 event[], int n_ev, | |||
340 | if (unit == PM_LSU1L && byte >= 2) | 343 | if (unit == PM_LSU1L && byte >= 2) |
341 | mmcr1 |= 1ull << (MMCR1_TTM3SEL_SH + 3 - byte); | 344 | mmcr1 |= 1ull << (MMCR1_TTM3SEL_SH + 3 - byte); |
342 | } | 345 | } |
343 | mmcr1 |= (u64)ttm << (MMCR1_TD_CP_DBG0SEL_SH - 2 * byte); | 346 | mmcr1 |= (unsigned long)ttm |
347 | << (MMCR1_TD_CP_DBG0SEL_SH - 2 * byte); | ||
344 | } | 348 | } |
345 | 349 | ||
346 | /* Second pass: assign PMCs, set PMCxSEL and PMCx_ADDER_SEL fields */ | 350 | /* Second pass: assign PMCs, set PMCxSEL and PMCx_ADDER_SEL fields */ |
@@ -386,7 +390,8 @@ static int p970_compute_mmcr(u64 event[], int n_ev, | |||
386 | for (pmc = 0; pmc < 2; ++pmc) | 390 | for (pmc = 0; pmc < 2; ++pmc) |
387 | mmcr0 |= pmcsel[pmc] << (MMCR0_PMC1SEL_SH - 7 * pmc); | 391 | mmcr0 |= pmcsel[pmc] << (MMCR0_PMC1SEL_SH - 7 * pmc); |
388 | for (; pmc < 8; ++pmc) | 392 | for (; pmc < 8; ++pmc) |
389 | mmcr1 |= (u64)pmcsel[pmc] << (MMCR1_PMC3SEL_SH - 5 * (pmc - 2)); | 393 | mmcr1 |= (unsigned long)pmcsel[pmc] |
394 | << (MMCR1_PMC3SEL_SH - 5 * (pmc - 2)); | ||
390 | if (pmc_inuse & 1) | 395 | if (pmc_inuse & 1) |
391 | mmcr0 |= MMCR0_PMC1CE; | 396 | mmcr0 |= MMCR0_PMC1CE; |
392 | if (pmc_inuse & 0xfe) | 397 | if (pmc_inuse & 0xfe) |
@@ -401,7 +406,7 @@ static int p970_compute_mmcr(u64 event[], int n_ev, | |||
401 | return 0; | 406 | return 0; |
402 | } | 407 | } |
403 | 408 | ||
404 | static void p970_disable_pmc(unsigned int pmc, u64 mmcr[]) | 409 | static void p970_disable_pmc(unsigned int pmc, unsigned long mmcr[]) |
405 | { | 410 | { |
406 | int shift, i; | 411 | int shift, i; |
407 | 412 | ||
@@ -467,16 +472,28 @@ static int ppc970_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = { | |||
467 | }, | 472 | }, |
468 | }; | 473 | }; |
469 | 474 | ||
470 | struct power_pmu ppc970_pmu = { | 475 | static struct power_pmu ppc970_pmu = { |
471 | .n_counter = 8, | 476 | .name = "PPC970/FX/MP", |
472 | .max_alternatives = 2, | 477 | .n_counter = 8, |
473 | .add_fields = 0x001100005555ull, | 478 | .max_alternatives = 2, |
474 | .test_adder = 0x013300000000ull, | 479 | .add_fields = 0x001100005555ull, |
475 | .compute_mmcr = p970_compute_mmcr, | 480 | .test_adder = 0x013300000000ull, |
476 | .get_constraint = p970_get_constraint, | 481 | .compute_mmcr = p970_compute_mmcr, |
477 | .get_alternatives = p970_get_alternatives, | 482 | .get_constraint = p970_get_constraint, |
478 | .disable_pmc = p970_disable_pmc, | 483 | .get_alternatives = p970_get_alternatives, |
479 | .n_generic = ARRAY_SIZE(ppc970_generic_events), | 484 | .disable_pmc = p970_disable_pmc, |
480 | .generic_events = ppc970_generic_events, | 485 | .n_generic = ARRAY_SIZE(ppc970_generic_events), |
481 | .cache_events = &ppc970_cache_events, | 486 | .generic_events = ppc970_generic_events, |
487 | .cache_events = &ppc970_cache_events, | ||
482 | }; | 488 | }; |
489 | |||
490 | static int init_ppc970_pmu(void) | ||
491 | { | ||
492 | if (strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc64/970") | ||
493 | && strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc64/970MP")) | ||
494 | return -ENODEV; | ||
495 | |||
496 | return register_power_pmu(&ppc970_pmu); | ||
497 | } | ||
498 | |||
499 | arch_initcall(init_ppc970_pmu); | ||