1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Cell Broadband Engine Performance Monitor
5 * (C) Copyright IBM Corporation 2001,2006
8 * David Erb (djerb@us.ibm.com)
9 * Kevin Corry (kevcorry@us.ibm.com)
12 #include <linux/interrupt.h>
13 #include <linux/types.h>
14 #include <linux/export.h>
16 #include <asm/irq_regs.h>
17 #include <asm/machdep.h>
21 #include <asm/cell-regs.h>
23 #include "interrupt.h"
26 * When writing to write-only mmio addresses, save a shadow copy. All of the
27 * registers are 32-bit, but stored in the upper-half of a 64-bit field in
31 #define WRITE_WO_MMIO(reg, x) \
34 struct cbe_pmd_regs __iomem *pmd_regs; \
35 struct cbe_pmd_shadow_regs *shadow_regs; \
36 pmd_regs = cbe_get_cpu_pmd_regs(cpu); \
37 shadow_regs = cbe_get_cpu_pmd_shadow_regs(cpu); \
38 out_be64(&(pmd_regs->reg), (((u64)_x) << 32)); \
39 shadow_regs->reg = _x; \
42 #define READ_SHADOW_REG(val, reg) \
44 struct cbe_pmd_shadow_regs *shadow_regs; \
45 shadow_regs = cbe_get_cpu_pmd_shadow_regs(cpu); \
46 (val) = shadow_regs->reg; \
49 #define READ_MMIO_UPPER32(val, reg) \
51 struct cbe_pmd_regs __iomem *pmd_regs; \
52 pmd_regs = cbe_get_cpu_pmd_regs(cpu); \
53 (val) = (u32)(in_be64(&pmd_regs->reg) >> 32); \
57 * Physical counter registers.
58 * Each physical counter can act as one 32-bit counter or two 16-bit counters.
61 u32 cbe_read_phys_ctr(u32 cpu, u32 phys_ctr)
63 u32 val_in_latch, val = 0;
65 if (phys_ctr < NR_PHYS_CTRS) {
66 READ_SHADOW_REG(val_in_latch, counter_value_in_latch);
68 /* Read the latch or the actual counter, whichever is newer. */
69 if (val_in_latch & (1 << phys_ctr)) {
70 READ_SHADOW_REG(val, pm_ctr[phys_ctr]);
72 READ_MMIO_UPPER32(val, pm_ctr[phys_ctr]);
78 EXPORT_SYMBOL_GPL(cbe_read_phys_ctr);
80 void cbe_write_phys_ctr(u32 cpu, u32 phys_ctr, u32 val)
82 struct cbe_pmd_shadow_regs *shadow_regs;
85 if (phys_ctr < NR_PHYS_CTRS) {
86 /* Writing to a counter only writes to a hardware latch.
87 * The new value is not propagated to the actual counter
88 * until the performance monitor is enabled.
90 WRITE_WO_MMIO(pm_ctr[phys_ctr], val);
92 pm_ctrl = cbe_read_pm(cpu, pm_control);
93 if (pm_ctrl & CBE_PM_ENABLE_PERF_MON) {
94 /* The counters are already active, so we need to
95 * rewrite the pm_control register to "re-enable"
98 cbe_write_pm(cpu, pm_control, pm_ctrl);
100 shadow_regs = cbe_get_cpu_pmd_shadow_regs(cpu);
101 shadow_regs->counter_value_in_latch |= (1 << phys_ctr);
105 EXPORT_SYMBOL_GPL(cbe_write_phys_ctr);
108 * "Logical" counter registers.
109 * These will read/write 16-bits or 32-bits depending on the
110 * current size of the counter. Counters 4 - 7 are always 16-bit.
113 u32 cbe_read_ctr(u32 cpu, u32 ctr)
116 u32 phys_ctr = ctr & (NR_PHYS_CTRS - 1);
118 val = cbe_read_phys_ctr(cpu, phys_ctr);
120 if (cbe_get_ctr_size(cpu, phys_ctr) == 16)
121 val = (ctr < NR_PHYS_CTRS) ? (val >> 16) : (val & 0xffff);
125 EXPORT_SYMBOL_GPL(cbe_read_ctr);
127 void cbe_write_ctr(u32 cpu, u32 ctr, u32 val)
132 phys_ctr = ctr & (NR_PHYS_CTRS - 1);
134 if (cbe_get_ctr_size(cpu, phys_ctr) == 16) {
135 phys_val = cbe_read_phys_ctr(cpu, phys_ctr);
137 if (ctr < NR_PHYS_CTRS)
138 val = (val << 16) | (phys_val & 0xffff);
140 val = (val & 0xffff) | (phys_val & 0xffff0000);
143 cbe_write_phys_ctr(cpu, phys_ctr, val);
145 EXPORT_SYMBOL_GPL(cbe_write_ctr);
148 * Counter-control registers.
149 * Each "logical" counter has a corresponding control register.
152 u32 cbe_read_pm07_control(u32 cpu, u32 ctr)
154 u32 pm07_control = 0;
157 READ_SHADOW_REG(pm07_control, pm07_control[ctr]);
161 EXPORT_SYMBOL_GPL(cbe_read_pm07_control);
163 void cbe_write_pm07_control(u32 cpu, u32 ctr, u32 val)
166 WRITE_WO_MMIO(pm07_control[ctr], val);
168 EXPORT_SYMBOL_GPL(cbe_write_pm07_control);
171 * Other PMU control registers. Most of these are write-only.
174 u32 cbe_read_pm(u32 cpu, enum pm_reg_name reg)
180 READ_SHADOW_REG(val, group_control);
183 case debug_bus_control:
184 READ_SHADOW_REG(val, debug_bus_control);
188 READ_MMIO_UPPER32(val, trace_address);
192 READ_SHADOW_REG(val, ext_tr_timer);
196 READ_MMIO_UPPER32(val, pm_status);
200 READ_SHADOW_REG(val, pm_control);
204 READ_MMIO_UPPER32(val, pm_interval);
208 READ_SHADOW_REG(val, pm_start_stop);
214 EXPORT_SYMBOL_GPL(cbe_read_pm);
216 void cbe_write_pm(u32 cpu, enum pm_reg_name reg, u32 val)
220 WRITE_WO_MMIO(group_control, val);
223 case debug_bus_control:
224 WRITE_WO_MMIO(debug_bus_control, val);
228 WRITE_WO_MMIO(trace_address, val);
232 WRITE_WO_MMIO(ext_tr_timer, val);
236 WRITE_WO_MMIO(pm_status, val);
240 WRITE_WO_MMIO(pm_control, val);
244 WRITE_WO_MMIO(pm_interval, val);
248 WRITE_WO_MMIO(pm_start_stop, val);
252 EXPORT_SYMBOL_GPL(cbe_write_pm);
255 * Get/set the size of a physical counter to either 16 or 32 bits.
258 u32 cbe_get_ctr_size(u32 cpu, u32 phys_ctr)
260 u32 pm_ctrl, size = 0;
262 if (phys_ctr < NR_PHYS_CTRS) {
263 pm_ctrl = cbe_read_pm(cpu, pm_control);
264 size = (pm_ctrl & CBE_PM_16BIT_CTR(phys_ctr)) ? 16 : 32;
269 EXPORT_SYMBOL_GPL(cbe_get_ctr_size);
271 void cbe_set_ctr_size(u32 cpu, u32 phys_ctr, u32 ctr_size)
275 if (phys_ctr < NR_PHYS_CTRS) {
276 pm_ctrl = cbe_read_pm(cpu, pm_control);
279 pm_ctrl |= CBE_PM_16BIT_CTR(phys_ctr);
283 pm_ctrl &= ~CBE_PM_16BIT_CTR(phys_ctr);
286 cbe_write_pm(cpu, pm_control, pm_ctrl);
289 EXPORT_SYMBOL_GPL(cbe_set_ctr_size);
292 * Enable/disable the entire performance monitoring unit.
293 * When we enable the PMU, all pending writes to counters get committed.
296 void cbe_enable_pm(u32 cpu)
298 struct cbe_pmd_shadow_regs *shadow_regs;
301 shadow_regs = cbe_get_cpu_pmd_shadow_regs(cpu);
302 shadow_regs->counter_value_in_latch = 0;
304 pm_ctrl = cbe_read_pm(cpu, pm_control) | CBE_PM_ENABLE_PERF_MON;
305 cbe_write_pm(cpu, pm_control, pm_ctrl);
307 EXPORT_SYMBOL_GPL(cbe_enable_pm);
309 void cbe_disable_pm(u32 cpu)
312 pm_ctrl = cbe_read_pm(cpu, pm_control) & ~CBE_PM_ENABLE_PERF_MON;
313 cbe_write_pm(cpu, pm_control, pm_ctrl);
315 EXPORT_SYMBOL_GPL(cbe_disable_pm);
318 * Reading from the trace_buffer.
319 * The trace buffer is two 64-bit registers. Reading from
320 * the second half automatically increments the trace_address.
323 void cbe_read_trace_buffer(u32 cpu, u64 *buf)
325 struct cbe_pmd_regs __iomem *pmd_regs = cbe_get_cpu_pmd_regs(cpu);
327 *buf++ = in_be64(&pmd_regs->trace_buffer_0_63);
328 *buf++ = in_be64(&pmd_regs->trace_buffer_64_127);
330 EXPORT_SYMBOL_GPL(cbe_read_trace_buffer);
333 * Enabling/disabling interrupts for the entire performance monitoring unit.
336 u32 cbe_get_and_clear_pm_interrupts(u32 cpu)
338 /* Reading pm_status clears the interrupt bits. */
339 return cbe_read_pm(cpu, pm_status);
341 EXPORT_SYMBOL_GPL(cbe_get_and_clear_pm_interrupts);
343 void cbe_enable_pm_interrupts(u32 cpu, u32 thread, u32 mask)
345 /* Set which node and thread will handle the next interrupt. */
346 iic_set_interrupt_routing(cpu, thread, 0);
348 /* Enable the interrupt bits in the pm_status register. */
350 cbe_write_pm(cpu, pm_status, mask);
352 EXPORT_SYMBOL_GPL(cbe_enable_pm_interrupts);
354 void cbe_disable_pm_interrupts(u32 cpu)
356 cbe_get_and_clear_pm_interrupts(cpu);
357 cbe_write_pm(cpu, pm_status, 0);
359 EXPORT_SYMBOL_GPL(cbe_disable_pm_interrupts);
361 static irqreturn_t cbe_pm_irq(int irq, void *dev_id)
363 perf_irq(get_irq_regs());
367 static int __init cbe_init_pm_irq(void)
372 for_each_online_node(node) {
373 irq = irq_create_mapping(NULL, IIC_IRQ_IOEX_PMI |
374 (node << IIC_IRQ_NODE_SHIFT));
376 printk("ERROR: Unable to allocate irq for node %d\n",
381 rc = request_irq(irq, cbe_pm_irq,
382 0, "cbe-pmu-0", NULL);
384 printk("ERROR: Request for irq on node %d failed\n",
392 machine_arch_initcall(cell, cbe_init_pm_irq);
394 void cbe_sync_irq(int node)
398 irq = irq_find_mapping(NULL,
400 | (node << IIC_IRQ_NODE_SHIFT));
403 printk(KERN_WARNING "ERROR, unable to get existing irq %d " \
404 "for node %d\n", irq, node);
408 synchronize_irq(irq);
410 EXPORT_SYMBOL_GPL(cbe_sync_irq);