diff options
author | Olof Johansson <olof@lixom.net> | 2007-01-28 22:25:57 -0500 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2007-02-06 22:03:19 -0500 |
commit | 6529c13dfe413e437ad1ed0e97783dcf69137114 (patch) | |
tree | 4042f247433dd413a196764d6b3b74f05568d8e3 | |
parent | 7583b6e424ebaa278342f6a8c2a61211af56dad1 (diff) |
[POWERPC] PA6T PMC support
Support for PA6T-style PMC registers.
PMCs are completely implementation-dependent on PPC, and PA6T numbers them
differently from the IBM model.
Signed-off-by: Olof Johansson <olof@lixom.net>
Signed-off-by: Paul Mackerras <paulus@samba.org>
-rw-r--r-- | arch/powerpc/kernel/pmc.c | 4 | ||||
-rw-r--r-- | arch/powerpc/kernel/sysfs.c | 141 | ||||
-rw-r--r-- | include/asm-powerpc/reg.h | 7 |
3 files changed, 102 insertions, 50 deletions
diff --git a/arch/powerpc/kernel/pmc.c b/arch/powerpc/kernel/pmc.c index e40f6ddd98a4..24d7b7c99bb9 100644 --- a/arch/powerpc/kernel/pmc.c +++ b/arch/powerpc/kernel/pmc.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
18 | 18 | ||
19 | #include <asm/processor.h> | 19 | #include <asm/processor.h> |
20 | #include <asm/cputable.h> | ||
20 | #include <asm/pmc.h> | 21 | #include <asm/pmc.h> |
21 | 22 | ||
22 | #ifndef MMCR0_PMA0 | 23 | #ifndef MMCR0_PMA0 |
@@ -28,7 +29,8 @@ static void dummy_perf(struct pt_regs *regs) | |||
28 | #if defined(CONFIG_FSL_BOOKE) && !defined(CONFIG_E200) | 29 | #if defined(CONFIG_FSL_BOOKE) && !defined(CONFIG_E200) |
29 | mtpmr(PMRN_PMGC0, mfpmr(PMRN_PMGC0) & ~PMGC0_PMIE); | 30 | mtpmr(PMRN_PMGC0, mfpmr(PMRN_PMGC0) & ~PMGC0_PMIE); |
30 | #elif defined(CONFIG_PPC64) || defined(CONFIG_6xx) | 31 | #elif defined(CONFIG_PPC64) || defined(CONFIG_6xx) |
31 | mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) & ~(MMCR0_PMXE|MMCR0_PMA0)); | 32 | if (cur_cpu_spec->pmc_type == PPC_PMC_IBM) |
33 | mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) & ~(MMCR0_PMXE|MMCR0_PMA0)); | ||
32 | #else | 34 | #else |
33 | mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) & ~MMCR0_PMXE); | 35 | mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) & ~MMCR0_PMXE); |
34 | #endif | 36 | #endif |
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c index 400ab2b946e7..d57818aea081 100644 --- a/arch/powerpc/kernel/sysfs.c +++ b/arch/powerpc/kernel/sysfs.c | |||
@@ -169,6 +169,11 @@ static ssize_t __attribute_used__ \ | |||
169 | return count; \ | 169 | return count; \ |
170 | } | 170 | } |
171 | 171 | ||
172 | |||
173 | /* Let's define all possible registers, we'll only hook up the ones | ||
174 | * that are implemented on the current processor | ||
175 | */ | ||
176 | |||
172 | SYSFS_PMCSETUP(mmcr0, SPRN_MMCR0); | 177 | SYSFS_PMCSETUP(mmcr0, SPRN_MMCR0); |
173 | SYSFS_PMCSETUP(mmcr1, SPRN_MMCR1); | 178 | SYSFS_PMCSETUP(mmcr1, SPRN_MMCR1); |
174 | SYSFS_PMCSETUP(mmcra, SPRN_MMCRA); | 179 | SYSFS_PMCSETUP(mmcra, SPRN_MMCRA); |
@@ -184,55 +189,87 @@ SYSFS_PMCSETUP(purr, SPRN_PURR); | |||
184 | SYSFS_PMCSETUP(spurr, SPRN_SPURR); | 189 | SYSFS_PMCSETUP(spurr, SPRN_SPURR); |
185 | SYSFS_PMCSETUP(dscr, SPRN_DSCR); | 190 | SYSFS_PMCSETUP(dscr, SPRN_DSCR); |
186 | 191 | ||
187 | static SYSDEV_ATTR(mmcr0, 0600, show_mmcr0, store_mmcr0); | 192 | SYSFS_PMCSETUP(pa6t_pmc0, PA6T_SPRN_PMC0); |
188 | static SYSDEV_ATTR(mmcr1, 0600, show_mmcr1, store_mmcr1); | 193 | SYSFS_PMCSETUP(pa6t_pmc1, PA6T_SPRN_PMC1); |
194 | SYSFS_PMCSETUP(pa6t_pmc2, PA6T_SPRN_PMC2); | ||
195 | SYSFS_PMCSETUP(pa6t_pmc3, PA6T_SPRN_PMC3); | ||
196 | SYSFS_PMCSETUP(pa6t_pmc4, PA6T_SPRN_PMC4); | ||
197 | SYSFS_PMCSETUP(pa6t_pmc5, PA6T_SPRN_PMC5); | ||
198 | |||
199 | |||
189 | static SYSDEV_ATTR(mmcra, 0600, show_mmcra, store_mmcra); | 200 | static SYSDEV_ATTR(mmcra, 0600, show_mmcra, store_mmcra); |
190 | static SYSDEV_ATTR(pmc1, 0600, show_pmc1, store_pmc1); | ||
191 | static SYSDEV_ATTR(pmc2, 0600, show_pmc2, store_pmc2); | ||
192 | static SYSDEV_ATTR(pmc3, 0600, show_pmc3, store_pmc3); | ||
193 | static SYSDEV_ATTR(pmc4, 0600, show_pmc4, store_pmc4); | ||
194 | static SYSDEV_ATTR(pmc5, 0600, show_pmc5, store_pmc5); | ||
195 | static SYSDEV_ATTR(pmc6, 0600, show_pmc6, store_pmc6); | ||
196 | static SYSDEV_ATTR(pmc7, 0600, show_pmc7, store_pmc7); | ||
197 | static SYSDEV_ATTR(pmc8, 0600, show_pmc8, store_pmc8); | ||
198 | static SYSDEV_ATTR(purr, 0600, show_purr, NULL); | ||
199 | static SYSDEV_ATTR(spurr, 0600, show_spurr, NULL); | 201 | static SYSDEV_ATTR(spurr, 0600, show_spurr, NULL); |
200 | static SYSDEV_ATTR(dscr, 0600, show_dscr, store_dscr); | 202 | static SYSDEV_ATTR(dscr, 0600, show_dscr, store_dscr); |
203 | static SYSDEV_ATTR(purr, 0600, show_purr, store_purr); | ||
204 | |||
205 | static struct sysdev_attribute ibm_common_attrs[] = { | ||
206 | _SYSDEV_ATTR(mmcr0, 0600, show_mmcr0, store_mmcr0), | ||
207 | _SYSDEV_ATTR(mmcr1, 0600, show_mmcr1, store_mmcr1), | ||
208 | }; | ||
209 | |||
210 | static struct sysdev_attribute ibm_pmc_attrs[] = { | ||
211 | _SYSDEV_ATTR(pmc1, 0600, show_pmc1, store_pmc1), | ||
212 | _SYSDEV_ATTR(pmc2, 0600, show_pmc2, store_pmc2), | ||
213 | _SYSDEV_ATTR(pmc3, 0600, show_pmc3, store_pmc3), | ||
214 | _SYSDEV_ATTR(pmc4, 0600, show_pmc4, store_pmc4), | ||
215 | _SYSDEV_ATTR(pmc5, 0600, show_pmc5, store_pmc5), | ||
216 | _SYSDEV_ATTR(pmc6, 0600, show_pmc6, store_pmc6), | ||
217 | _SYSDEV_ATTR(pmc7, 0600, show_pmc7, store_pmc7), | ||
218 | _SYSDEV_ATTR(pmc8, 0600, show_pmc8, store_pmc8), | ||
219 | }; | ||
220 | |||
221 | static struct sysdev_attribute pa6t_attrs[] = { | ||
222 | _SYSDEV_ATTR(mmcr0, 0600, show_mmcr0, store_mmcr0), | ||
223 | _SYSDEV_ATTR(mmcr1, 0600, show_mmcr1, store_mmcr1), | ||
224 | _SYSDEV_ATTR(pmc0, 0600, show_pa6t_pmc0, store_pa6t_pmc0), | ||
225 | _SYSDEV_ATTR(pmc1, 0600, show_pa6t_pmc1, store_pa6t_pmc1), | ||
226 | _SYSDEV_ATTR(pmc2, 0600, show_pa6t_pmc2, store_pa6t_pmc2), | ||
227 | _SYSDEV_ATTR(pmc3, 0600, show_pa6t_pmc3, store_pa6t_pmc3), | ||
228 | _SYSDEV_ATTR(pmc4, 0600, show_pa6t_pmc4, store_pa6t_pmc4), | ||
229 | _SYSDEV_ATTR(pmc5, 0600, show_pa6t_pmc5, store_pa6t_pmc5), | ||
230 | }; | ||
231 | |||
201 | 232 | ||
202 | static void register_cpu_online(unsigned int cpu) | 233 | static void register_cpu_online(unsigned int cpu) |
203 | { | 234 | { |
204 | struct cpu *c = &per_cpu(cpu_devices, cpu); | 235 | struct cpu *c = &per_cpu(cpu_devices, cpu); |
205 | struct sys_device *s = &c->sysdev; | 236 | struct sys_device *s = &c->sysdev; |
237 | struct sysdev_attribute *attrs, *pmc_attrs; | ||
238 | int i, nattrs; | ||
206 | 239 | ||
207 | if (!firmware_has_feature(FW_FEATURE_ISERIES) && | 240 | if (!firmware_has_feature(FW_FEATURE_ISERIES) && |
208 | cpu_has_feature(CPU_FTR_SMT)) | 241 | cpu_has_feature(CPU_FTR_SMT)) |
209 | sysdev_create_file(s, &attr_smt_snooze_delay); | 242 | sysdev_create_file(s, &attr_smt_snooze_delay); |
210 | 243 | ||
211 | /* PMC stuff */ | 244 | /* PMC stuff */ |
245 | switch (cur_cpu_spec->pmc_type) { | ||
246 | case PPC_PMC_IBM: | ||
247 | attrs = ibm_common_attrs; | ||
248 | nattrs = sizeof(ibm_common_attrs) / sizeof(struct sysdev_attribute); | ||
249 | pmc_attrs = ibm_pmc_attrs; | ||
250 | break; | ||
251 | case PPC_PMC_PA6T: | ||
252 | /* PA Semi starts counting at PMC0 */ | ||
253 | attrs = pa6t_attrs; | ||
254 | nattrs = sizeof(pa6t_attrs) / sizeof(struct sysdev_attribute); | ||
255 | pmc_attrs = NULL; | ||
256 | break; | ||
257 | default: | ||
258 | attrs = NULL; | ||
259 | nattrs = 0; | ||
260 | pmc_attrs = NULL; | ||
261 | } | ||
262 | |||
263 | for (i = 0; i < nattrs; i++) | ||
264 | sysdev_create_file(s, &attrs[i]); | ||
212 | 265 | ||
213 | sysdev_create_file(s, &attr_mmcr0); | 266 | if (pmc_attrs) |
214 | sysdev_create_file(s, &attr_mmcr1); | 267 | for (i = 0; i < cur_cpu_spec->num_pmcs; i++) |
268 | sysdev_create_file(s, &pmc_attrs[i]); | ||
215 | 269 | ||
216 | if (cpu_has_feature(CPU_FTR_MMCRA)) | 270 | if (cpu_has_feature(CPU_FTR_MMCRA)) |
217 | sysdev_create_file(s, &attr_mmcra); | 271 | sysdev_create_file(s, &attr_mmcra); |
218 | 272 | ||
219 | if (cur_cpu_spec->num_pmcs >= 1) | ||
220 | sysdev_create_file(s, &attr_pmc1); | ||
221 | if (cur_cpu_spec->num_pmcs >= 2) | ||
222 | sysdev_create_file(s, &attr_pmc2); | ||
223 | if (cur_cpu_spec->num_pmcs >= 3) | ||
224 | sysdev_create_file(s, &attr_pmc3); | ||
225 | if (cur_cpu_spec->num_pmcs >= 4) | ||
226 | sysdev_create_file(s, &attr_pmc4); | ||
227 | if (cur_cpu_spec->num_pmcs >= 5) | ||
228 | sysdev_create_file(s, &attr_pmc5); | ||
229 | if (cur_cpu_spec->num_pmcs >= 6) | ||
230 | sysdev_create_file(s, &attr_pmc6); | ||
231 | if (cur_cpu_spec->num_pmcs >= 7) | ||
232 | sysdev_create_file(s, &attr_pmc7); | ||
233 | if (cur_cpu_spec->num_pmcs >= 8) | ||
234 | sysdev_create_file(s, &attr_pmc8); | ||
235 | |||
236 | if (cpu_has_feature(CPU_FTR_PURR)) | 273 | if (cpu_has_feature(CPU_FTR_PURR)) |
237 | sysdev_create_file(s, &attr_purr); | 274 | sysdev_create_file(s, &attr_purr); |
238 | 275 | ||
@@ -248,6 +285,8 @@ static void unregister_cpu_online(unsigned int cpu) | |||
248 | { | 285 | { |
249 | struct cpu *c = &per_cpu(cpu_devices, cpu); | 286 | struct cpu *c = &per_cpu(cpu_devices, cpu); |
250 | struct sys_device *s = &c->sysdev; | 287 | struct sys_device *s = &c->sysdev; |
288 | struct sysdev_attribute *attrs, *pmc_attrs; | ||
289 | int i, nattrs; | ||
251 | 290 | ||
252 | BUG_ON(!c->hotpluggable); | 291 | BUG_ON(!c->hotpluggable); |
253 | 292 | ||
@@ -256,30 +295,34 @@ static void unregister_cpu_online(unsigned int cpu) | |||
256 | sysdev_remove_file(s, &attr_smt_snooze_delay); | 295 | sysdev_remove_file(s, &attr_smt_snooze_delay); |
257 | 296 | ||
258 | /* PMC stuff */ | 297 | /* PMC stuff */ |
298 | switch (cur_cpu_spec->pmc_type) { | ||
299 | case PPC_PMC_IBM: | ||
300 | attrs = ibm_common_attrs; | ||
301 | nattrs = sizeof(ibm_common_attrs) / sizeof(struct sysdev_attribute); | ||
302 | pmc_attrs = ibm_pmc_attrs; | ||
303 | break; | ||
304 | case PPC_PMC_PA6T: | ||
305 | /* PA Semi starts counting at PMC0 */ | ||
306 | attrs = pa6t_attrs; | ||
307 | nattrs = sizeof(pa6t_attrs) / sizeof(struct sysdev_attribute); | ||
308 | pmc_attrs = NULL; | ||
309 | break; | ||
310 | default: | ||
311 | attrs = NULL; | ||
312 | nattrs = 0; | ||
313 | pmc_attrs = NULL; | ||
314 | } | ||
259 | 315 | ||
260 | sysdev_remove_file(s, &attr_mmcr0); | 316 | for (i = 0; i < nattrs; i++) |
261 | sysdev_remove_file(s, &attr_mmcr1); | 317 | sysdev_remove_file(s, &attrs[i]); |
318 | |||
319 | if (pmc_attrs) | ||
320 | for (i = 0; i < cur_cpu_spec->num_pmcs; i++) | ||
321 | sysdev_remove_file(s, &pmc_attrs[i]); | ||
262 | 322 | ||
263 | if (cpu_has_feature(CPU_FTR_MMCRA)) | 323 | if (cpu_has_feature(CPU_FTR_MMCRA)) |
264 | sysdev_remove_file(s, &attr_mmcra); | 324 | sysdev_remove_file(s, &attr_mmcra); |
265 | 325 | ||
266 | if (cur_cpu_spec->num_pmcs >= 1) | ||
267 | sysdev_remove_file(s, &attr_pmc1); | ||
268 | if (cur_cpu_spec->num_pmcs >= 2) | ||
269 | sysdev_remove_file(s, &attr_pmc2); | ||
270 | if (cur_cpu_spec->num_pmcs >= 3) | ||
271 | sysdev_remove_file(s, &attr_pmc3); | ||
272 | if (cur_cpu_spec->num_pmcs >= 4) | ||
273 | sysdev_remove_file(s, &attr_pmc4); | ||
274 | if (cur_cpu_spec->num_pmcs >= 5) | ||
275 | sysdev_remove_file(s, &attr_pmc5); | ||
276 | if (cur_cpu_spec->num_pmcs >= 6) | ||
277 | sysdev_remove_file(s, &attr_pmc6); | ||
278 | if (cur_cpu_spec->num_pmcs >= 7) | ||
279 | sysdev_remove_file(s, &attr_pmc7); | ||
280 | if (cur_cpu_spec->num_pmcs >= 8) | ||
281 | sysdev_remove_file(s, &attr_pmc8); | ||
282 | |||
283 | if (cpu_has_feature(CPU_FTR_PURR)) | 326 | if (cpu_has_feature(CPU_FTR_PURR)) |
284 | sysdev_remove_file(s, &attr_purr); | 327 | sysdev_remove_file(s, &attr_purr); |
285 | 328 | ||
diff --git a/include/asm-powerpc/reg.h b/include/asm-powerpc/reg.h index a3631b15754c..0279d4ec5211 100644 --- a/include/asm-powerpc/reg.h +++ b/include/asm-powerpc/reg.h | |||
@@ -462,6 +462,13 @@ | |||
462 | #define SPRN_SIAR 780 | 462 | #define SPRN_SIAR 780 |
463 | #define SPRN_SDAR 781 | 463 | #define SPRN_SDAR 781 |
464 | 464 | ||
465 | #define PA6T_SPRN_PMC0 787 | ||
466 | #define PA6T_SPRN_PMC1 788 | ||
467 | #define PA6T_SPRN_PMC2 789 | ||
468 | #define PA6T_SPRN_PMC3 790 | ||
469 | #define PA6T_SPRN_PMC4 791 | ||
470 | #define PA6T_SPRN_PMC5 792 | ||
471 | |||
465 | #else /* 32-bit */ | 472 | #else /* 32-bit */ |
466 | #define SPRN_MMCR0 952 /* Monitor Mode Control Register 0 */ | 473 | #define SPRN_MMCR0 952 /* Monitor Mode Control Register 0 */ |
467 | #define MMCR0_FC 0x80000000UL /* freeze counters */ | 474 | #define MMCR0_FC 0x80000000UL /* freeze counters */ |