Merge tag 'for-6.2-rc7-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave...
[platform/kernel/linux-rpi.git] / drivers / ps3 / ps3-lpm.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * PS3 Logical Performance Monitor.
4  *
5  *  Copyright (C) 2007 Sony Computer Entertainment Inc.
6  *  Copyright 2007 Sony Corp.
7  */
8
9 #include <linux/slab.h>
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/interrupt.h>
13 #include <linux/uaccess.h>
14 #include <asm/smp.h>
15 #include <asm/time.h>
16 #include <asm/ps3.h>
17 #include <asm/lv1call.h>
18 #include <asm/cell-pmu.h>
19
20
21 /* BOOKMARK tag macros */
22 #define PS3_PM_BOOKMARK_START                    0x8000000000000000ULL
23 #define PS3_PM_BOOKMARK_STOP                     0x4000000000000000ULL
24 #define PS3_PM_BOOKMARK_TAG_KERNEL               0x1000000000000000ULL
25 #define PS3_PM_BOOKMARK_TAG_USER                 0x3000000000000000ULL
26 #define PS3_PM_BOOKMARK_TAG_MASK_HI              0xF000000000000000ULL
27 #define PS3_PM_BOOKMARK_TAG_MASK_LO              0x0F00000000000000ULL
28
29 /* CBE PM CONTROL register macros */
30 #define PS3_PM_CONTROL_PPU_TH0_BOOKMARK          0x00001000
31 #define PS3_PM_CONTROL_PPU_TH1_BOOKMARK          0x00000800
32 #define PS3_PM_CONTROL_PPU_COUNT_MODE_MASK       0x000C0000
33 #define PS3_PM_CONTROL_PPU_COUNT_MODE_PROBLEM    0x00080000
34 #define PS3_WRITE_PM_MASK                        0xFFFFFFFFFFFFFFFFULL
35
36 /* CBE PM START STOP register macros */
37 #define PS3_PM_START_STOP_PPU_TH0_BOOKMARK_START 0x02000000
38 #define PS3_PM_START_STOP_PPU_TH1_BOOKMARK_START 0x01000000
39 #define PS3_PM_START_STOP_PPU_TH0_BOOKMARK_STOP  0x00020000
40 #define PS3_PM_START_STOP_PPU_TH1_BOOKMARK_STOP  0x00010000
41 #define PS3_PM_START_STOP_START_MASK             0xFF000000
42 #define PS3_PM_START_STOP_STOP_MASK              0x00FF0000
43
44 /* CBE PM COUNTER register macres */
45 #define PS3_PM_COUNTER_MASK_HI                   0xFFFFFFFF00000000ULL
46 #define PS3_PM_COUNTER_MASK_LO                   0x00000000FFFFFFFFULL
47
48 /* BASE SIGNAL GROUP NUMBER macros */
49 #define PM_ISLAND2_BASE_SIGNAL_GROUP_NUMBER  0
50 #define PM_ISLAND2_SIGNAL_GROUP_NUMBER1      6
51 #define PM_ISLAND2_SIGNAL_GROUP_NUMBER2      7
52 #define PM_ISLAND3_BASE_SIGNAL_GROUP_NUMBER  7
53 #define PM_ISLAND4_BASE_SIGNAL_GROUP_NUMBER  15
54 #define PM_SPU_TRIGGER_SIGNAL_GROUP_NUMBER   17
55 #define PM_SPU_EVENT_SIGNAL_GROUP_NUMBER     18
56 #define PM_ISLAND5_BASE_SIGNAL_GROUP_NUMBER  18
57 #define PM_ISLAND6_BASE_SIGNAL_GROUP_NUMBER  24
58 #define PM_ISLAND7_BASE_SIGNAL_GROUP_NUMBER  49
59 #define PM_ISLAND8_BASE_SIGNAL_GROUP_NUMBER  52
60 #define PM_SIG_GROUP_SPU                     41
61 #define PM_SIG_GROUP_SPU_TRIGGER             42
62 #define PM_SIG_GROUP_SPU_EVENT               43
63 #define PM_SIG_GROUP_MFC_MAX                 60
64
65 /**
66  * struct ps3_lpm_shadow_regs - Performance monitor shadow registers.
67  *
68  * @pm_control: Shadow of the processor's pm_control register.
69  * @pm_start_stop: Shadow of the processor's pm_start_stop register.
70  * @group_control: Shadow of the processor's group_control register.
71  * @debug_bus_control: Shadow of the processor's debug_bus_control register.
72  *
73  * The logical performance monitor provides a write-only interface to
74  * these processor registers.  These shadow variables cache the processor
75  * register values for reading.
76  *
77  * The initial value of the shadow registers at lpm creation is
78  * PS3_LPM_SHADOW_REG_INIT.
79  */
80
81 struct ps3_lpm_shadow_regs {
82         u64 pm_control;
83         u64 pm_start_stop;
84         u64 group_control;
85         u64 debug_bus_control;
86 };
87
88 #define PS3_LPM_SHADOW_REG_INIT 0xFFFFFFFF00000000ULL
89
90 /**
91  * struct ps3_lpm_priv - Private lpm device data.
92  *
93  * @open: An atomic variable indicating the lpm driver has been opened.
94  * @rights: The lpm rigths granted by the system policy module.  A logical
95  *  OR of enum ps3_lpm_rights.
96  * @node_id: The node id of a BE processor whose performance monitor this
97  *  lpar has the right to use.
98  * @pu_id: The lv1 id of the logical PU.
99  * @lpm_id: The lv1 id of this lpm instance.
100  * @outlet_id: The outlet created by lv1 for this lpm instance.
101  * @tb_count: The number of bytes of data held in the lv1 trace buffer.
102  * @tb_cache: Kernel buffer to receive the data from the lv1 trace buffer.
103  *  Must be 128 byte aligned.
104  * @tb_cache_size: Size of the kernel @tb_cache buffer.  Must be 128 byte
105  *  aligned.
106  * @tb_cache_internal: An unaligned buffer allocated by this driver to be
107  *  used for the trace buffer cache when ps3_lpm_open() is called with a
108  *  NULL tb_cache argument.  Otherwise unused.
109  * @shadow: Processor register shadow of type struct ps3_lpm_shadow_regs.
110  * @sbd: The struct ps3_system_bus_device attached to this driver.
111  *
112  * The trace buffer is a buffer allocated and used internally to the lv1
113  * hypervisor to collect trace data.  The trace buffer cache is a guest
114  * buffer that accepts the trace data from the trace buffer.
115  */
116
117 struct ps3_lpm_priv {
118         atomic_t open;
119         u64 rights;
120         u64 node_id;
121         u64 pu_id;
122         u64 lpm_id;
123         u64 outlet_id;
124         u64 tb_count;
125         void *tb_cache;
126         u64 tb_cache_size;
127         void *tb_cache_internal;
128         struct ps3_lpm_shadow_regs shadow;
129         struct ps3_system_bus_device *sbd;
130 };
131
132 enum {
133         PS3_LPM_DEFAULT_TB_CACHE_SIZE = 0x4000,
134 };
135
136 /**
137  * lpm_priv - Static instance of the lpm data.
138  *
139  * Since the exported routines don't support the notion of a device
140  * instance we need to hold the instance in this static variable
141  * and then only allow at most one instance at a time to be created.
142  */
143
144 static struct ps3_lpm_priv *lpm_priv;
145
146 static struct device *sbd_core(void)
147 {
148         BUG_ON(!lpm_priv || !lpm_priv->sbd);
149         return &lpm_priv->sbd->core;
150 }
151
152 /**
153  * use_start_stop_bookmark - Enable the PPU bookmark trace.
154  *
155  * And it enables PPU bookmark triggers ONLY if the other triggers are not set.
156  * The start/stop bookmarks are inserted at ps3_enable_pm() and ps3_disable_pm()
157  * to start/stop LPM.
158  *
159  * Used to get good quality of the performance counter.
160  */
161
162 enum {use_start_stop_bookmark = 1,};
163
164 void ps3_set_bookmark(u64 bookmark)
165 {
166         /*
167          * As per the PPE book IV, to avoid bookmark loss there must
168          * not be a traced branch within 10 cycles of setting the
169          * SPRN_BKMK register.  The actual text is unclear if 'within'
170          * includes cycles before the call.
171          */
172
173         asm volatile("nop;nop;nop;nop;nop;nop;nop;nop;nop;");
174         mtspr(SPRN_BKMK, bookmark);
175         asm volatile("nop;nop;nop;nop;nop;nop;nop;nop;nop;");
176 }
177 EXPORT_SYMBOL_GPL(ps3_set_bookmark);
178
179 void ps3_set_pm_bookmark(u64 tag, u64 incident, u64 th_id)
180 {
181         u64 bookmark;
182
183         bookmark = (get_tb() & 0x00000000FFFFFFFFULL) |
184                 PS3_PM_BOOKMARK_TAG_KERNEL;
185         bookmark = ((tag << 56) & PS3_PM_BOOKMARK_TAG_MASK_LO) |
186                 (incident << 48) | (th_id << 32) | bookmark;
187         ps3_set_bookmark(bookmark);
188 }
189 EXPORT_SYMBOL_GPL(ps3_set_pm_bookmark);
190
191 /**
192  * ps3_read_phys_ctr - Read physical counter registers.
193  *
194  * Each physical counter can act as one 32 bit counter or as two 16 bit
195  * counters.
196  */
197
198 u32 ps3_read_phys_ctr(u32 cpu, u32 phys_ctr)
199 {
200         int result;
201         u64 counter0415;
202         u64 counter2637;
203
204         if (phys_ctr >= NR_PHYS_CTRS) {
205                 dev_dbg(sbd_core(), "%s:%u: phys_ctr too big: %u\n", __func__,
206                         __LINE__, phys_ctr);
207                 return 0;
208         }
209
210         result = lv1_set_lpm_counter(lpm_priv->lpm_id, 0, 0, 0, 0, &counter0415,
211                                      &counter2637);
212         if (result) {
213                 dev_err(sbd_core(), "%s:%u: lv1_set_lpm_counter failed: "
214                         "phys_ctr %u, %s\n", __func__, __LINE__, phys_ctr,
215                         ps3_result(result));
216                 return 0;
217         }
218
219         switch (phys_ctr) {
220         case 0:
221                 return counter0415 >> 32;
222         case 1:
223                 return counter0415 & PS3_PM_COUNTER_MASK_LO;
224         case 2:
225                 return counter2637 >> 32;
226         case 3:
227                 return counter2637 & PS3_PM_COUNTER_MASK_LO;
228         default:
229                 BUG();
230         }
231         return 0;
232 }
233 EXPORT_SYMBOL_GPL(ps3_read_phys_ctr);
234
235 /**
236  * ps3_write_phys_ctr - Write physical counter registers.
237  *
238  * Each physical counter can act as one 32 bit counter or as two 16 bit
239  * counters.
240  */
241
242 void ps3_write_phys_ctr(u32 cpu, u32 phys_ctr, u32 val)
243 {
244         u64 counter0415;
245         u64 counter0415_mask;
246         u64 counter2637;
247         u64 counter2637_mask;
248         int result;
249
250         if (phys_ctr >= NR_PHYS_CTRS) {
251                 dev_dbg(sbd_core(), "%s:%u: phys_ctr too big: %u\n", __func__,
252                         __LINE__, phys_ctr);
253                 return;
254         }
255
256         switch (phys_ctr) {
257         case 0:
258                 counter0415 = (u64)val << 32;
259                 counter0415_mask = PS3_PM_COUNTER_MASK_HI;
260                 counter2637 = 0x0;
261                 counter2637_mask = 0x0;
262                 break;
263         case 1:
264                 counter0415 = (u64)val;
265                 counter0415_mask = PS3_PM_COUNTER_MASK_LO;
266                 counter2637 = 0x0;
267                 counter2637_mask = 0x0;
268                 break;
269         case 2:
270                 counter0415 = 0x0;
271                 counter0415_mask = 0x0;
272                 counter2637 = (u64)val << 32;
273                 counter2637_mask = PS3_PM_COUNTER_MASK_HI;
274                 break;
275         case 3:
276                 counter0415 = 0x0;
277                 counter0415_mask = 0x0;
278                 counter2637 = (u64)val;
279                 counter2637_mask = PS3_PM_COUNTER_MASK_LO;
280                 break;
281         default:
282                 BUG();
283         }
284
285         result = lv1_set_lpm_counter(lpm_priv->lpm_id,
286                                      counter0415, counter0415_mask,
287                                      counter2637, counter2637_mask,
288                                      &counter0415, &counter2637);
289         if (result)
290                 dev_err(sbd_core(), "%s:%u: lv1_set_lpm_counter failed: "
291                         "phys_ctr %u, val %u, %s\n", __func__, __LINE__,
292                         phys_ctr, val, ps3_result(result));
293 }
294 EXPORT_SYMBOL_GPL(ps3_write_phys_ctr);
295
296 /**
297  * ps3_read_ctr - Read counter.
298  *
299  * Read 16 or 32 bits depending on the current size of the counter.
300  * Counters 4, 5, 6 & 7 are always 16 bit.
301  */
302
303 u32 ps3_read_ctr(u32 cpu, u32 ctr)
304 {
305         u32 val;
306         u32 phys_ctr = ctr & (NR_PHYS_CTRS - 1);
307
308         val = ps3_read_phys_ctr(cpu, phys_ctr);
309
310         if (ps3_get_ctr_size(cpu, phys_ctr) == 16)
311                 val = (ctr < NR_PHYS_CTRS) ? (val >> 16) : (val & 0xffff);
312
313         return val;
314 }
315 EXPORT_SYMBOL_GPL(ps3_read_ctr);
316
317 /**
318  * ps3_write_ctr - Write counter.
319  *
320  * Write 16 or 32 bits depending on the current size of the counter.
321  * Counters 4, 5, 6 & 7 are always 16 bit.
322  */
323
324 void ps3_write_ctr(u32 cpu, u32 ctr, u32 val)
325 {
326         u32 phys_ctr;
327         u32 phys_val;
328
329         phys_ctr = ctr & (NR_PHYS_CTRS - 1);
330
331         if (ps3_get_ctr_size(cpu, phys_ctr) == 16) {
332                 phys_val = ps3_read_phys_ctr(cpu, phys_ctr);
333
334                 if (ctr < NR_PHYS_CTRS)
335                         val = (val << 16) | (phys_val & 0xffff);
336                 else
337                         val = (val & 0xffff) | (phys_val & 0xffff0000);
338         }
339
340         ps3_write_phys_ctr(cpu, phys_ctr, val);
341 }
342 EXPORT_SYMBOL_GPL(ps3_write_ctr);
343
344 /**
345  * ps3_read_pm07_control - Read counter control registers.
346  *
347  * Each logical counter has a corresponding control register.
348  */
349
350 u32 ps3_read_pm07_control(u32 cpu, u32 ctr)
351 {
352         return 0;
353 }
354 EXPORT_SYMBOL_GPL(ps3_read_pm07_control);
355
356 /**
357  * ps3_write_pm07_control - Write counter control registers.
358  *
359  * Each logical counter has a corresponding control register.
360  */
361
362 void ps3_write_pm07_control(u32 cpu, u32 ctr, u32 val)
363 {
364         int result;
365         static const u64 mask = 0xFFFFFFFFFFFFFFFFULL;
366         u64 old_value;
367
368         if (ctr >= NR_CTRS) {
369                 dev_dbg(sbd_core(), "%s:%u: ctr too big: %u\n", __func__,
370                         __LINE__, ctr);
371                 return;
372         }
373
374         result = lv1_set_lpm_counter_control(lpm_priv->lpm_id, ctr, val, mask,
375                                              &old_value);
376         if (result)
377                 dev_err(sbd_core(), "%s:%u: lv1_set_lpm_counter_control "
378                         "failed: ctr %u, %s\n", __func__, __LINE__, ctr,
379                         ps3_result(result));
380 }
381 EXPORT_SYMBOL_GPL(ps3_write_pm07_control);
382
383 /**
384  * ps3_read_pm - Read Other LPM control registers.
385  */
386
387 u32 ps3_read_pm(u32 cpu, enum pm_reg_name reg)
388 {
389         int result = 0;
390         u64 val = 0;
391
392         switch (reg) {
393         case pm_control:
394                 return lpm_priv->shadow.pm_control;
395         case trace_address:
396                 return CBE_PM_TRACE_BUF_EMPTY;
397         case pm_start_stop:
398                 return lpm_priv->shadow.pm_start_stop;
399         case pm_interval:
400                 result = lv1_set_lpm_interval(lpm_priv->lpm_id, 0, 0, &val);
401                 if (result) {
402                         val = 0;
403                         dev_dbg(sbd_core(), "%s:%u: lv1 set_interval failed: "
404                                 "reg %u, %s\n", __func__, __LINE__, reg,
405                                 ps3_result(result));
406                 }
407                 return (u32)val;
408         case group_control:
409                 return lpm_priv->shadow.group_control;
410         case debug_bus_control:
411                 return lpm_priv->shadow.debug_bus_control;
412         case pm_status:
413                 result = lv1_get_lpm_interrupt_status(lpm_priv->lpm_id,
414                                                       &val);
415                 if (result) {
416                         val = 0;
417                         dev_dbg(sbd_core(), "%s:%u: lv1 get_lpm_status failed: "
418                                 "reg %u, %s\n", __func__, __LINE__, reg,
419                                 ps3_result(result));
420                 }
421                 return (u32)val;
422         case ext_tr_timer:
423                 return 0;
424         default:
425                 dev_dbg(sbd_core(), "%s:%u: unknown reg: %d\n", __func__,
426                         __LINE__, reg);
427                 BUG();
428                 break;
429         }
430
431         return 0;
432 }
433 EXPORT_SYMBOL_GPL(ps3_read_pm);
434
435 /**
436  * ps3_write_pm - Write Other LPM control registers.
437  */
438
439 void ps3_write_pm(u32 cpu, enum pm_reg_name reg, u32 val)
440 {
441         int result = 0;
442         u64 dummy;
443
444         switch (reg) {
445         case group_control:
446                 if (val != lpm_priv->shadow.group_control)
447                         result = lv1_set_lpm_group_control(lpm_priv->lpm_id,
448                                                            val,
449                                                            PS3_WRITE_PM_MASK,
450                                                            &dummy);
451                 lpm_priv->shadow.group_control = val;
452                 break;
453         case debug_bus_control:
454                 if (val != lpm_priv->shadow.debug_bus_control)
455                         result = lv1_set_lpm_debug_bus_control(lpm_priv->lpm_id,
456                                                               val,
457                                                               PS3_WRITE_PM_MASK,
458                                                               &dummy);
459                 lpm_priv->shadow.debug_bus_control = val;
460                 break;
461         case pm_control:
462                 if (use_start_stop_bookmark)
463                         val |= (PS3_PM_CONTROL_PPU_TH0_BOOKMARK |
464                                 PS3_PM_CONTROL_PPU_TH1_BOOKMARK);
465                 if (val != lpm_priv->shadow.pm_control)
466                         result = lv1_set_lpm_general_control(lpm_priv->lpm_id,
467                                                              val,
468                                                              PS3_WRITE_PM_MASK,
469                                                              0, 0, &dummy,
470                                                              &dummy);
471                 lpm_priv->shadow.pm_control = val;
472                 break;
473         case pm_interval:
474                 result = lv1_set_lpm_interval(lpm_priv->lpm_id, val,
475                                               PS3_WRITE_PM_MASK, &dummy);
476                 break;
477         case pm_start_stop:
478                 if (val != lpm_priv->shadow.pm_start_stop)
479                         result = lv1_set_lpm_trigger_control(lpm_priv->lpm_id,
480                                                              val,
481                                                              PS3_WRITE_PM_MASK,
482                                                              &dummy);
483                 lpm_priv->shadow.pm_start_stop = val;
484                 break;
485         case trace_address:
486         case ext_tr_timer:
487         case pm_status:
488                 break;
489         default:
490                 dev_dbg(sbd_core(), "%s:%u: unknown reg: %d\n", __func__,
491                         __LINE__, reg);
492                 BUG();
493                 break;
494         }
495
496         if (result)
497                 dev_err(sbd_core(), "%s:%u: lv1 set_control failed: "
498                         "reg %u, %s\n", __func__, __LINE__, reg,
499                         ps3_result(result));
500 }
501 EXPORT_SYMBOL_GPL(ps3_write_pm);
502
503 /**
504  * ps3_get_ctr_size - Get the size of a physical counter.
505  *
506  * Returns either 16 or 32.
507  */
508
509 u32 ps3_get_ctr_size(u32 cpu, u32 phys_ctr)
510 {
511         u32 pm_ctrl;
512
513         if (phys_ctr >= NR_PHYS_CTRS) {
514                 dev_dbg(sbd_core(), "%s:%u: phys_ctr too big: %u\n", __func__,
515                         __LINE__, phys_ctr);
516                 return 0;
517         }
518
519         pm_ctrl = ps3_read_pm(cpu, pm_control);
520         return (pm_ctrl & CBE_PM_16BIT_CTR(phys_ctr)) ? 16 : 32;
521 }
522 EXPORT_SYMBOL_GPL(ps3_get_ctr_size);
523
524 /**
525  * ps3_set_ctr_size - Set the size of a physical counter to 16 or 32 bits.
526  */
527
528 void ps3_set_ctr_size(u32 cpu, u32 phys_ctr, u32 ctr_size)
529 {
530         u32 pm_ctrl;
531
532         if (phys_ctr >= NR_PHYS_CTRS) {
533                 dev_dbg(sbd_core(), "%s:%u: phys_ctr too big: %u\n", __func__,
534                         __LINE__, phys_ctr);
535                 return;
536         }
537
538         pm_ctrl = ps3_read_pm(cpu, pm_control);
539
540         switch (ctr_size) {
541         case 16:
542                 pm_ctrl |= CBE_PM_16BIT_CTR(phys_ctr);
543                 ps3_write_pm(cpu, pm_control, pm_ctrl);
544                 break;
545
546         case 32:
547                 pm_ctrl &= ~CBE_PM_16BIT_CTR(phys_ctr);
548                 ps3_write_pm(cpu, pm_control, pm_ctrl);
549                 break;
550         default:
551                 BUG();
552         }
553 }
554 EXPORT_SYMBOL_GPL(ps3_set_ctr_size);
555
556 static u64 pm_translate_signal_group_number_on_island2(u64 subgroup)
557 {
558
559         if (subgroup == 2)
560                 subgroup = 3;
561
562         if (subgroup <= 6)
563                 return PM_ISLAND2_BASE_SIGNAL_GROUP_NUMBER + subgroup;
564         else if (subgroup == 7)
565                 return PM_ISLAND2_SIGNAL_GROUP_NUMBER1;
566         else
567                 return PM_ISLAND2_SIGNAL_GROUP_NUMBER2;
568 }
569
570 static u64 pm_translate_signal_group_number_on_island3(u64 subgroup)
571 {
572
573         switch (subgroup) {
574         case 2:
575         case 3:
576         case 4:
577                 subgroup += 2;
578                 break;
579         case 5:
580                 subgroup = 8;
581                 break;
582         default:
583                 break;
584         }
585         return PM_ISLAND3_BASE_SIGNAL_GROUP_NUMBER + subgroup;
586 }
587
588 static u64 pm_translate_signal_group_number_on_island4(u64 subgroup)
589 {
590         return PM_ISLAND4_BASE_SIGNAL_GROUP_NUMBER + subgroup;
591 }
592
593 static u64 pm_translate_signal_group_number_on_island5(u64 subgroup)
594 {
595
596         switch (subgroup) {
597         case 3:
598                 subgroup = 4;
599                 break;
600         case 4:
601                 subgroup = 6;
602                 break;
603         default:
604                 break;
605         }
606         return PM_ISLAND5_BASE_SIGNAL_GROUP_NUMBER + subgroup;
607 }
608
609 static u64 pm_translate_signal_group_number_on_island6(u64 subgroup,
610                                                        u64 subsubgroup)
611 {
612         switch (subgroup) {
613         case 3:
614         case 4:
615         case 5:
616                 subgroup += 1;
617                 break;
618         default:
619                 break;
620         }
621
622         switch (subsubgroup) {
623         case 4:
624         case 5:
625         case 6:
626                 subsubgroup += 2;
627                 break;
628         case 7:
629         case 8:
630         case 9:
631         case 10:
632                 subsubgroup += 4;
633                 break;
634         case 11:
635         case 12:
636         case 13:
637                 subsubgroup += 5;
638                 break;
639         default:
640                 break;
641         }
642
643         if (subgroup <= 5)
644                 return (PM_ISLAND6_BASE_SIGNAL_GROUP_NUMBER + subgroup);
645         else
646                 return (PM_ISLAND6_BASE_SIGNAL_GROUP_NUMBER + subgroup
647                         + subsubgroup - 1);
648 }
649
650 static u64 pm_translate_signal_group_number_on_island7(u64 subgroup)
651 {
652         return PM_ISLAND7_BASE_SIGNAL_GROUP_NUMBER + subgroup;
653 }
654
655 static u64 pm_translate_signal_group_number_on_island8(u64 subgroup)
656 {
657         return PM_ISLAND8_BASE_SIGNAL_GROUP_NUMBER + subgroup;
658 }
659
660 static u64 pm_signal_group_to_ps3_lv1_signal_group(u64 group)
661 {
662         u64 island;
663         u64 subgroup;
664         u64 subsubgroup;
665
666         subgroup = 0;
667         subsubgroup = 0;
668         island = 0;
669         if (group < 1000) {
670                 if (group < 100) {
671                         if (20 <= group && group < 30) {
672                                 island = 2;
673                                 subgroup = group - 20;
674                         } else if (30 <= group && group < 40) {
675                                 island = 3;
676                                 subgroup = group - 30;
677                         } else if (40 <= group && group < 50) {
678                                 island = 4;
679                                 subgroup = group - 40;
680                         } else if (50 <= group && group < 60) {
681                                 island = 5;
682                                 subgroup = group - 50;
683                         } else if (60 <= group && group < 70) {
684                                 island = 6;
685                                 subgroup = group - 60;
686                         } else if (70 <= group && group < 80) {
687                                 island = 7;
688                                 subgroup = group - 70;
689                         } else if (80 <= group && group < 90) {
690                                 island = 8;
691                                 subgroup = group - 80;
692                         }
693                 } else if (200 <= group && group < 300) {
694                         island = 2;
695                         subgroup = group - 200;
696                 } else if (600 <= group && group < 700) {
697                         island = 6;
698                         subgroup = 5;
699                         subsubgroup = group - 650;
700                 }
701         } else if (6000 <= group && group < 7000) {
702                 island = 6;
703                 subgroup = 5;
704                 subsubgroup = group - 6500;
705         }
706
707         switch (island) {
708         case 2:
709                 return pm_translate_signal_group_number_on_island2(subgroup);
710         case 3:
711                 return pm_translate_signal_group_number_on_island3(subgroup);
712         case 4:
713                 return pm_translate_signal_group_number_on_island4(subgroup);
714         case 5:
715                 return pm_translate_signal_group_number_on_island5(subgroup);
716         case 6:
717                 return pm_translate_signal_group_number_on_island6(subgroup,
718                                                                    subsubgroup);
719         case 7:
720                 return pm_translate_signal_group_number_on_island7(subgroup);
721         case 8:
722                 return pm_translate_signal_group_number_on_island8(subgroup);
723         default:
724                 dev_dbg(sbd_core(), "%s:%u: island not found: %llu\n", __func__,
725                         __LINE__, group);
726                 BUG();
727                 break;
728         }
729         return 0;
730 }
731
732 static u64 pm_bus_word_to_ps3_lv1_bus_word(u8 word)
733 {
734
735         switch (word) {
736         case 1:
737                 return 0xF000;
738         case 2:
739                 return 0x0F00;
740         case 4:
741                 return 0x00F0;
742         case 8:
743         default:
744                 return 0x000F;
745         }
746 }
747
748 static int __ps3_set_signal(u64 lv1_signal_group, u64 bus_select,
749                             u64 signal_select, u64 attr1, u64 attr2, u64 attr3)
750 {
751         int ret;
752
753         ret = lv1_set_lpm_signal(lpm_priv->lpm_id, lv1_signal_group, bus_select,
754                                  signal_select, attr1, attr2, attr3);
755         if (ret)
756                 dev_err(sbd_core(),
757                         "%s:%u: error:%d 0x%llx 0x%llx 0x%llx 0x%llx 0x%llx 0x%llx\n",
758                         __func__, __LINE__, ret, lv1_signal_group, bus_select,
759                         signal_select, attr1, attr2, attr3);
760
761         return ret;
762 }
763
764 int ps3_set_signal(u64 signal_group, u8 signal_bit, u16 sub_unit,
765                    u8 bus_word)
766 {
767         int ret;
768         u64 lv1_signal_group;
769         u64 bus_select;
770         u64 signal_select;
771         u64 attr1, attr2, attr3;
772
773         if (signal_group == 0)
774                 return __ps3_set_signal(0, 0, 0, 0, 0, 0);
775
776         lv1_signal_group =
777                 pm_signal_group_to_ps3_lv1_signal_group(signal_group);
778         bus_select = pm_bus_word_to_ps3_lv1_bus_word(bus_word);
779
780         switch (signal_group) {
781         case PM_SIG_GROUP_SPU_TRIGGER:
782                 signal_select = 1;
783                 signal_select = signal_select << (63 - signal_bit);
784                 break;
785         case PM_SIG_GROUP_SPU_EVENT:
786                 signal_select = 1;
787                 signal_select = (signal_select << (63 - signal_bit)) | 0x3;
788                 break;
789         default:
790                 signal_select = 0;
791                 break;
792         }
793
794         /*
795          * 0: physical object.
796          * 1: logical object.
797          * This parameter is only used for the PPE and SPE signals.
798          */
799         attr1 = 1;
800
801         /*
802          * This parameter is used to specify the target physical/logical
803          * PPE/SPE object.
804          */
805         if (PM_SIG_GROUP_SPU <= signal_group &&
806                 signal_group < PM_SIG_GROUP_MFC_MAX)
807                 attr2 = sub_unit;
808         else
809                 attr2 = lpm_priv->pu_id;
810
811         /*
812          * This parameter is only used for setting the SPE signal.
813          */
814         attr3 = 0;
815
816         ret = __ps3_set_signal(lv1_signal_group, bus_select, signal_select,
817                                attr1, attr2, attr3);
818         if (ret)
819                 dev_err(sbd_core(), "%s:%u: __ps3_set_signal failed: %d\n",
820                         __func__, __LINE__, ret);
821
822         return ret;
823 }
824 EXPORT_SYMBOL_GPL(ps3_set_signal);
825
826 u32 ps3_get_hw_thread_id(int cpu)
827 {
828         return get_hard_smp_processor_id(cpu);
829 }
830 EXPORT_SYMBOL_GPL(ps3_get_hw_thread_id);
831
832 /**
833  * ps3_enable_pm - Enable the entire performance monitoring unit.
834  *
835  * When we enable the LPM, all pending writes to counters get committed.
836  */
837
838 void ps3_enable_pm(u32 cpu)
839 {
840         int result;
841         u64 tmp;
842         int insert_bookmark = 0;
843
844         lpm_priv->tb_count = 0;
845
846         if (use_start_stop_bookmark) {
847                 if (!(lpm_priv->shadow.pm_start_stop &
848                         (PS3_PM_START_STOP_START_MASK
849                         | PS3_PM_START_STOP_STOP_MASK))) {
850                         result = lv1_set_lpm_trigger_control(lpm_priv->lpm_id,
851                                 (PS3_PM_START_STOP_PPU_TH0_BOOKMARK_START |
852                                 PS3_PM_START_STOP_PPU_TH1_BOOKMARK_START |
853                                 PS3_PM_START_STOP_PPU_TH0_BOOKMARK_STOP |
854                                 PS3_PM_START_STOP_PPU_TH1_BOOKMARK_STOP),
855                                 0xFFFFFFFFFFFFFFFFULL, &tmp);
856
857                         if (result)
858                                 dev_err(sbd_core(), "%s:%u: "
859                                         "lv1_set_lpm_trigger_control failed: "
860                                         "%s\n", __func__, __LINE__,
861                                         ps3_result(result));
862
863                         insert_bookmark = !result;
864                 }
865         }
866
867         result = lv1_start_lpm(lpm_priv->lpm_id);
868
869         if (result)
870                 dev_err(sbd_core(), "%s:%u: lv1_start_lpm failed: %s\n",
871                         __func__, __LINE__, ps3_result(result));
872
873         if (use_start_stop_bookmark && !result && insert_bookmark)
874                 ps3_set_bookmark(get_tb() | PS3_PM_BOOKMARK_START);
875 }
876 EXPORT_SYMBOL_GPL(ps3_enable_pm);
877
878 /**
879  * ps3_disable_pm - Disable the entire performance monitoring unit.
880  */
881
882 void ps3_disable_pm(u32 cpu)
883 {
884         int result;
885         u64 tmp;
886
887         ps3_set_bookmark(get_tb() | PS3_PM_BOOKMARK_STOP);
888
889         result = lv1_stop_lpm(lpm_priv->lpm_id, &tmp);
890
891         if (result) {
892                 if (result != LV1_WRONG_STATE)
893                         dev_err(sbd_core(), "%s:%u: lv1_stop_lpm failed: %s\n",
894                                 __func__, __LINE__, ps3_result(result));
895                 return;
896         }
897
898         lpm_priv->tb_count = tmp;
899
900         dev_dbg(sbd_core(), "%s:%u: tb_count %llu (%llxh)\n", __func__, __LINE__,
901                 lpm_priv->tb_count, lpm_priv->tb_count);
902 }
903 EXPORT_SYMBOL_GPL(ps3_disable_pm);
904
905 /**
906  * ps3_lpm_copy_tb - Copy data from the trace buffer to a kernel buffer.
907  * @offset: Offset in bytes from the start of the trace buffer.
908  * @buf: Copy destination.
909  * @count: Maximum count of bytes to copy.
910  * @bytes_copied: Pointer to a variable that will receive the number of
911  *  bytes copied to @buf.
912  *
913  * On error @buf will contain any successfully copied trace buffer data
914  * and bytes_copied will be set to the number of bytes successfully copied.
915  */
916
917 int ps3_lpm_copy_tb(unsigned long offset, void *buf, unsigned long count,
918                     unsigned long *bytes_copied)
919 {
920         int result;
921
922         *bytes_copied = 0;
923
924         if (!lpm_priv->tb_cache)
925                 return -EPERM;
926
927         if (offset >= lpm_priv->tb_count)
928                 return 0;
929
930         count = min_t(u64, count, lpm_priv->tb_count - offset);
931
932         while (*bytes_copied < count) {
933                 const unsigned long request = count - *bytes_copied;
934                 u64 tmp;
935
936                 result = lv1_copy_lpm_trace_buffer(lpm_priv->lpm_id, offset,
937                                                    request, &tmp);
938                 if (result) {
939                         dev_dbg(sbd_core(), "%s:%u: 0x%lx bytes at 0x%lx\n",
940                                 __func__, __LINE__, request, offset);
941
942                         dev_err(sbd_core(), "%s:%u: lv1_copy_lpm_trace_buffer "
943                                 "failed: %s\n", __func__, __LINE__,
944                                 ps3_result(result));
945                         return result == LV1_WRONG_STATE ? -EBUSY : -EINVAL;
946                 }
947
948                 memcpy(buf, lpm_priv->tb_cache, tmp);
949                 buf += tmp;
950                 *bytes_copied += tmp;
951                 offset += tmp;
952         }
953         dev_dbg(sbd_core(), "%s:%u: copied %lxh bytes\n", __func__, __LINE__,
954                 *bytes_copied);
955
956         return 0;
957 }
958 EXPORT_SYMBOL_GPL(ps3_lpm_copy_tb);
959
960 /**
961  * ps3_lpm_copy_tb_to_user - Copy data from the trace buffer to a user buffer.
962  * @offset: Offset in bytes from the start of the trace buffer.
963  * @buf: A __user copy destination.
964  * @count: Maximum count of bytes to copy.
965  * @bytes_copied: Pointer to a variable that will receive the number of
966  *  bytes copied to @buf.
967  *
968  * On error @buf will contain any successfully copied trace buffer data
969  * and bytes_copied will be set to the number of bytes successfully copied.
970  */
971
972 int ps3_lpm_copy_tb_to_user(unsigned long offset, void __user *buf,
973                             unsigned long count, unsigned long *bytes_copied)
974 {
975         int result;
976
977         *bytes_copied = 0;
978
979         if (!lpm_priv->tb_cache)
980                 return -EPERM;
981
982         if (offset >= lpm_priv->tb_count)
983                 return 0;
984
985         count = min_t(u64, count, lpm_priv->tb_count - offset);
986
987         while (*bytes_copied < count) {
988                 const unsigned long request = count - *bytes_copied;
989                 u64 tmp;
990
991                 result = lv1_copy_lpm_trace_buffer(lpm_priv->lpm_id, offset,
992                                                    request, &tmp);
993                 if (result) {
994                         dev_dbg(sbd_core(), "%s:%u: 0x%lx bytes at 0x%lx\n",
995                                 __func__, __LINE__, request, offset);
996                         dev_err(sbd_core(), "%s:%u: lv1_copy_lpm_trace_buffer "
997                                 "failed: %s\n", __func__, __LINE__,
998                                 ps3_result(result));
999                         return result == LV1_WRONG_STATE ? -EBUSY : -EINVAL;
1000                 }
1001
1002                 result = copy_to_user(buf, lpm_priv->tb_cache, tmp);
1003
1004                 if (result) {
1005                         dev_dbg(sbd_core(), "%s:%u: 0x%llx bytes at 0x%p\n",
1006                                 __func__, __LINE__, tmp, buf);
1007                         dev_err(sbd_core(), "%s:%u: copy_to_user failed: %d\n",
1008                                 __func__, __LINE__, result);
1009                         return -EFAULT;
1010                 }
1011
1012                 buf += tmp;
1013                 *bytes_copied += tmp;
1014                 offset += tmp;
1015         }
1016         dev_dbg(sbd_core(), "%s:%u: copied %lxh bytes\n", __func__, __LINE__,
1017                 *bytes_copied);
1018
1019         return 0;
1020 }
1021 EXPORT_SYMBOL_GPL(ps3_lpm_copy_tb_to_user);
1022
1023 /**
1024  * ps3_get_and_clear_pm_interrupts -
1025  *
1026  * Clearing interrupts for the entire performance monitoring unit.
1027  * Reading pm_status clears the interrupt bits.
1028  */
1029
1030 u32 ps3_get_and_clear_pm_interrupts(u32 cpu)
1031 {
1032         return ps3_read_pm(cpu, pm_status);
1033 }
1034 EXPORT_SYMBOL_GPL(ps3_get_and_clear_pm_interrupts);
1035
1036 /**
1037  * ps3_enable_pm_interrupts -
1038  *
1039  * Enabling interrupts for the entire performance monitoring unit.
1040  * Enables the interrupt bits in the pm_status register.
1041  */
1042
1043 void ps3_enable_pm_interrupts(u32 cpu, u32 thread, u32 mask)
1044 {
1045         if (mask)
1046                 ps3_write_pm(cpu, pm_status, mask);
1047 }
1048 EXPORT_SYMBOL_GPL(ps3_enable_pm_interrupts);
1049
1050 /**
1051  * ps3_enable_pm_interrupts -
1052  *
1053  * Disabling interrupts for the entire performance monitoring unit.
1054  */
1055
1056 void ps3_disable_pm_interrupts(u32 cpu)
1057 {
1058         ps3_get_and_clear_pm_interrupts(cpu);
1059         ps3_write_pm(cpu, pm_status, 0);
1060 }
1061 EXPORT_SYMBOL_GPL(ps3_disable_pm_interrupts);
1062
1063 /**
1064  * ps3_lpm_open - Open the logical performance monitor device.
1065  * @tb_type: Specifies the type of trace buffer lv1 should use for this lpm
1066  *  instance, specified by one of enum ps3_lpm_tb_type.
1067  * @tb_cache: Optional user supplied buffer to use as the trace buffer cache.
1068  *  If NULL, the driver will allocate and manage an internal buffer.
1069  *  Unused when @tb_type is PS3_LPM_TB_TYPE_NONE.
1070  * @tb_cache_size: The size in bytes of the user supplied @tb_cache buffer.
1071  *  Unused when @tb_cache is NULL or @tb_type is PS3_LPM_TB_TYPE_NONE.
1072  */
1073
1074 int ps3_lpm_open(enum ps3_lpm_tb_type tb_type, void *tb_cache,
1075         u64 tb_cache_size)
1076 {
1077         int result;
1078         u64 tb_size;
1079
1080         BUG_ON(!lpm_priv);
1081         BUG_ON(tb_type != PS3_LPM_TB_TYPE_NONE
1082                 && tb_type != PS3_LPM_TB_TYPE_INTERNAL);
1083
1084         if (tb_type == PS3_LPM_TB_TYPE_NONE && tb_cache)
1085                 dev_dbg(sbd_core(), "%s:%u: bad in vals\n", __func__, __LINE__);
1086
1087         if (!atomic_add_unless(&lpm_priv->open, 1, 1)) {
1088                 dev_dbg(sbd_core(), "%s:%u: busy\n", __func__, __LINE__);
1089                 return -EBUSY;
1090         }
1091
1092         /* Note tb_cache needs 128 byte alignment. */
1093
1094         if (tb_type == PS3_LPM_TB_TYPE_NONE) {
1095                 lpm_priv->tb_cache_size = 0;
1096                 lpm_priv->tb_cache_internal = NULL;
1097                 lpm_priv->tb_cache = NULL;
1098         } else if (tb_cache) {
1099                 if (tb_cache != (void *)ALIGN((unsigned long)tb_cache, 128)
1100                         || tb_cache_size != ALIGN(tb_cache_size, 128)) {
1101                         dev_err(sbd_core(), "%s:%u: unaligned tb_cache\n",
1102                                 __func__, __LINE__);
1103                         result = -EINVAL;
1104                         goto fail_align;
1105                 }
1106                 lpm_priv->tb_cache_size = tb_cache_size;
1107                 lpm_priv->tb_cache_internal = NULL;
1108                 lpm_priv->tb_cache = tb_cache;
1109         } else {
1110                 lpm_priv->tb_cache_size = PS3_LPM_DEFAULT_TB_CACHE_SIZE;
1111                 lpm_priv->tb_cache_internal = kzalloc(
1112                         lpm_priv->tb_cache_size + 127, GFP_KERNEL);
1113                 if (!lpm_priv->tb_cache_internal) {
1114                         result = -ENOMEM;
1115                         goto fail_malloc;
1116                 }
1117                 lpm_priv->tb_cache = (void *)ALIGN(
1118                         (unsigned long)lpm_priv->tb_cache_internal, 128);
1119         }
1120
1121         result = lv1_construct_lpm(lpm_priv->node_id, tb_type, 0, 0,
1122                                 ps3_mm_phys_to_lpar(__pa(lpm_priv->tb_cache)),
1123                                 lpm_priv->tb_cache_size, &lpm_priv->lpm_id,
1124                                 &lpm_priv->outlet_id, &tb_size);
1125
1126         if (result) {
1127                 dev_err(sbd_core(), "%s:%u: lv1_construct_lpm failed: %s\n",
1128                         __func__, __LINE__, ps3_result(result));
1129                 result = -EINVAL;
1130                 goto fail_construct;
1131         }
1132
1133         lpm_priv->shadow.pm_control = PS3_LPM_SHADOW_REG_INIT;
1134         lpm_priv->shadow.pm_start_stop = PS3_LPM_SHADOW_REG_INIT;
1135         lpm_priv->shadow.group_control = PS3_LPM_SHADOW_REG_INIT;
1136         lpm_priv->shadow.debug_bus_control = PS3_LPM_SHADOW_REG_INIT;
1137
1138         dev_dbg(sbd_core(), "%s:%u: lpm_id 0x%llx, outlet_id 0x%llx, "
1139                 "tb_size 0x%llx\n", __func__, __LINE__, lpm_priv->lpm_id,
1140                 lpm_priv->outlet_id, tb_size);
1141
1142         return 0;
1143
1144 fail_construct:
1145         kfree(lpm_priv->tb_cache_internal);
1146         lpm_priv->tb_cache_internal = NULL;
1147 fail_malloc:
1148 fail_align:
1149         atomic_dec(&lpm_priv->open);
1150         return result;
1151 }
1152 EXPORT_SYMBOL_GPL(ps3_lpm_open);
1153
1154 /**
1155  * ps3_lpm_close - Close the lpm device.
1156  *
1157  */
1158
1159 int ps3_lpm_close(void)
1160 {
1161         dev_dbg(sbd_core(), "%s:%u\n", __func__, __LINE__);
1162
1163         lv1_destruct_lpm(lpm_priv->lpm_id);
1164         lpm_priv->lpm_id = 0;
1165
1166         kfree(lpm_priv->tb_cache_internal);
1167         lpm_priv->tb_cache_internal = NULL;
1168
1169         atomic_dec(&lpm_priv->open);
1170         return 0;
1171 }
1172 EXPORT_SYMBOL_GPL(ps3_lpm_close);
1173
1174 static int ps3_lpm_probe(struct ps3_system_bus_device *dev)
1175 {
1176         dev_dbg(&dev->core, " -> %s:%u\n", __func__, __LINE__);
1177
1178         if (lpm_priv) {
1179                 dev_info(&dev->core, "%s:%u: called twice\n",
1180                         __func__, __LINE__);
1181                 return -EBUSY;
1182         }
1183
1184         lpm_priv = kzalloc(sizeof(*lpm_priv), GFP_KERNEL);
1185
1186         if (!lpm_priv)
1187                 return -ENOMEM;
1188
1189         lpm_priv->sbd = dev;
1190         lpm_priv->node_id = dev->lpm.node_id;
1191         lpm_priv->pu_id = dev->lpm.pu_id;
1192         lpm_priv->rights = dev->lpm.rights;
1193
1194         dev_info(&dev->core, " <- %s:%u:\n", __func__, __LINE__);
1195
1196         return 0;
1197 }
1198
1199 static void ps3_lpm_remove(struct ps3_system_bus_device *dev)
1200 {
1201         dev_dbg(&dev->core, " -> %s:%u:\n", __func__, __LINE__);
1202
1203         ps3_lpm_close();
1204
1205         kfree(lpm_priv);
1206         lpm_priv = NULL;
1207
1208         dev_info(&dev->core, " <- %s:%u:\n", __func__, __LINE__);
1209 }
1210
1211 static struct ps3_system_bus_driver ps3_lpm_driver = {
1212         .match_id = PS3_MATCH_ID_LPM,
1213         .core.name      = "ps3-lpm",
1214         .core.owner     = THIS_MODULE,
1215         .probe          = ps3_lpm_probe,
1216         .remove         = ps3_lpm_remove,
1217         .shutdown       = ps3_lpm_remove,
1218 };
1219
1220 static int __init ps3_lpm_init(void)
1221 {
1222         pr_debug("%s:%d:\n", __func__, __LINE__);
1223         return ps3_system_bus_driver_register(&ps3_lpm_driver);
1224 }
1225
1226 static void __exit ps3_lpm_exit(void)
1227 {
1228         pr_debug("%s:%d:\n", __func__, __LINE__);
1229         ps3_system_bus_driver_unregister(&ps3_lpm_driver);
1230 }
1231
1232 module_init(ps3_lpm_init);
1233 module_exit(ps3_lpm_exit);
1234
1235 MODULE_LICENSE("GPL v2");
1236 MODULE_DESCRIPTION("PS3 Logical Performance Monitor Driver");
1237 MODULE_AUTHOR("Sony Corporation");
1238 MODULE_ALIAS(PS3_MODULE_ALIAS_LPM);