aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/power5+-pmu.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/power5+-pmu.c')
-rw-r--r--arch/powerpc/kernel/power5+-pmu.c95
1 files changed, 56 insertions, 39 deletions
diff --git a/arch/powerpc/kernel/power5+-pmu.c b/arch/powerpc/kernel/power5+-pmu.c
index 41e5d2d958d4..f4adca8e98a4 100644
--- a/arch/powerpc/kernel/power5+-pmu.c
+++ b/arch/powerpc/kernel/power5+-pmu.c
@@ -10,7 +10,9 @@
10 */ 10 */
11#include <linux/kernel.h> 11#include <linux/kernel.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 POWER5+ (POWER5 GS) and POWER5++ (POWER5 GS DD3) 18 * Bits in event code for POWER5+ (POWER5 GS) and POWER5++ (POWER5 GS DD3)
@@ -126,20 +128,21 @@ static const int grsel_shift[8] = {
126}; 128};
127 129
128/* Masks and values for using events from the various units */ 130/* Masks and values for using events from the various units */
129static u64 unit_cons[PM_LASTUNIT+1][2] = { 131static unsigned long unit_cons[PM_LASTUNIT+1][2] = {
130 [PM_FPU] = { 0x3200000000ull, 0x0100000000ull }, 132 [PM_FPU] = { 0x3200000000ul, 0x0100000000ul },
131 [PM_ISU0] = { 0x0200000000ull, 0x0080000000ull }, 133 [PM_ISU0] = { 0x0200000000ul, 0x0080000000ul },
132 [PM_ISU1] = { 0x3200000000ull, 0x3100000000ull }, 134 [PM_ISU1] = { 0x3200000000ul, 0x3100000000ul },
133 [PM_IFU] = { 0x3200000000ull, 0x2100000000ull }, 135 [PM_IFU] = { 0x3200000000ul, 0x2100000000ul },
134 [PM_IDU] = { 0x0e00000000ull, 0x0040000000ull }, 136 [PM_IDU] = { 0x0e00000000ul, 0x0040000000ul },
135 [PM_GRS] = { 0x0e00000000ull, 0x0c40000000ull }, 137 [PM_GRS] = { 0x0e00000000ul, 0x0c40000000ul },
136}; 138};
137 139
138static int power5p_get_constraint(u64 event, u64 *maskp, u64 *valp) 140static int power5p_get_constraint(u64 event, unsigned long *maskp,
141 unsigned long *valp)
139{ 142{
140 int pmc, byte, unit, sh; 143 int pmc, byte, unit, sh;
141 int bit, fmask; 144 int bit, fmask;
142 u64 mask = 0, value = 0; 145 unsigned long mask = 0, value = 0;
143 146
144 pmc = (event >> PM_PMC_SH) & PM_PMC_MSK; 147 pmc = (event >> PM_PMC_SH) & PM_PMC_MSK;
145 if (pmc) { 148 if (pmc) {
@@ -171,17 +174,18 @@ static int power5p_get_constraint(u64 event, u64 *maskp, u64 *valp)
171 bit = event & 7; 174 bit = event & 7;
172 fmask = (bit == 6)? 7: 3; 175 fmask = (bit == 6)? 7: 3;
173 sh = grsel_shift[bit]; 176 sh = grsel_shift[bit];
174 mask |= (u64)fmask << sh; 177 mask |= (unsigned long)fmask << sh;
175 value |= (u64)((event >> PM_GRS_SH) & fmask) << sh; 178 value |= (unsigned long)((event >> PM_GRS_SH) & fmask)
179 << sh;
176 } 180 }
177 /* Set byte lane select field */ 181 /* Set byte lane select field */
178 mask |= 0xfULL << (24 - 4 * byte); 182 mask |= 0xfUL << (24 - 4 * byte);
179 value |= (u64)unit << (24 - 4 * byte); 183 value |= (unsigned long)unit << (24 - 4 * byte);
180 } 184 }
181 if (pmc < 5) { 185 if (pmc < 5) {
182 /* need a counter from PMC1-4 set */ 186 /* need a counter from PMC1-4 set */
183 mask |= 0x8000000000000ull; 187 mask |= 0x8000000000000ul;
184 value |= 0x1000000000000ull; 188 value |= 0x1000000000000ul;
185 } 189 }
186 *maskp = mask; 190 *maskp = mask;
187 *valp = value; 191 *valp = value;
@@ -452,10 +456,10 @@ static int power5p_marked_instr_event(u64 event)
452} 456}
453 457
454static int power5p_compute_mmcr(u64 event[], int n_ev, 458static int power5p_compute_mmcr(u64 event[], int n_ev,
455 unsigned int hwc[], u64 mmcr[]) 459 unsigned int hwc[], unsigned long mmcr[])
456{ 460{
457 u64 mmcr1 = 0; 461 unsigned long mmcr1 = 0;
458 u64 mmcra = 0; 462 unsigned long mmcra = 0;
459 unsigned int pmc, unit, byte, psel; 463 unsigned int pmc, unit, byte, psel;
460 unsigned int ttm; 464 unsigned int ttm;
461 int i, isbus, bit, grsel; 465 int i, isbus, bit, grsel;
@@ -517,7 +521,7 @@ static int power5p_compute_mmcr(u64 event[], int n_ev,
517 continue; 521 continue;
518 if (ttmuse++) 522 if (ttmuse++)
519 return -1; 523 return -1;
520 mmcr1 |= (u64)i << MMCR1_TTM0SEL_SH; 524 mmcr1 |= (unsigned long)i << MMCR1_TTM0SEL_SH;
521 } 525 }
522 ttmuse = 0; 526 ttmuse = 0;
523 for (; i <= PM_GRS; ++i) { 527 for (; i <= PM_GRS; ++i) {
@@ -525,7 +529,7 @@ static int power5p_compute_mmcr(u64 event[], int n_ev,
525 continue; 529 continue;
526 if (ttmuse++) 530 if (ttmuse++)
527 return -1; 531 return -1;
528 mmcr1 |= (u64)(i & 3) << MMCR1_TTM1SEL_SH; 532 mmcr1 |= (unsigned long)(i & 3) << MMCR1_TTM1SEL_SH;
529 } 533 }
530 if (ttmuse > 1) 534 if (ttmuse > 1)
531 return -1; 535 return -1;
@@ -540,10 +544,11 @@ static int power5p_compute_mmcr(u64 event[], int n_ev,
540 unit = PM_ISU0_ALT; 544 unit = PM_ISU0_ALT;
541 } else if (unit == PM_LSU1 + 1) { 545 } else if (unit == PM_LSU1 + 1) {
542 /* select lower word of LSU1 for this byte */ 546 /* select lower word of LSU1 for this byte */
543 mmcr1 |= 1ull << (MMCR1_TTM3SEL_SH + 3 - byte); 547 mmcr1 |= 1ul << (MMCR1_TTM3SEL_SH + 3 - byte);
544 } 548 }
545 ttm = unit >> 2; 549 ttm = unit >> 2;
546 mmcr1 |= (u64)ttm << (MMCR1_TD_CP_DBG0SEL_SH - 2 * byte); 550 mmcr1 |= (unsigned long)ttm
551 << (MMCR1_TD_CP_DBG0SEL_SH - 2 * byte);
547 } 552 }
548 553
549 /* Second pass: assign PMCs, set PMCxSEL and PMCx_ADDER_SEL fields */ 554 /* Second pass: assign PMCs, set PMCxSEL and PMCx_ADDER_SEL fields */
@@ -568,7 +573,7 @@ static int power5p_compute_mmcr(u64 event[], int n_ev,
568 if (isbus && (byte & 2) && 573 if (isbus && (byte & 2) &&
569 (psel == 8 || psel == 0x10 || psel == 0x28)) 574 (psel == 8 || psel == 0x10 || psel == 0x28))
570 /* add events on higher-numbered bus */ 575 /* add events on higher-numbered bus */
571 mmcr1 |= 1ull << (MMCR1_PMC1_ADDER_SEL_SH - pmc); 576 mmcr1 |= 1ul << (MMCR1_PMC1_ADDER_SEL_SH - pmc);
572 } else { 577 } else {
573 /* Instructions or run cycles on PMC5/6 */ 578 /* Instructions or run cycles on PMC5/6 */
574 --pmc; 579 --pmc;
@@ -576,7 +581,7 @@ static int power5p_compute_mmcr(u64 event[], int n_ev,
576 if (isbus && unit == PM_GRS) { 581 if (isbus && unit == PM_GRS) {
577 bit = psel & 7; 582 bit = psel & 7;
578 grsel = (event[i] >> PM_GRS_SH) & PM_GRS_MSK; 583 grsel = (event[i] >> PM_GRS_SH) & PM_GRS_MSK;
579 mmcr1 |= (u64)grsel << grsel_shift[bit]; 584 mmcr1 |= (unsigned long)grsel << grsel_shift[bit];
580 } 585 }
581 if (power5p_marked_instr_event(event[i])) 586 if (power5p_marked_instr_event(event[i]))
582 mmcra |= MMCRA_SAMPLE_ENABLE; 587 mmcra |= MMCRA_SAMPLE_ENABLE;
@@ -599,7 +604,7 @@ static int power5p_compute_mmcr(u64 event[], int n_ev,
599 return 0; 604 return 0;
600} 605}
601 606
602static void power5p_disable_pmc(unsigned int pmc, u64 mmcr[]) 607static void power5p_disable_pmc(unsigned int pmc, unsigned long mmcr[])
603{ 608{
604 if (pmc <= 3) 609 if (pmc <= 3)
605 mmcr[1] &= ~(0x7fUL << MMCR1_PMCSEL_SH(pmc)); 610 mmcr[1] &= ~(0x7fUL << MMCR1_PMCSEL_SH(pmc));
@@ -654,18 +659,30 @@ static int power5p_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = {
654 }, 659 },
655}; 660};
656 661
657struct power_pmu power5p_pmu = { 662static struct power_pmu power5p_pmu = {
658 .n_counter = 6, 663 .name = "POWER5+/++",
659 .max_alternatives = MAX_ALT, 664 .n_counter = 6,
660 .add_fields = 0x7000000000055ull, 665 .max_alternatives = MAX_ALT,
661 .test_adder = 0x3000040000000ull, 666 .add_fields = 0x7000000000055ul,
662 .compute_mmcr = power5p_compute_mmcr, 667 .test_adder = 0x3000040000000ul,
663 .get_constraint = power5p_get_constraint, 668 .compute_mmcr = power5p_compute_mmcr,
664 .get_alternatives = power5p_get_alternatives, 669 .get_constraint = power5p_get_constraint,
665 .disable_pmc = power5p_disable_pmc, 670 .get_alternatives = power5p_get_alternatives,
666 .limited_pmc_event = power5p_limited_pmc_event, 671 .disable_pmc = power5p_disable_pmc,
667 .flags = PPMU_LIMITED_PMC5_6, 672 .limited_pmc_event = power5p_limited_pmc_event,
668 .n_generic = ARRAY_SIZE(power5p_generic_events), 673 .flags = PPMU_LIMITED_PMC5_6,
669 .generic_events = power5p_generic_events, 674 .n_generic = ARRAY_SIZE(power5p_generic_events),
670 .cache_events = &power5p_cache_events, 675 .generic_events = power5p_generic_events,
676 .cache_events = &power5p_cache_events,
671}; 677};
678
679static int init_power5p_pmu(void)
680{
681 if (strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc64/power5+")
682 && strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc64/power5++"))
683 return -ENODEV;
684
685 return register_power_pmu(&power5p_pmu);
686}
687
688arch_initcall(init_power5p_pmu);