1/* SPDX-License-Identifier: GPL-2.0-or-later */
2/*
3 * Copyright (C) 2004 Anton Blanchard <anton@au.ibm.com>, IBM
4 *
5 * Based on alpha version.
6 */
7
8#ifndef _ASM_POWERPC_OPROFILE_IMPL_H
9#define _ASM_POWERPC_OPROFILE_IMPL_H
10#ifdef __KERNEL__
11
12#define OP_MAX_COUNTER 8
13
14/* Per-counter configuration as set via oprofilefs.  */
15struct op_counter_config {
16	unsigned long enabled;
17	unsigned long event;
18	unsigned long count;
19	/* Classic doesn't support per-counter user/kernel selection */
20	unsigned long kernel;
21	unsigned long user;
22	unsigned long unit_mask;
23};
24
25/* System-wide configuration as set via oprofilefs.  */
26struct op_system_config {
27#ifdef CONFIG_PPC64
28	unsigned long mmcr0;
29	unsigned long mmcr1;
30	unsigned long mmcra;
31#ifdef CONFIG_OPROFILE_CELL
32	/* Register for oprofile user tool to check cell kernel profiling
33	 * support.
34	 */
35	unsigned long cell_support;
36#endif
37#endif
38	unsigned long enable_kernel;
39	unsigned long enable_user;
40};
41
42/* Per-arch configuration */
43struct op_powerpc_model {
44	int (*reg_setup) (struct op_counter_config *,
45			   struct op_system_config *,
46			   int num_counters);
47	int  (*cpu_setup) (struct op_counter_config *);
48	int  (*start) (struct op_counter_config *);
49	int  (*global_start) (struct op_counter_config *);
50	void (*stop) (void);
51	void (*global_stop) (void);
52	int (*sync_start)(void);
53	int (*sync_stop)(void);
54	void (*handle_interrupt) (struct pt_regs *,
55				  struct op_counter_config *);
56	int num_counters;
57};
58
59extern struct op_powerpc_model op_model_fsl_emb;
60extern struct op_powerpc_model op_model_power4;
61extern struct op_powerpc_model op_model_7450;
62extern struct op_powerpc_model op_model_cell;
63extern struct op_powerpc_model op_model_pa6t;
64
65
66/* All the classic PPC parts use these */
67static inline unsigned int classic_ctr_read(unsigned int i)
68{
69	switch(i) {
70	case 0:
71		return mfspr(SPRN_PMC1);
72	case 1:
73		return mfspr(SPRN_PMC2);
74	case 2:
75		return mfspr(SPRN_PMC3);
76	case 3:
77		return mfspr(SPRN_PMC4);
78	case 4:
79		return mfspr(SPRN_PMC5);
80	case 5:
81		return mfspr(SPRN_PMC6);
82
83/* No PPC32 chip has more than 6 so far */
84#ifdef CONFIG_PPC64
85	case 6:
86		return mfspr(SPRN_PMC7);
87	case 7:
88		return mfspr(SPRN_PMC8);
89#endif
90	default:
91		return 0;
92	}
93}
94
95static inline void classic_ctr_write(unsigned int i, unsigned int val)
96{
97	switch(i) {
98	case 0:
99		mtspr(SPRN_PMC1, val);
100		break;
101	case 1:
102		mtspr(SPRN_PMC2, val);
103		break;
104	case 2:
105		mtspr(SPRN_PMC3, val);
106		break;
107	case 3:
108		mtspr(SPRN_PMC4, val);
109		break;
110	case 4:
111		mtspr(SPRN_PMC5, val);
112		break;
113	case 5:
114		mtspr(SPRN_PMC6, val);
115		break;
116
117/* No PPC32 chip has more than 6, yet */
118#ifdef CONFIG_PPC64
119	case 6:
120		mtspr(SPRN_PMC7, val);
121		break;
122	case 7:
123		mtspr(SPRN_PMC8, val);
124		break;
125#endif
126	default:
127		break;
128	}
129}
130
131
132extern void op_powerpc_backtrace(struct pt_regs * const regs, unsigned int depth);
133
134#endif /* __KERNEL__ */
135#endif /* _ASM_POWERPC_OPROFILE_IMPL_H */
136