blob: ffd0b8d13703005cfd3eff0b6813fb37ab319811 [file] [log] [blame]
Pratik Patel7831c082011-06-08 21:44:37 -07001/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#include <linux/kernel.h>
14#include <linux/module.h>
15#include <linux/platform_device.h>
16#include <linux/io.h>
17#include <linux/err.h>
18#include <linux/fs.h>
19#include <linux/miscdevice.h>
20#include <linux/uaccess.h>
21#include <linux/slab.h>
22#include <linux/delay.h>
23#include <linux/smp.h>
24#include <linux/percpu.h>
25#include <linux/wakelock.h>
26#include <linux/pm_qos_params.h>
27#include <linux/clk.h>
28#include <asm/atomic.h>
29
30#include "qdss.h"
31
32#define ptm_writel(ptm, cpu, val, off) \
33 __raw_writel((val), ptm.base + (SZ_4K * cpu) + off)
34#define ptm_readl(ptm, cpu, off) \
35 __raw_readl(ptm.base + (SZ_4K * cpu) + off)
36
37/*
38 * Device registers:
39 * 0x000 - 0x2FC: Trace registers
40 * 0x300 - 0x314: Management registers
41 * 0x318 - 0xEFC: Trace registers
42 *
43 * Coresight registers
44 * 0xF00 - 0xF9C: Management registers
45 * 0xFA0 - 0xFA4: Management registers in PFTv1.0
46 * Trace registers in PFTv1.1
47 * 0xFA8 - 0xFFC: Management registers
48 */
49
50/* Trace registers (0x000-0x2FC) */
51#define ETMCR (0x000)
52#define ETMCCR (0x004)
53#define ETMTRIGGER (0x008)
54#define ETMSR (0x010)
55#define ETMSCR (0x014)
56#define ETMTSSCR (0x018)
57#define ETMTEEVR (0x020)
58#define ETMTECR1 (0x024)
59#define ETMFFLR (0x02C)
60#define ETMACVRn(n) (0x040 + (n * 4))
61#define ETMACTRn(n) (0x080 + (n * 4))
62#define ETMCNTRLDVRn(n) (0x140 + (n * 4))
63#define ETMCNTENRn(n) (0x150 + (n * 4))
64#define ETMCNTRLDEVRn(n) (0x160 + (n * 4))
65#define ETMCNTVRn(n) (0x170 + (n * 4))
66#define ETMSQ12EVR (0x180)
67#define ETMSQ21EVR (0x184)
68#define ETMSQ23EVR (0x188)
69#define ETMSQ32EVR (0x18C)
70#define ETMSQ13EVR (0x190)
71#define ETMSQ31EVR (0x194)
72#define ETMSQR (0x19C)
73#define ETMEXTOUTEVRn(n) (0x1A0 + (n * 4))
74#define ETMCIDCVRn(n) (0x1B0 + (n * 4))
75#define ETMCIDCMR (0x1BC)
76#define ETMIMPSPEC0 (0x1C0)
77#define ETMIMPSPEC1 (0x1C4)
78#define ETMIMPSPEC2 (0x1C8)
79#define ETMIMPSPEC3 (0x1CC)
80#define ETMIMPSPEC4 (0x1D0)
81#define ETMIMPSPEC5 (0x1D4)
82#define ETMIMPSPEC6 (0x1D8)
83#define ETMIMPSPEC7 (0x1DC)
84#define ETMSYNCFR (0x1E0)
85#define ETMIDR (0x1E4)
86#define ETMCCER (0x1E8)
87#define ETMEXTINSELR (0x1EC)
88#define ETMTESSEICR (0x1F0)
89#define ETMEIBCR (0x1F4)
90#define ETMTSEVR (0x1F8)
91#define ETMAUXCR (0x1FC)
92#define ETMTRACEIDR (0x200)
93#define ETMVMIDCVR (0x204)
94/* Management registers (0x300-0x314) */
95#define ETMOSLAR (0x300)
96#define ETMOSLSR (0x304)
97#define ETMOSSRR (0x308)
98#define ETMPDCR (0x310)
99#define ETMPDSR (0x314)
100
101
102#define PTM_LOCK(cpu) \
103do { \
104 mb(); \
105 ptm_writel(ptm, cpu, MAGIC2, CS_LAR); \
106} while (0)
107#define PTM_UNLOCK(cpu) \
108do { \
109 ptm_writel(ptm, cpu, MAGIC1, CS_LAR); \
110 mb(); \
111} while (0)
112
113#define PTM_OS_LOCK(cpu) \
114do { \
115 ptm_writel(ptm, cpu, MAGIC1, ETMOSLAR); \
116 mb(); \
117} while (0)
118#define PTM_OS_UNLOCK(cpu) \
119do { \
120 ptm_writel(ptm, cpu, MAGIC2, ETMOSLAR); \
121 mb(); \
122} while (0)
123
124#define MAX_TRACE_REGS (78)
125#define MAX_STATE_SIZE (MAX_TRACE_REGS * num_possible_cpus())
126
127/* Forward declarations */
128static void ptm_cfg_rw_init(void);
129
130static int trace_on_boot;
131module_param_named(
132 trace_on_boot, trace_on_boot, int, S_IRUGO
133);
134
135struct ptm_config {
136 /* read only config registers */
137 uint32_t config_code;
138 /* derived values */
139 uint8_t nr_addr_comp;
140 uint8_t nr_cntr;
141 uint8_t nr_ext_input;
142 uint8_t nr_ext_output;
143 uint8_t nr_context_id_comp;
144
145 uint32_t config_code_extn;
146 /* derived values */
147 uint8_t nr_extnd_ext_input_sel;
148 uint8_t nr_instr_resources;
149
150 uint32_t system_config;
151 /* derived values */
152 uint8_t fifofull_supported;
153 uint8_t nr_procs_supported;
154
155 /* read-write registers */
156 uint32_t main_control;
157 uint32_t trigger_event;
158 uint32_t te_start_stop_control;
159 uint32_t te_event;
160 uint32_t te_control;
161 uint32_t fifofull_level;
162 uint32_t addr_comp_value[16];
163 uint32_t addr_comp_access_type[16];
164 uint32_t cntr_reload_value[4];
165 uint32_t cntr_enable_event[4];
166 uint32_t cntr_reload_event[4];
167 uint32_t cntr_value[4];
168 uint32_t seq_state_12_event;
169 uint32_t seq_state_21_event;
170 uint32_t seq_state_23_event;
171 uint32_t seq_state_32_event;
172 uint32_t seq_state_13_event;
173 uint32_t seq_state_31_event;
174 uint32_t current_seq_state;
175 uint32_t ext_output_event[4];
176 uint32_t context_id_comp_value[3];
177 uint32_t context_id_comp_mask;
178 uint32_t sync_freq;
179 uint32_t extnd_ext_input_sel;
180 uint32_t ts_event;
181 uint32_t aux_control;
182 uint32_t coresight_trace_id;
183 uint32_t vmid_comp_value;
184};
185
186struct ptm_ctx {
187 struct ptm_config cfg;
188 void __iomem *base;
189 uint32_t *state;
190 bool trace_enabled;
191 int *cpu_restore;
192 struct wake_lock wake_lock;
193 struct pm_qos_request_list qos_req;
194 atomic_t in_use;
195 struct device *dev;
196 struct clk *qdss_at_clk;
197 struct clk *qdss_pclkdbg_clk;
198 struct clk *qdss_pclk;
199 struct clk *qdss_traceclkin_clk;
200 struct clk *qdss_tsctr_clk;
201};
202
203static struct ptm_ctx ptm;
204
205/* Memory mapped writes to clear os lock don't work */
206static void ptm_os_unlock(void *unused)
207{
208 unsigned long value = 0x0;
209
210 asm("mcr p14, 1, %0, c1, c0, 4\n\t" : : "r" (value));
211 asm("isb\n\t");
212}
213
214static int ptm_clock_enable(void)
215{
216 int ret;
217
218 ret = clk_enable(ptm.qdss_at_clk);
219 if (WARN(ret, "qdss_at_clk not enabled (%d)\n", ret))
220 goto err;
221
222 ret = clk_enable(ptm.qdss_pclkdbg_clk);
223 if (WARN(ret, "qdss_pclkdbg_clk not enabled (%d)\n", ret))
224 goto err_pclkdbg;
225
226 ret = clk_enable(ptm.qdss_pclk);
227 if (WARN(ret, "qdss_pclk not enabled (%d)\n", ret))
228 goto err_pclk;
229
230 ret = clk_enable(ptm.qdss_traceclkin_clk);
231 if (WARN(ret, "qdss_traceclkin_clk not enabled (%d)\n", ret))
232 goto err_traceclkin;
233
234 ret = clk_enable(ptm.qdss_tsctr_clk);
235 if (WARN(ret, "qdss_tsctr_clk not enabled (%d)\n", ret))
236 goto err_tsctr;
237
238 return 0;
239
240err_tsctr:
241 clk_disable(ptm.qdss_traceclkin_clk);
242err_traceclkin:
243 clk_disable(ptm.qdss_pclk);
244err_pclk:
245 clk_disable(ptm.qdss_pclkdbg_clk);
246err_pclkdbg:
247 clk_disable(ptm.qdss_at_clk);
248err:
249 return ret;
250}
251
252static void ptm_clock_disable(void)
253{
254 clk_disable(ptm.qdss_tsctr_clk);
255 clk_disable(ptm.qdss_traceclkin_clk);
256 clk_disable(ptm.qdss_pclk);
257 clk_disable(ptm.qdss_pclkdbg_clk);
258 clk_disable(ptm.qdss_at_clk);
259}
260
261static void ptm_set_powerdown(int cpu)
262{
263 uint32_t etmcr;
264
265 etmcr = ptm_readl(ptm, cpu, ETMCR);
266 etmcr |= BIT(0);
267 ptm_writel(ptm, cpu, etmcr, ETMCR);
268}
269
270static void ptm_clear_powerdown(int cpu)
271{
272 uint32_t etmcr;
273
274 etmcr = ptm_readl(ptm, cpu, ETMCR);
275 etmcr &= ~BIT(0);
276 ptm_writel(ptm, cpu, etmcr, ETMCR);
277}
278
279static void ptm_set_prog(int cpu)
280{
281 uint32_t etmcr;
282 int count;
283
284 etmcr = ptm_readl(ptm, cpu, ETMCR);
285 etmcr |= BIT(10);
286 ptm_writel(ptm, cpu, etmcr, ETMCR);
287
288 for (count = TIMEOUT_US; BVAL(ptm_readl(ptm, cpu, ETMSR), 1) != 1
289 && count > 0; count--)
290 udelay(1);
291 WARN(count == 0, "timeout while setting prog bit\n");
292}
293
294static void ptm_clear_prog(int cpu)
295{
296 uint32_t etmcr;
297 int count;
298
299 etmcr = ptm_readl(ptm, cpu, ETMCR);
300 etmcr &= ~BIT(10);
301 ptm_writel(ptm, cpu, etmcr, ETMCR);
302
303 for (count = TIMEOUT_US; BVAL(ptm_readl(ptm, cpu, ETMSR), 1) != 0
304 && count > 0; count--)
305 udelay(1);
306 WARN(count == 0, "timeout while clearing prog bit\n");
307}
308
309static void __ptm_trace_enable(void)
310{
311 int i, cpu;
312
313 for_each_online_cpu(cpu) {
314 PTM_UNLOCK(cpu);
315 ptm_clear_powerdown(cpu);
316 ptm_set_prog(cpu);
317
318 ptm_writel(ptm, cpu, ptm.cfg.main_control | BIT(10), ETMCR);
319 ptm_writel(ptm, cpu, ptm.cfg.trigger_event, ETMTRIGGER);
320 ptm_writel(ptm, cpu, ptm.cfg.te_start_stop_control, ETMTSSCR);
321 ptm_writel(ptm, cpu, ptm.cfg.te_event, ETMTEEVR);
322 ptm_writel(ptm, cpu, ptm.cfg.te_control, ETMTECR1);
323 ptm_writel(ptm, cpu, ptm.cfg.fifofull_level, ETMFFLR);
324 for (i = 0; i < ptm.cfg.nr_addr_comp; i++) {
325 ptm_writel(ptm, cpu, ptm.cfg.addr_comp_value[i],
326 ETMACVRn(i));
327 ptm_writel(ptm, cpu, ptm.cfg.addr_comp_access_type[i],
328 ETMACTRn(i));
329 }
330 for (i = 0; i < ptm.cfg.nr_cntr; i++) {
331 ptm_writel(ptm, cpu, ptm.cfg.cntr_reload_value[i],
332 ETMCNTRLDVRn(i));
333 ptm_writel(ptm, cpu, ptm.cfg.cntr_enable_event[i],
334 ETMCNTENRn(i));
335 ptm_writel(ptm, cpu, ptm.cfg.cntr_reload_event[i],
336 ETMCNTRLDEVRn(i));
337 ptm_writel(ptm, cpu, ptm.cfg.cntr_value[i],
338 ETMCNTVRn(i));
339 }
340 ptm_writel(ptm, cpu, ptm.cfg.seq_state_12_event, ETMSQ12EVR);
341 ptm_writel(ptm, cpu, ptm.cfg.seq_state_21_event, ETMSQ21EVR);
342 ptm_writel(ptm, cpu, ptm.cfg.seq_state_23_event, ETMSQ23EVR);
343 ptm_writel(ptm, cpu, ptm.cfg.seq_state_32_event, ETMSQ32EVR);
344 ptm_writel(ptm, cpu, ptm.cfg.seq_state_13_event, ETMSQ13EVR);
345 ptm_writel(ptm, cpu, ptm.cfg.seq_state_31_event, ETMSQ31EVR);
346 ptm_writel(ptm, cpu, ptm.cfg.current_seq_state, ETMSQR);
347 for (i = 0; i < ptm.cfg.nr_ext_output; i++)
348 ptm_writel(ptm, cpu, ptm.cfg.ext_output_event[i],
349 ETMEXTOUTEVRn(i));
350 for (i = 0; i < ptm.cfg.nr_context_id_comp; i++)
351 ptm_writel(ptm, cpu, ptm.cfg.context_id_comp_value[i],
352 ETMCIDCVRn(i));
353 ptm_writel(ptm, cpu, ptm.cfg.context_id_comp_mask, ETMCIDCMR);
354 ptm_writel(ptm, cpu, ptm.cfg.sync_freq, ETMSYNCFR);
355 ptm_writel(ptm, cpu, ptm.cfg.extnd_ext_input_sel, ETMEXTINSELR);
356 ptm_writel(ptm, cpu, ptm.cfg.ts_event, ETMTSEVR);
357 ptm_writel(ptm, cpu, ptm.cfg.aux_control, ETMAUXCR);
358 ptm_writel(ptm, cpu, ptm.cfg.vmid_comp_value, ETMVMIDCVR);
359
360 ptm_clear_prog(cpu);
361 PTM_LOCK(cpu);
362 }
363}
364
365static int ptm_trace_enable(void)
366{
367 int ret;
368
369 ret = ptm_clock_enable();
370 if (ret)
371 return ret;
372
373 wake_lock(&ptm.wake_lock);
374 /* 1. causes all cpus to come out of idle PC
375 * 2. prevents idle PC until save restore flag is enabled atomically
376 */
377 pm_qos_update_request(&ptm.qos_req, 0);
378
379 etb_disable();
380 tpiu_disable();
381 /* enable ETB first to avoid loosing any trace data */
382 etb_enable();
383 funnel_enable(0x0, 0x3);
384 ptm_os_unlock(NULL);
385 smp_call_function(ptm_os_unlock, NULL, 1);
386 __ptm_trace_enable();
387
388 ptm.trace_enabled = true;
389
390 pm_qos_update_request(&ptm.qos_req, PM_QOS_DEFAULT_VALUE);
391 wake_unlock(&ptm.wake_lock);
392
393 return 0;
394}
395
396static void __ptm_trace_disable(void)
397{
398 int cpu;
399
400 for_each_online_cpu(cpu) {
401 PTM_UNLOCK(cpu);
402 ptm_set_prog(cpu);
403
404 /* program trace enable to low by using always false event */
405 ptm_writel(ptm, cpu, 0x6F | BIT(14), ETMTEEVR);
406
407 ptm_set_powerdown(cpu);
408 PTM_LOCK(cpu);
409 }
410}
411
412static void ptm_trace_disable(void)
413{
414 int cpu;
415
416 wake_lock(&ptm.wake_lock);
417 /* 1. causes all cpus to come out of idle PC
418 * 2. prevents idle PC until save restore flag is disabled atomically
419 */
420 pm_qos_update_request(&ptm.qos_req, 0);
421
422 ptm_os_unlock(NULL);
423 smp_call_function(ptm_os_unlock, NULL, 1);
424 __ptm_trace_disable();
425 etb_dump();
426 etb_disable();
427 funnel_disable(0x0, 0x3);
428
429 ptm.trace_enabled = false;
430
431 for_each_online_cpu(cpu)
432 *per_cpu_ptr(ptm.cpu_restore, cpu) = 0;
433
434 pm_qos_update_request(&ptm.qos_req, PM_QOS_DEFAULT_VALUE);
435 wake_unlock(&ptm.wake_lock);
436
437 ptm_clock_disable();
438}
439
440static int ptm_open(struct inode *inode, struct file *file)
441{
442 if (atomic_cmpxchg(&ptm.in_use, 0, 1))
443 return -EBUSY;
444
445 dev_dbg(ptm.dev, "%s: successfully opened\n", __func__);
446 return 0;
447}
448
449static void ptm_range_filter(char range, uint32_t reg1,
450 uint32_t addr1, uint32_t reg2, uint32_t addr2)
451{
452 ptm.cfg.addr_comp_value[reg1] = addr1;
453 ptm.cfg.addr_comp_value[reg2] = addr2;
454
455 ptm.cfg.te_control |= (1 << (reg1/2));
456 if (range == 'i')
457 ptm.cfg.te_control &= ~BIT(24);
458 else if (range == 'e')
459 ptm.cfg.te_control |= BIT(24);
460}
461
462static void ptm_start_stop_filter(char start_stop,
463 uint32_t reg, uint32_t addr)
464{
465 ptm.cfg.addr_comp_value[reg] = addr;
466
467 if (start_stop == 's')
468 ptm.cfg.te_start_stop_control |= (1 << reg);
469 else if (start_stop == 't')
470 ptm.cfg.te_start_stop_control |= (1 << (reg + 16));
471
472 ptm.cfg.te_control |= BIT(25);
473}
474
475#define MAX_COMMAND_STRLEN 40
476static ssize_t ptm_write(struct file *file, const char __user *data,
477 size_t len, loff_t *ppos)
478{
479 char command[MAX_COMMAND_STRLEN];
480 int str_len;
481 unsigned long reg1, reg2;
482 unsigned long addr1, addr2;
483
484 str_len = strnlen_user(data, MAX_COMMAND_STRLEN);
485 dev_dbg(ptm.dev, "string length: %d", str_len);
486 if (str_len == 0 || str_len == (MAX_COMMAND_STRLEN+1)) {
487 dev_err(ptm.dev, "error in str_len: %d", str_len);
488 return -EFAULT;
489 }
490 /* includes the null character */
491 if (copy_from_user(command, data, str_len)) {
492 dev_err(ptm.dev, "error in copy_from_user: %d", str_len);
493 return -EFAULT;
494 }
495
496 dev_dbg(ptm.dev, "input = %s", command);
497
498 switch (command[0]) {
499 case '0':
500 if (ptm.trace_enabled) {
501 ptm_trace_disable();
502 dev_info(ptm.dev, "tracing disabled\n");
503 } else
504 dev_err(ptm.dev, "trace already disabled\n");
505
506 break;
507 case '1':
508 if (!ptm.trace_enabled) {
509 if (!ptm_trace_enable())
510 dev_info(ptm.dev, "tracing enabled\n");
511 else
512 dev_err(ptm.dev, "error enabling trace\n");
513 } else
514 dev_err(ptm.dev, "trace already enabled\n");
515 break;
516 case 'f':
517 switch (command[2]) {
518 case 'i':
519 switch (command[4]) {
520 case 'i':
521 if (sscanf(&command[6], "%lx:%lx:%lx:%lx\\0",
522 &reg1, &addr1, &reg2, &addr2) != 4)
523 goto err_out;
524 if (reg1 > 7 || reg2 > 7 || (reg1 % 2))
525 goto err_out;
526 ptm_range_filter('i',
527 reg1, addr1, reg2, addr2);
528 break;
529 case 'e':
530 if (sscanf(&command[6], "%lx:%lx:%lx:%lx\\0",
531 &reg1, &addr1, &reg2, &addr2) != 4)
532 goto err_out;
533 if (reg1 > 7 || reg2 > 7 || (reg1 % 2)
534 || command[2] == 'd')
535 goto err_out;
536 ptm_range_filter('e',
537 reg1, addr1, reg2, addr2);
538 break;
539 case 's':
540 if (sscanf(&command[6], "%lx:%lx\\0",
541 &reg1, &addr1) != 2)
542 goto err_out;
543 if (reg1 > 7)
544 goto err_out;
545 ptm_start_stop_filter('s', reg1, addr1);
546 break;
547 case 't':
548 if (sscanf(&command[6], "%lx:%lx\\0",
549 &reg1, &addr1) != 2)
550 goto err_out;
551 if (reg1 > 7)
552 goto err_out;
553 ptm_start_stop_filter('t', reg1, addr1);
554 break;
555 default:
556 goto err_out;
557 }
558 break;
559 case 'r':
560 ptm_cfg_rw_init();
561 break;
562 default:
563 goto err_out;
564 }
565 break;
566 default:
567 goto err_out;
568 }
569
570 return len;
571
572err_out:
573 return -EFAULT;
574}
575
576static int ptm_release(struct inode *inode, struct file *file)
577{
578 atomic_set(&ptm.in_use, 0);
579 dev_dbg(ptm.dev, "%s: released\n", __func__);
580 return 0;
581}
582
583static const struct file_operations ptm_fops = {
584 .owner = THIS_MODULE,
585 .open = ptm_open,
586 .write = ptm_write,
587 .release = ptm_release,
588};
589
590static struct miscdevice ptm_misc = {
591 .name = "msm_ptm",
592 .minor = MISC_DYNAMIC_MINOR,
593 .fops = &ptm_fops,
594};
595
596static void ptm_save_reg(int cpu)
597{
598 uint32_t i;
599 int j;
600
601 PTM_UNLOCK(cpu);
602
603 i = cpu * MAX_TRACE_REGS;
604
605 ptm.state[i++] = ptm_readl(ptm, cpu, ETMCR);
606 ptm_set_prog(cpu);
607
608 ptm.state[i++] = ptm_readl(ptm, cpu, ETMTRIGGER);
609 ptm.state[i++] = ptm_readl(ptm, cpu, ETMSR);
610 ptm.state[i++] = ptm_readl(ptm, cpu, ETMTSSCR);
611 ptm.state[i++] = ptm_readl(ptm, cpu, ETMTEEVR);
612 ptm.state[i++] = ptm_readl(ptm, cpu, ETMTECR1);
613 ptm.state[i++] = ptm_readl(ptm, cpu, ETMFFLR);
614 for (j = 0; j < ptm.cfg.nr_addr_comp; j++) {
615 ptm.state[i++] = ptm_readl(ptm, cpu, ETMACVRn(j));
616 ptm.state[i++] = ptm_readl(ptm, cpu, ETMACTRn(j));
617 }
618 for (j = 0; j < ptm.cfg.nr_cntr; j++) {
619 ptm.state[i++] = ptm_readl(ptm, cpu, ETMCNTRLDVRn(j));
620 ptm.state[i++] = ptm_readl(ptm, cpu, ETMCNTENRn(j));
621 ptm.state[i++] = ptm_readl(ptm, cpu, ETMCNTRLDEVRn(j));
622 ptm.state[i++] = ptm_readl(ptm, cpu, ETMCNTVRn(j));
623 }
624 ptm.state[i++] = ptm_readl(ptm, cpu, ETMSQ12EVR);
625 ptm.state[i++] = ptm_readl(ptm, cpu, ETMSQ21EVR);
626 ptm.state[i++] = ptm_readl(ptm, cpu, ETMSQ23EVR);
627 ptm.state[i++] = ptm_readl(ptm, cpu, ETMSQ32EVR);
628 ptm.state[i++] = ptm_readl(ptm, cpu, ETMSQ13EVR);
629 ptm.state[i++] = ptm_readl(ptm, cpu, ETMSQ31EVR);
630 ptm.state[i++] = ptm_readl(ptm, cpu, ETMSQR);
631 for (j = 0; j < ptm.cfg.nr_ext_output; j++)
632 ptm.state[i++] = ptm_readl(ptm, cpu, ETMEXTOUTEVRn(j));
633 for (j = 0; j < ptm.cfg.nr_context_id_comp; j++)
634 ptm.state[i++] = ptm_readl(ptm, cpu, ETMCIDCVRn(j));
635 ptm.state[i++] = ptm_readl(ptm, cpu, ETMCIDCMR);
636 ptm.state[i++] = ptm_readl(ptm, cpu, ETMSYNCFR);
637 ptm.state[i++] = ptm_readl(ptm, cpu, ETMEXTINSELR);
638 ptm.state[i++] = ptm_readl(ptm, cpu, ETMTSEVR);
639 ptm.state[i++] = ptm_readl(ptm, cpu, ETMAUXCR);
640 ptm.state[i++] = ptm_readl(ptm, cpu, ETMVMIDCVR);
641 ptm.state[i++] = ptm_readl(ptm, cpu, CS_CLAIMSET);
642 ptm.state[i++] = ptm_readl(ptm, cpu, CS_CLAIMCLR);
643
644 PTM_LOCK(cpu);
645}
646
647static void ptm_restore_reg(int cpu)
648{
649 uint32_t i;
650 int j;
651
652 ptm_os_unlock(NULL);
653 PTM_UNLOCK(cpu);
654
655 i = cpu * MAX_TRACE_REGS;
656
657 ptm_clear_powerdown(cpu);
658 ptm_set_prog(cpu);
659 /* Ensure prog bit doesn't get cleared since we have set it above.
660 * Power down bit should already be clear in the saved state.
661 */
662 ptm_writel(ptm, cpu, ptm.state[i++] | BIT(10), ETMCR);
663
664 ptm_writel(ptm, cpu, ptm.state[i++], ETMTRIGGER);
665 ptm_writel(ptm, cpu, ptm.state[i++], ETMSR);
666 ptm_writel(ptm, cpu, ptm.state[i++], ETMTSSCR);
667 ptm_writel(ptm, cpu, ptm.state[i++], ETMTEEVR);
668 ptm_writel(ptm, cpu, ptm.state[i++], ETMTECR1);
669 ptm_writel(ptm, cpu, ptm.state[i++], ETMFFLR);
670 for (j = 0; j < ptm.cfg.nr_addr_comp; j++) {
671 ptm_writel(ptm, cpu, ptm.state[i++], ETMACVRn(j));
672 ptm_writel(ptm, cpu, ptm.state[i++], ETMACTRn(j));
673 }
674 for (j = 0; j < ptm.cfg.nr_cntr; j++) {
675 ptm_writel(ptm, cpu, ptm.state[i++], ETMCNTRLDVRn(j));
676 ptm_writel(ptm, cpu, ptm.state[i++], ETMCNTENRn(j));
677 ptm_writel(ptm, cpu, ptm.state[i++], ETMCNTRLDEVRn(j));
678 ptm_writel(ptm, cpu, ptm.state[i++], ETMCNTVRn(j));
679 }
680 ptm_writel(ptm, cpu, ptm.state[i++], ETMSQ12EVR);
681 ptm_writel(ptm, cpu, ptm.state[i++], ETMSQ21EVR);
682 ptm_writel(ptm, cpu, ptm.state[i++], ETMSQ23EVR);
683 ptm_writel(ptm, cpu, ptm.state[i++], ETMSQ32EVR);
684 ptm_writel(ptm, cpu, ptm.state[i++], ETMSQ13EVR);
685 ptm_writel(ptm, cpu, ptm.state[i++], ETMSQ31EVR);
686 ptm_writel(ptm, cpu, ptm.state[i++], ETMSQR);
687 for (j = 0; j < ptm.cfg.nr_ext_output; j++)
688 ptm_writel(ptm, cpu, ptm.state[i++], ETMEXTOUTEVRn(j));
689 for (j = 0; j < ptm.cfg.nr_context_id_comp; j++)
690 ptm_writel(ptm, cpu, ptm.state[i++], ETMCIDCVRn(j));
691 ptm_writel(ptm, cpu, ptm.state[i++], ETMCIDCMR);
692 ptm_writel(ptm, cpu, ptm.state[i++], ETMSYNCFR);
693 ptm_writel(ptm, cpu, ptm.state[i++], ETMEXTINSELR);
694 ptm_writel(ptm, cpu, ptm.state[i++], ETMTSEVR);
695 ptm_writel(ptm, cpu, ptm.state[i++], ETMAUXCR);
696 ptm_writel(ptm, cpu, ptm.state[i++], ETMVMIDCVR);
697 ptm_writel(ptm, cpu, ptm.state[i++], CS_CLAIMSET);
698 ptm_writel(ptm, cpu, ptm.state[i++], CS_CLAIMCLR);
699
700 ptm_clear_prog(cpu);
701
702 PTM_LOCK(cpu);
703}
704
705/* etm_save_reg_check and etm_restore_reg_check should be fast
706 *
707 * These functions will be called either from:
708 * 1. per_cpu idle thread context for idle power collapses.
709 * 2. per_cpu idle thread context for hotplug/suspend power collapse for
710 * nonboot cpus.
711 * 3. suspend thread context for core0.
712 *
713 * In all cases we are guaranteed to be running on the same cpu for the
714 * entire duration.
715 *
716 * Another assumption is that etm registers won't change after trace_enabled
717 * is set. Current usage model guarantees this doesn't happen.
718 */
719void etm_save_reg_check(void)
720{
721 /* Disabling all kinds of power_collapses when enabling and disabling
722 * trace provides mutual exclusion to be able to safely access
723 * ptm.trace_enabled here.
724 */
725 if (ptm.trace_enabled) {
726 int cpu = smp_processor_id();
727
728 /* Don't save the registers if we just got called from per_cpu
729 * idle thread context of a nonboot cpu after hotplug/suspend
730 * power collapse. This is to prevent corruption due to saving
731 * twice since nonboot cpus start out fresh without the
732 * corresponding restore.
733 */
734 if (!(*per_cpu_ptr(ptm.cpu_restore, cpu))) {
735 ptm_save_reg(cpu);
736 *per_cpu_ptr(ptm.cpu_restore, cpu) = 1;
737 }
738 }
739}
740
741void etm_restore_reg_check(void)
742{
743 /* Disabling all kinds of power_collapses when enabling and disabling
744 * trace provides mutual exclusion to be able to safely access
745 * ptm.trace_enabled here.
746 */
747 if (ptm.trace_enabled) {
748 int cpu = smp_processor_id();
749
750 ptm_restore_reg(cpu);
751 *per_cpu_ptr(ptm.cpu_restore, cpu) = 0;
752 }
753}
754
755static void ptm_cfg_rw_init(void)
756{
757 int i;
758
759 ptm.cfg.main_control = 0x00001000;
760 ptm.cfg.trigger_event = 0x0000406F;
761 ptm.cfg.te_start_stop_control = 0x00000000;
762 ptm.cfg.te_event = 0x0000006F;
763 ptm.cfg.te_control = 0x01000000;
764 ptm.cfg.fifofull_level = 0x00000028;
765 for (i = 0; i < ptm.cfg.nr_addr_comp; i++) {
766 ptm.cfg.addr_comp_value[i] = 0x00000000;
767 ptm.cfg.addr_comp_access_type[i] = 0x00000000;
768 }
769 for (i = 0; i < ptm.cfg.nr_cntr; i++) {
770 ptm.cfg.cntr_reload_value[i] = 0x00000000;
771 ptm.cfg.cntr_enable_event[i] = 0x0000406F;
772 ptm.cfg.cntr_reload_event[i] = 0x0000406F;
773 ptm.cfg.cntr_value[i] = 0x00000000;
774 }
775 ptm.cfg.seq_state_12_event = 0x0000406F;
776 ptm.cfg.seq_state_21_event = 0x0000406F;
777 ptm.cfg.seq_state_23_event = 0x0000406F;
778 ptm.cfg.seq_state_32_event = 0x0000406F;
779 ptm.cfg.seq_state_13_event = 0x0000406F;
780 ptm.cfg.seq_state_31_event = 0x0000406F;
781 ptm.cfg.current_seq_state = 0x00000000;
782 for (i = 0; i < ptm.cfg.nr_ext_output; i++)
783 ptm.cfg.ext_output_event[i] = 0x0000406F;
784 for (i = 0; i < ptm.cfg.nr_context_id_comp; i++)
785 ptm.cfg.context_id_comp_value[i] = 0x00000000;
786 ptm.cfg.context_id_comp_mask = 0x00000000;
787 ptm.cfg.sync_freq = 0x00000080;
788 ptm.cfg.extnd_ext_input_sel = 0x00000000;
789 ptm.cfg.ts_event = 0x0000406F;
790 ptm.cfg.aux_control = 0x00000000;
791 ptm.cfg.vmid_comp_value = 0x00000000;
792}
793
794static void ptm_cfg_ro_init(void)
795{
796 /* use cpu 0 for setup */
797 int cpu = 0;
798
799 ptm_os_unlock(NULL);
800 smp_call_function(ptm_os_unlock, NULL, 1);
801 PTM_UNLOCK(cpu);
802 ptm_clear_powerdown(cpu);
803 ptm_set_prog(cpu);
804
805 /* find all capabilities */
806 ptm.cfg.config_code = ptm_readl(ptm, cpu, ETMCCR);
807 ptm.cfg.nr_addr_comp = BMVAL(ptm.cfg.config_code, 0, 3) * 2;
808 ptm.cfg.nr_cntr = BMVAL(ptm.cfg.config_code, 13, 15);
809 ptm.cfg.nr_ext_input = BMVAL(ptm.cfg.config_code, 17, 19);
810 ptm.cfg.nr_ext_output = BMVAL(ptm.cfg.config_code, 20, 22);
811 ptm.cfg.nr_context_id_comp = BMVAL(ptm.cfg.config_code, 24, 25);
812
813 ptm.cfg.config_code_extn = ptm_readl(ptm, cpu, ETMCCER);
814 ptm.cfg.nr_extnd_ext_input_sel =
815 BMVAL(ptm.cfg.config_code_extn, 0, 2);
816 ptm.cfg.nr_instr_resources = BMVAL(ptm.cfg.config_code_extn, 13, 15);
817
818 ptm.cfg.system_config = ptm_readl(ptm, cpu, ETMSCR);
819 ptm.cfg.fifofull_supported = BVAL(ptm.cfg.system_config, 8);
820 ptm.cfg.nr_procs_supported = BMVAL(ptm.cfg.system_config, 12, 14);
821
822 ptm_set_powerdown(cpu);
823 PTM_LOCK(cpu);
824}
825
826static int __devinit ptm_probe(struct platform_device *pdev)
827{
828 int ret, cpu;
829 struct resource *res;
830
831 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
832 if (!res) {
833 ret = -EINVAL;
834 goto err_res;
835 }
836
837 ptm.base = ioremap_nocache(res->start, resource_size(res));
838 if (!ptm.base) {
839 ret = -EINVAL;
840 goto err_ioremap;
841 }
842
843 ptm.dev = &pdev->dev;
844
845 ptm.state = kzalloc(MAX_STATE_SIZE * sizeof(uint32_t), GFP_KERNEL);
846 if (!ptm.state) {
847 ret = -ENOMEM;
848 goto err_kzalloc;
849 }
850
851 ret = misc_register(&ptm_misc);
852 if (ret)
853 goto err_misc;
854
855 ptm.qdss_at_clk = clk_get(NULL, "qdss_at_clk");
856 if (IS_ERR(ptm.qdss_at_clk)) {
857 ret = PTR_ERR(ptm.qdss_at_clk);
858 goto err_at;
859 }
860 ret = clk_set_rate(ptm.qdss_at_clk, 300000000);
861 if (ret)
862 goto err_at_rate;
863 ret = clk_enable(ptm.qdss_at_clk);
864 if (ret)
865 goto err_at_enable;
866
867 ptm.qdss_pclkdbg_clk = clk_get(NULL, "qdss_pclkdbg_clk");
868 if (IS_ERR(ptm.qdss_pclkdbg_clk)) {
869 ret = PTR_ERR(ptm.qdss_pclkdbg_clk);
870 goto err_pclkdbg;
871 }
872 ret = clk_enable(ptm.qdss_pclkdbg_clk);
873 if (ret)
874 goto err_pclkdbg_enable;
875
876 ptm.qdss_pclk = clk_get(NULL, "qdss_pclk");
877 if (IS_ERR(ptm.qdss_pclk)) {
878 ret = PTR_ERR(ptm.qdss_pclk);
879 goto err_pclk;
880 }
881
882 ret = clk_enable(ptm.qdss_pclk);
883 if (ret)
884 goto err_pclk_enable;
885
886 ptm.qdss_traceclkin_clk = clk_get(NULL, "qdss_traceclkin_clk");
887 if (IS_ERR(ptm.qdss_traceclkin_clk)) {
888 ret = PTR_ERR(ptm.qdss_traceclkin_clk);
889 goto err_traceclkin;
890 }
891 ret = clk_set_rate(ptm.qdss_traceclkin_clk, 300000000);
892 if (ret)
893 goto err_traceclkin_rate;
894 ret = clk_enable(ptm.qdss_traceclkin_clk);
895 if (ret)
896 goto err_traceclkin_enable;
897
898 ptm.qdss_tsctr_clk = clk_get(NULL, "qdss_tsctr_clk");
899 if (IS_ERR(ptm.qdss_tsctr_clk)) {
900 ret = PTR_ERR(ptm.qdss_tsctr_clk);
901 goto err_tsctr;
902 }
903 ret = clk_set_rate(ptm.qdss_tsctr_clk, 400000000);
904 if (ret)
905 goto err_tsctr_rate;
906
907 ret = clk_enable(ptm.qdss_tsctr_clk);
908 if (ret)
909 goto err_tsctr_enable;
910
911 ptm_cfg_ro_init();
912 ptm_cfg_rw_init();
913
914 ptm.trace_enabled = false;
915
916 ptm.cpu_restore = alloc_percpu(int);
917 if (!ptm.cpu_restore) {
918 ret = -ENOMEM;
919 goto err_percpu;
920 }
921
922 for_each_possible_cpu(cpu)
923 *per_cpu_ptr(ptm.cpu_restore, cpu) = 0;
924
925 wake_lock_init(&ptm.wake_lock, WAKE_LOCK_SUSPEND, "msm_ptm");
926 pm_qos_add_request(&ptm.qos_req, PM_QOS_CPU_DMA_LATENCY,
927 PM_QOS_DEFAULT_VALUE);
928 atomic_set(&ptm.in_use, 0);
929
930 clk_disable(ptm.qdss_tsctr_clk);
931 clk_disable(ptm.qdss_traceclkin_clk);
932 clk_disable(ptm.qdss_pclk);
933 clk_disable(ptm.qdss_pclkdbg_clk);
934 clk_disable(ptm.qdss_at_clk);
935
936 dev_info(ptm.dev, "PTM intialized.\n");
937
938 if (trace_on_boot) {
939 if (!ptm_trace_enable())
940 dev_info(ptm.dev, "tracing enabled\n");
941 else
942 dev_err(ptm.dev, "error enabling trace\n");
943 }
944
945 return 0;
946
947err_percpu:
948 clk_disable(ptm.qdss_tsctr_clk);
949err_tsctr_enable:
950err_tsctr_rate:
951 clk_put(ptm.qdss_tsctr_clk);
952err_tsctr:
953 clk_disable(ptm.qdss_traceclkin_clk);
954err_traceclkin_enable:
955err_traceclkin_rate:
956 clk_put(ptm.qdss_traceclkin_clk);
957err_traceclkin:
958 clk_disable(ptm.qdss_pclk);
959err_pclk_enable:
960 clk_put(ptm.qdss_pclk);
961err_pclk:
962 clk_disable(ptm.qdss_pclkdbg_clk);
963err_pclkdbg_enable:
964 clk_put(ptm.qdss_pclkdbg_clk);
965err_pclkdbg:
966 clk_disable(ptm.qdss_at_clk);
967err_at_enable:
968err_at_rate:
969 clk_put(ptm.qdss_at_clk);
970err_at:
971 misc_deregister(&ptm_misc);
972err_misc:
973 kfree(ptm.state);
974err_kzalloc:
975 iounmap(ptm.base);
976err_ioremap:
977err_res:
978 return ret;
979}
980
981static int __devexit ptm_remove(struct platform_device *pdev)
982{
983 if (ptm.trace_enabled)
984 ptm_trace_disable();
985 pm_qos_remove_request(&ptm.qos_req);
986 wake_lock_destroy(&ptm.wake_lock);
987 free_percpu(ptm.cpu_restore);
988 clk_put(ptm.qdss_tsctr_clk);
989 clk_put(ptm.qdss_traceclkin_clk);
990 clk_put(ptm.qdss_pclk);
991 clk_put(ptm.qdss_pclkdbg_clk);
992 clk_put(ptm.qdss_at_clk);
993 misc_deregister(&ptm_misc);
994 kfree(ptm.state);
995 iounmap(ptm.base);
996
997 return 0;
998}
999
1000static struct platform_driver ptm_driver = {
1001 .probe = ptm_probe,
1002 .remove = __devexit_p(ptm_remove),
1003 .driver = {
1004 .name = "msm_ptm",
1005 },
1006};
1007
1008static int __init ptm_init(void)
1009{
1010 return platform_driver_register(&ptm_driver);
1011}
1012module_init(ptm_init);
1013
1014static void __exit ptm_exit(void)
1015{
1016 platform_driver_unregister(&ptm_driver);
1017}
1018module_exit(ptm_exit);
1019
1020MODULE_LICENSE("GPL v2");
1021MODULE_DESCRIPTION("Coresight Program Flow Trace driver");