aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/oprofile/op_model_fsl_booke.c
diff options
context:
space:
mode:
authorAndy Fleming <afleming@freescale.com>2006-10-27 16:06:32 -0400
committerPaul Mackerras <paulus@samba.org>2006-10-31 22:52:48 -0500
commitdd6c89f686bdb2a5de72fab636fc839e5a0add6d (patch)
tree0175b22323dcff97dea9a85b8c01561eeb94a0b1 /arch/powerpc/oprofile/op_model_fsl_booke.c
parente0da0daee14862e0a5c49f2059641a8deb27eca2 (diff)
[POWERPC] Fix oprofile support for e500 in arch/powerpc
Fixed a compile error in building the 85xx support with oprofile, and in the process cleaned up some issues with the fsl_booke performance monitor code. * Reorganized FSL Book-E performance monitoring code so that the 7450 wouldn't be built if the e500 was, and cleaned it up so it was more self-contained. * Added a cpu_setup function for FSL Book-E. The original cpu_setup function prototype had no arguments, assuming that the reg_setup function would copy the required information into variables which represented the registers. This was silly for e500, since it has 1 register per counter (rather than 3 for all counters), so the code has been restructured to have cpu_setup take the current counter config array as an argument, with op_powerpc_setup() invoking op_powerpc_cpu_setup() through on_each_cpu(), and op_powerpc_cpu_setup() invoking the model-specific cpu_setup function with an argument. The argument is ignored on all other platforms at present. * Fixed a confusing line where a trinary operator only had two arguments Signed-off-by: Andrew Fleming <afleming@freescale.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/oprofile/op_model_fsl_booke.c')
-rw-r--r--arch/powerpc/oprofile/op_model_fsl_booke.c170
1 files changed, 136 insertions, 34 deletions
diff --git a/arch/powerpc/oprofile/op_model_fsl_booke.c b/arch/powerpc/oprofile/op_model_fsl_booke.c
index e29dede31423..0b3c31f5209e 100644
--- a/arch/powerpc/oprofile/op_model_fsl_booke.c
+++ b/arch/powerpc/oprofile/op_model_fsl_booke.c
@@ -32,42 +32,152 @@ static unsigned long reset_value[OP_MAX_COUNTER];
32static int num_counters; 32static int num_counters;
33static int oprofile_running; 33static int oprofile_running;
34 34
35static inline unsigned int ctr_read(unsigned int i) 35static void init_pmc_stop(int ctr)
36{ 36{
37 switch(i) { 37 u32 pmlca = (PMLCA_FC | PMLCA_FCS | PMLCA_FCU |
38 case 0: 38 PMLCA_FCM1 | PMLCA_FCM0);
39 return mfpmr(PMRN_PMC0); 39 u32 pmlcb = 0;
40 case 1:
41 return mfpmr(PMRN_PMC1);
42 case 2:
43 return mfpmr(PMRN_PMC2);
44 case 3:
45 return mfpmr(PMRN_PMC3);
46 default:
47 return 0;
48 }
49}
50 40
51static inline void ctr_write(unsigned int i, unsigned int val) 41 switch (ctr) {
52{
53 switch(i) {
54 case 0: 42 case 0:
55 mtpmr(PMRN_PMC0, val); 43 mtpmr(PMRN_PMLCA0, pmlca);
44 mtpmr(PMRN_PMLCB0, pmlcb);
56 break; 45 break;
57 case 1: 46 case 1:
58 mtpmr(PMRN_PMC1, val); 47 mtpmr(PMRN_PMLCA1, pmlca);
48 mtpmr(PMRN_PMLCB1, pmlcb);
59 break; 49 break;
60 case 2: 50 case 2:
61 mtpmr(PMRN_PMC2, val); 51 mtpmr(PMRN_PMLCA2, pmlca);
52 mtpmr(PMRN_PMLCB2, pmlcb);
62 break; 53 break;
63 case 3: 54 case 3:
64 mtpmr(PMRN_PMC3, val); 55 mtpmr(PMRN_PMLCA3, pmlca);
56 mtpmr(PMRN_PMLCB3, pmlcb);
65 break; 57 break;
66 default: 58 default:
67 break; 59 panic("Bad ctr number!\n");
68 } 60 }
69} 61}
70 62
63static void set_pmc_event(int ctr, int event)
64{
65 u32 pmlca;
66
67 pmlca = get_pmlca(ctr);
68
69 pmlca = (pmlca & ~PMLCA_EVENT_MASK) |
70 ((event << PMLCA_EVENT_SHIFT) &
71 PMLCA_EVENT_MASK);
72
73 set_pmlca(ctr, pmlca);
74}
75
76static void set_pmc_user_kernel(int ctr, int user, int kernel)
77{
78 u32 pmlca;
79
80 pmlca = get_pmlca(ctr);
81
82 if(user)
83 pmlca &= ~PMLCA_FCU;
84 else
85 pmlca |= PMLCA_FCU;
86
87 if(kernel)
88 pmlca &= ~PMLCA_FCS;
89 else
90 pmlca |= PMLCA_FCS;
91
92 set_pmlca(ctr, pmlca);
93}
94
95static void set_pmc_marked(int ctr, int mark0, int mark1)
96{
97 u32 pmlca = get_pmlca(ctr);
98
99 if(mark0)
100 pmlca &= ~PMLCA_FCM0;
101 else
102 pmlca |= PMLCA_FCM0;
103
104 if(mark1)
105 pmlca &= ~PMLCA_FCM1;
106 else
107 pmlca |= PMLCA_FCM1;
108
109 set_pmlca(ctr, pmlca);
110}
111
112static void pmc_start_ctr(int ctr, int enable)
113{
114 u32 pmlca = get_pmlca(ctr);
115
116 pmlca &= ~PMLCA_FC;
117
118 if (enable)
119 pmlca |= PMLCA_CE;
120 else
121 pmlca &= ~PMLCA_CE;
122
123 set_pmlca(ctr, pmlca);
124}
125
126static void pmc_start_ctrs(int enable)
127{
128 u32 pmgc0 = mfpmr(PMRN_PMGC0);
129
130 pmgc0 &= ~PMGC0_FAC;
131 pmgc0 |= PMGC0_FCECE;
132
133 if (enable)
134 pmgc0 |= PMGC0_PMIE;
135 else
136 pmgc0 &= ~PMGC0_PMIE;
137
138 mtpmr(PMRN_PMGC0, pmgc0);
139}
140
141static void pmc_stop_ctrs(void)
142{
143 u32 pmgc0 = mfpmr(PMRN_PMGC0);
144
145 pmgc0 |= PMGC0_FAC;
146
147 pmgc0 &= ~(PMGC0_PMIE | PMGC0_FCECE);
148
149 mtpmr(PMRN_PMGC0, pmgc0);
150}
151
152static void dump_pmcs(void)
153{
154 printk("pmgc0: %x\n", mfpmr(PMRN_PMGC0));
155 printk("pmc\t\tpmlca\t\tpmlcb\n");
156 printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC0),
157 mfpmr(PMRN_PMLCA0), mfpmr(PMRN_PMLCB0));
158 printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC1),
159 mfpmr(PMRN_PMLCA1), mfpmr(PMRN_PMLCB1));
160 printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC2),
161 mfpmr(PMRN_PMLCA2), mfpmr(PMRN_PMLCB2));
162 printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC3),
163 mfpmr(PMRN_PMLCA3), mfpmr(PMRN_PMLCB3));
164}
165
166static void fsl_booke_cpu_setup(struct op_counter_config *ctr)
167{
168 int i;
169
170 /* freeze all counters */
171 pmc_stop_ctrs();
172
173 for (i = 0;i < num_counters;i++) {
174 init_pmc_stop(i);
175
176 set_pmc_event(i, ctr[i].event);
177
178 set_pmc_user_kernel(i, ctr[i].user, ctr[i].kernel);
179 }
180}
71 181
72static void fsl_booke_reg_setup(struct op_counter_config *ctr, 182static void fsl_booke_reg_setup(struct op_counter_config *ctr,
73 struct op_system_config *sys, 183 struct op_system_config *sys,
@@ -77,23 +187,14 @@ static void fsl_booke_reg_setup(struct op_counter_config *ctr,
77 187
78 num_counters = num_ctrs; 188 num_counters = num_ctrs;
79 189
80 /* freeze all counters */
81 pmc_stop_ctrs();
82
83 /* Our counters count up, and "count" refers to 190 /* Our counters count up, and "count" refers to
84 * how much before the next interrupt, and we interrupt 191 * how much before the next interrupt, and we interrupt
85 * on overflow. So we calculate the starting value 192 * on overflow. So we calculate the starting value
86 * which will give us "count" until overflow. 193 * which will give us "count" until overflow.
87 * Then we set the events on the enabled counters */ 194 * Then we set the events on the enabled counters */
88 for (i = 0; i < num_counters; ++i) { 195 for (i = 0; i < num_counters; ++i)
89 reset_value[i] = 0x80000000UL - ctr[i].count; 196 reset_value[i] = 0x80000000UL - ctr[i].count;
90 197
91 init_pmc_stop(i);
92
93 set_pmc_event(i, ctr[i].event);
94
95 set_pmc_user_kernel(i, ctr[i].user, ctr[i].kernel);
96 }
97} 198}
98 199
99static void fsl_booke_start(struct op_counter_config *ctr) 200static void fsl_booke_start(struct op_counter_config *ctr)
@@ -105,8 +206,8 @@ static void fsl_booke_start(struct op_counter_config *ctr)
105 for (i = 0; i < num_counters; ++i) { 206 for (i = 0; i < num_counters; ++i) {
106 if (ctr[i].enabled) { 207 if (ctr[i].enabled) {
107 ctr_write(i, reset_value[i]); 208 ctr_write(i, reset_value[i]);
108 /* Set Each enabled counterd to only 209 /* Set each enabled counter to only
109 * count when the Mark bit is not set */ 210 * count when the Mark bit is *not* set */
110 set_pmc_marked(i, 1, 0); 211 set_pmc_marked(i, 1, 0);
111 pmc_start_ctr(i, 1); 212 pmc_start_ctr(i, 1);
112 } else { 213 } else {
@@ -177,6 +278,7 @@ static void fsl_booke_handle_interrupt(struct pt_regs *regs,
177 278
178struct op_powerpc_model op_model_fsl_booke = { 279struct op_powerpc_model op_model_fsl_booke = {
179 .reg_setup = fsl_booke_reg_setup, 280 .reg_setup = fsl_booke_reg_setup,
281 .cpu_setup = fsl_booke_cpu_setup,
180 .start = fsl_booke_start, 282 .start = fsl_booke_start,
181 .stop = fsl_booke_stop, 283 .stop = fsl_booke_stop,
182 .handle_interrupt = fsl_booke_handle_interrupt, 284 .handle_interrupt = fsl_booke_handle_interrupt,