blob: dbc1c10d1691968a224fa361497a48bed339243d [file] [log] [blame]
Pratik Patel17f3b822011-11-21 12:41:47 -08001/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
Pratik Patel7831c082011-06-08 21:44:37 -07002 *
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>
Pratik Patelcf418622011-09-22 11:15:11 -070015#include <linux/init.h>
16#include <linux/types.h>
17#include <linux/device.h>
Pratik Patel7831c082011-06-08 21:44:37 -070018#include <linux/platform_device.h>
19#include <linux/io.h>
20#include <linux/err.h>
21#include <linux/fs.h>
Pratik Patel7831c082011-06-08 21:44:37 -070022#include <linux/slab.h>
23#include <linux/delay.h>
24#include <linux/smp.h>
Pratik Patel7831c082011-06-08 21:44:37 -070025#include <linux/wakelock.h>
26#include <linux/pm_qos_params.h>
Pratik Patel6630ebe2012-03-06 16:44:22 -080027#include <linux/sysfs.h>
28#include <linux/stat.h>
Pratik Pateld30deda2012-02-01 14:40:55 -080029#include <asm/sections.h>
Pratik Patel7831c082011-06-08 21:44:37 -070030
31#include "qdss.h"
32
Pratik Patel492b3012012-03-06 14:22:30 -080033#define etm_writel(etm, cpu, val, off) \
34 __raw_writel((val), etm.base + (SZ_4K * cpu) + off)
35#define etm_readl(etm, cpu, off) \
36 __raw_readl(etm.base + (SZ_4K * cpu) + off)
Pratik Patel7831c082011-06-08 21:44:37 -070037
38/*
39 * Device registers:
40 * 0x000 - 0x2FC: Trace registers
41 * 0x300 - 0x314: Management registers
42 * 0x318 - 0xEFC: Trace registers
43 *
44 * Coresight registers
45 * 0xF00 - 0xF9C: Management registers
46 * 0xFA0 - 0xFA4: Management registers in PFTv1.0
47 * Trace registers in PFTv1.1
48 * 0xFA8 - 0xFFC: Management registers
49 */
50
51/* Trace registers (0x000-0x2FC) */
52#define ETMCR (0x000)
53#define ETMCCR (0x004)
54#define ETMTRIGGER (0x008)
55#define ETMSR (0x010)
56#define ETMSCR (0x014)
57#define ETMTSSCR (0x018)
58#define ETMTEEVR (0x020)
59#define ETMTECR1 (0x024)
60#define ETMFFLR (0x02C)
61#define ETMACVRn(n) (0x040 + (n * 4))
62#define ETMACTRn(n) (0x080 + (n * 4))
63#define ETMCNTRLDVRn(n) (0x140 + (n * 4))
64#define ETMCNTENRn(n) (0x150 + (n * 4))
65#define ETMCNTRLDEVRn(n) (0x160 + (n * 4))
66#define ETMCNTVRn(n) (0x170 + (n * 4))
67#define ETMSQ12EVR (0x180)
68#define ETMSQ21EVR (0x184)
69#define ETMSQ23EVR (0x188)
Pratik Pateld5bbc762012-01-29 14:13:21 -080070#define ETMSQ31EVR (0x18C)
71#define ETMSQ32EVR (0x190)
72#define ETMSQ13EVR (0x194)
Pratik Patel7831c082011-06-08 21:44:37 -070073#define ETMSQR (0x19C)
74#define ETMEXTOUTEVRn(n) (0x1A0 + (n * 4))
75#define ETMCIDCVRn(n) (0x1B0 + (n * 4))
76#define ETMCIDCMR (0x1BC)
77#define ETMIMPSPEC0 (0x1C0)
78#define ETMIMPSPEC1 (0x1C4)
79#define ETMIMPSPEC2 (0x1C8)
80#define ETMIMPSPEC3 (0x1CC)
81#define ETMIMPSPEC4 (0x1D0)
82#define ETMIMPSPEC5 (0x1D4)
83#define ETMIMPSPEC6 (0x1D8)
84#define ETMIMPSPEC7 (0x1DC)
85#define ETMSYNCFR (0x1E0)
86#define ETMIDR (0x1E4)
87#define ETMCCER (0x1E8)
88#define ETMEXTINSELR (0x1EC)
89#define ETMTESSEICR (0x1F0)
90#define ETMEIBCR (0x1F4)
91#define ETMTSEVR (0x1F8)
92#define ETMAUXCR (0x1FC)
93#define ETMTRACEIDR (0x200)
Pratik Pateld5bbc762012-01-29 14:13:21 -080094#define ETMVMIDCVR (0x240)
Pratik Patel7831c082011-06-08 21:44:37 -070095/* Management registers (0x300-0x314) */
96#define ETMOSLAR (0x300)
97#define ETMOSLSR (0x304)
98#define ETMOSSRR (0x308)
99#define ETMPDCR (0x310)
100#define ETMPDSR (0x314)
101
Pratik Patel61de7302012-03-07 12:06:10 -0800102#define ETM_MAX_ADDR_CMP (16)
103#define ETM_MAX_CNTR (4)
104#define ETM_MAX_CTXID_CMP (3)
105
Pratik Patel6630ebe2012-03-06 16:44:22 -0800106#define ETM_MODE_EXCLUDE BIT(0)
107#define ETM_MODE_CYCACC BIT(1)
108#define ETM_MODE_STALL BIT(2)
109#define ETM_MODE_TIMESTAMP BIT(3)
110#define ETM_MODE_CTXID BIT(4)
111#define ETM_MODE_ALL (0x1F)
112
113#define ETM_EVENT_MASK (0x1FFFF)
114#define ETM_SYNC_MASK (0xFFF)
115#define ETM_ALL_MASK (0xFFFFFFFF)
116
117#define ETM_SEQ_STATE_MAX_VAL (0x2)
118
119enum {
120 ETM_ADDR_TYPE_NONE,
121 ETM_ADDR_TYPE_SINGLE,
122 ETM_ADDR_TYPE_RANGE,
123 ETM_ADDR_TYPE_START,
124 ETM_ADDR_TYPE_STOP,
125};
126
Pratik Patel492b3012012-03-06 14:22:30 -0800127#define ETM_LOCK(cpu) \
Pratik Patel7831c082011-06-08 21:44:37 -0700128do { \
129 mb(); \
Pratik Patel492b3012012-03-06 14:22:30 -0800130 etm_writel(etm, cpu, 0x0, CS_LAR); \
Pratik Patel7831c082011-06-08 21:44:37 -0700131} while (0)
Pratik Patel492b3012012-03-06 14:22:30 -0800132#define ETM_UNLOCK(cpu) \
Pratik Patel7831c082011-06-08 21:44:37 -0700133do { \
Pratik Patel492b3012012-03-06 14:22:30 -0800134 etm_writel(etm, cpu, CS_UNLOCK_MAGIC, CS_LAR); \
Pratik Patel7831c082011-06-08 21:44:37 -0700135 mb(); \
136} while (0)
137
Pratik Patel7831c082011-06-08 21:44:37 -0700138
Pratik Patel6630ebe2012-03-06 16:44:22 -0800139#ifdef MODULE_PARAM_PREFIX
140#undef MODULE_PARAM_PREFIX
141#endif
142#define MODULE_PARAM_PREFIX "qdss."
143
Pratik Patel29cba152012-01-03 11:40:26 -0800144#ifdef CONFIG_MSM_QDSS_ETM_DEFAULT_ENABLE
Pratik Patel61de7302012-03-07 12:06:10 -0800145static int etm_boot_enable = 1;
Pratik Patel29cba152012-01-03 11:40:26 -0800146#else
Pratik Patel61de7302012-03-07 12:06:10 -0800147static int etm_boot_enable;
Pratik Patel29cba152012-01-03 11:40:26 -0800148#endif
Pratik Patel7831c082011-06-08 21:44:37 -0700149module_param_named(
Pratik Patel61de7302012-03-07 12:06:10 -0800150 etm_boot_enable, etm_boot_enable, int, S_IRUGO
Pratik Patel7831c082011-06-08 21:44:37 -0700151);
152
Pratik Patel492b3012012-03-06 14:22:30 -0800153struct etm_ctx {
Pratik Patel7831c082011-06-08 21:44:37 -0700154 void __iomem *base;
Pratik Patel61de7302012-03-07 12:06:10 -0800155 bool enabled;
Pratik Patel7831c082011-06-08 21:44:37 -0700156 struct wake_lock wake_lock;
157 struct pm_qos_request_list qos_req;
Pratik Patel6630ebe2012-03-06 16:44:22 -0800158 struct mutex mutex;
Pratik Patel7831c082011-06-08 21:44:37 -0700159 struct device *dev;
Pratik Patel6630ebe2012-03-06 16:44:22 -0800160 struct kobject *kobj;
Pratik Patel61de7302012-03-07 12:06:10 -0800161 uint8_t arch;
162 uint8_t nr_addr_cmp;
163 uint8_t nr_cntr;
164 uint8_t nr_ext_inp;
165 uint8_t nr_ext_out;
166 uint8_t nr_ctxid_cmp;
Pratik Pateld30deda2012-02-01 14:40:55 -0800167 uint8_t reset;
Pratik Patel6630ebe2012-03-06 16:44:22 -0800168 uint32_t mode;
Pratik Patel61de7302012-03-07 12:06:10 -0800169 uint32_t ctrl;
170 uint32_t trigger_event;
171 uint32_t startstop_ctrl;
172 uint32_t enable_event;
173 uint32_t enable_ctrl1;
174 uint32_t fifofull_level;
Pratik Patel6630ebe2012-03-06 16:44:22 -0800175 uint8_t addr_idx;
Pratik Patel61de7302012-03-07 12:06:10 -0800176 uint32_t addr_val[ETM_MAX_ADDR_CMP];
177 uint32_t addr_acctype[ETM_MAX_ADDR_CMP];
Pratik Patel6630ebe2012-03-06 16:44:22 -0800178 uint32_t addr_type[ETM_MAX_ADDR_CMP];
179 uint8_t cntr_idx;
Pratik Patel61de7302012-03-07 12:06:10 -0800180 uint32_t cntr_rld_val[ETM_MAX_CNTR];
181 uint32_t cntr_event[ETM_MAX_CNTR];
182 uint32_t cntr_rld_event[ETM_MAX_CNTR];
183 uint32_t cntr_val[ETM_MAX_CNTR];
184 uint32_t seq_12_event;
185 uint32_t seq_21_event;
186 uint32_t seq_23_event;
187 uint32_t seq_31_event;
188 uint32_t seq_32_event;
189 uint32_t seq_13_event;
190 uint32_t seq_curr_state;
Pratik Patel6630ebe2012-03-06 16:44:22 -0800191 uint8_t ctxid_idx;
Pratik Patel61de7302012-03-07 12:06:10 -0800192 uint32_t ctxid_val[ETM_MAX_CTXID_CMP];
193 uint32_t ctxid_mask;
194 uint32_t sync_freq;
195 uint32_t timestamp_event;
Pratik Patel7831c082011-06-08 21:44:37 -0700196};
197
Pratik Patel61de7302012-03-07 12:06:10 -0800198static struct etm_ctx etm = {
Pratik Pateld30deda2012-02-01 14:40:55 -0800199 .mode = 0x2,
Pratik Patel61de7302012-03-07 12:06:10 -0800200 .ctrl = 0x1000,
201 .trigger_event = 0x406F,
202 .enable_event = 0x6F,
Pratik Pateld30deda2012-02-01 14:40:55 -0800203 .enable_ctrl1 = 0x1,
Pratik Patel61de7302012-03-07 12:06:10 -0800204 .fifofull_level = 0x28,
Pratik Pateld30deda2012-02-01 14:40:55 -0800205 .addr_val = {(uint32_t) _stext, (uint32_t) _etext},
206 .addr_type = {ETM_ADDR_TYPE_RANGE, ETM_ADDR_TYPE_RANGE},
Pratik Patel61de7302012-03-07 12:06:10 -0800207 .cntr_event = {[0 ... (ETM_MAX_CNTR - 1)] = 0x406F},
208 .cntr_rld_event = {[0 ... (ETM_MAX_CNTR - 1)] = 0x406F},
209 .seq_12_event = 0x406F,
210 .seq_21_event = 0x406F,
211 .seq_23_event = 0x406F,
212 .seq_31_event = 0x406F,
213 .seq_32_event = 0x406F,
214 .seq_13_event = 0x406F,
215 .sync_freq = 0x80,
216 .timestamp_event = 0x406F,
217};
Pratik Patel7831c082011-06-08 21:44:37 -0700218
Pratik Patel7831c082011-06-08 21:44:37 -0700219
Pratik Patel17f3b822011-11-21 12:41:47 -0800220/* ETM clock is derived from the processor clock and gets enabled on a
221 * logical OR of below items on Krait (pass2 onwards):
222 * 1.CPMR[ETMCLKEN] is 1
223 * 2.ETMCR[PD] is 0
224 * 3.ETMPDCR[PU] is 1
225 * 4.Reset is asserted (core or debug)
226 * 5.APB memory mapped requests (eg. EDAP access)
227 *
228 * 1., 2. and 3. above are permanent enables whereas 4. and 5. are temporary
229 * enables
230 *
231 * We rely on 5. to be able to access ETMCR and then use 2. above for ETM
232 * clock vote in the driver and the save-restore code uses 1. above
233 * for its vote
234 */
Pratik Patel61de7302012-03-07 12:06:10 -0800235static void etm_set_pwrdwn(int cpu)
Pratik Patel7831c082011-06-08 21:44:37 -0700236{
237 uint32_t etmcr;
238
Pratik Patel492b3012012-03-06 14:22:30 -0800239 etmcr = etm_readl(etm, cpu, ETMCR);
Pratik Patel7831c082011-06-08 21:44:37 -0700240 etmcr |= BIT(0);
Pratik Patel492b3012012-03-06 14:22:30 -0800241 etm_writel(etm, cpu, etmcr, ETMCR);
Pratik Patel7831c082011-06-08 21:44:37 -0700242}
243
Pratik Patel61de7302012-03-07 12:06:10 -0800244static void etm_clr_pwrdwn(int cpu)
Pratik Patel7831c082011-06-08 21:44:37 -0700245{
246 uint32_t etmcr;
247
Pratik Patel492b3012012-03-06 14:22:30 -0800248 etmcr = etm_readl(etm, cpu, ETMCR);
Pratik Patel7831c082011-06-08 21:44:37 -0700249 etmcr &= ~BIT(0);
Pratik Patel492b3012012-03-06 14:22:30 -0800250 etm_writel(etm, cpu, etmcr, ETMCR);
Pratik Patel7831c082011-06-08 21:44:37 -0700251}
252
Pratik Patel492b3012012-03-06 14:22:30 -0800253static void etm_set_prog(int cpu)
Pratik Patel7831c082011-06-08 21:44:37 -0700254{
255 uint32_t etmcr;
256 int count;
257
Pratik Patel492b3012012-03-06 14:22:30 -0800258 etmcr = etm_readl(etm, cpu, ETMCR);
Pratik Patel7831c082011-06-08 21:44:37 -0700259 etmcr |= BIT(10);
Pratik Patel492b3012012-03-06 14:22:30 -0800260 etm_writel(etm, cpu, etmcr, ETMCR);
Pratik Patel7831c082011-06-08 21:44:37 -0700261
Pratik Patel492b3012012-03-06 14:22:30 -0800262 for (count = TIMEOUT_US; BVAL(etm_readl(etm, cpu, ETMSR), 1) != 1
Pratik Patel7831c082011-06-08 21:44:37 -0700263 && count > 0; count--)
264 udelay(1);
Pratik Patel61de7302012-03-07 12:06:10 -0800265 WARN(count == 0, "timeout while setting prog bit, ETMSR: %#x\n",
266 etm_readl(etm, cpu, ETMSR));
Pratik Patel7831c082011-06-08 21:44:37 -0700267}
268
Pratik Patel61de7302012-03-07 12:06:10 -0800269static void etm_clr_prog(int cpu)
Pratik Patel7831c082011-06-08 21:44:37 -0700270{
271 uint32_t etmcr;
272 int count;
273
Pratik Patel492b3012012-03-06 14:22:30 -0800274 etmcr = etm_readl(etm, cpu, ETMCR);
Pratik Patel7831c082011-06-08 21:44:37 -0700275 etmcr &= ~BIT(10);
Pratik Patel492b3012012-03-06 14:22:30 -0800276 etm_writel(etm, cpu, etmcr, ETMCR);
Pratik Patel7831c082011-06-08 21:44:37 -0700277
Pratik Patel492b3012012-03-06 14:22:30 -0800278 for (count = TIMEOUT_US; BVAL(etm_readl(etm, cpu, ETMSR), 1) != 0
Pratik Patel7831c082011-06-08 21:44:37 -0700279 && count > 0; count--)
280 udelay(1);
Pratik Patel61de7302012-03-07 12:06:10 -0800281 WARN(count == 0, "timeout while clearing prog bit, ETMSR: %#x\n",
282 etm_readl(etm, cpu, ETMSR));
Pratik Patel7831c082011-06-08 21:44:37 -0700283}
284
Pratik Patel61de7302012-03-07 12:06:10 -0800285static void __etm_enable(int cpu)
Pratik Patel7831c082011-06-08 21:44:37 -0700286{
Pratik Patel17f3b822011-11-21 12:41:47 -0800287 int i;
Pratik Patel7831c082011-06-08 21:44:37 -0700288
Pratik Patel492b3012012-03-06 14:22:30 -0800289 ETM_UNLOCK(cpu);
Pratik Patel17f3b822011-11-21 12:41:47 -0800290 /* Vote for ETM power/clock enable */
Pratik Patel61de7302012-03-07 12:06:10 -0800291 etm_clr_pwrdwn(cpu);
Pratik Patel492b3012012-03-06 14:22:30 -0800292 etm_set_prog(cpu);
Pratik Patel7831c082011-06-08 21:44:37 -0700293
Pratik Patel61de7302012-03-07 12:06:10 -0800294 etm_writel(etm, cpu, etm.ctrl | BIT(10), ETMCR);
295 etm_writel(etm, cpu, etm.trigger_event, ETMTRIGGER);
296 etm_writel(etm, cpu, etm.startstop_ctrl, ETMTSSCR);
297 etm_writel(etm, cpu, etm.enable_event, ETMTEEVR);
298 etm_writel(etm, cpu, etm.enable_ctrl1, ETMTECR1);
299 etm_writel(etm, cpu, etm.fifofull_level, ETMFFLR);
300 for (i = 0; i < etm.nr_addr_cmp; i++) {
301 etm_writel(etm, cpu, etm.addr_val[i], ETMACVRn(i));
302 etm_writel(etm, cpu, etm.addr_acctype[i], ETMACTRn(i));
Pratik Patel7831c082011-06-08 21:44:37 -0700303 }
Pratik Patel61de7302012-03-07 12:06:10 -0800304 for (i = 0; i < etm.nr_cntr; i++) {
305 etm_writel(etm, cpu, etm.cntr_rld_val[i], ETMCNTRLDVRn(i));
306 etm_writel(etm, cpu, etm.cntr_event[i], ETMCNTENRn(i));
307 etm_writel(etm, cpu, etm.cntr_rld_event[i], ETMCNTRLDEVRn(i));
308 etm_writel(etm, cpu, etm.cntr_val[i], ETMCNTVRn(i));
Pratik Patel17f3b822011-11-21 12:41:47 -0800309 }
Pratik Patel61de7302012-03-07 12:06:10 -0800310 etm_writel(etm, cpu, etm.seq_12_event, ETMSQ12EVR);
311 etm_writel(etm, cpu, etm.seq_21_event, ETMSQ21EVR);
312 etm_writel(etm, cpu, etm.seq_23_event, ETMSQ23EVR);
313 etm_writel(etm, cpu, etm.seq_31_event, ETMSQ31EVR);
314 etm_writel(etm, cpu, etm.seq_32_event, ETMSQ32EVR);
315 etm_writel(etm, cpu, etm.seq_13_event, ETMSQ13EVR);
316 etm_writel(etm, cpu, etm.seq_curr_state, ETMSQR);
317 for (i = 0; i < etm.nr_ext_out; i++)
318 etm_writel(etm, cpu, 0x0000406F, ETMEXTOUTEVRn(i));
319 for (i = 0; i < etm.nr_ctxid_cmp; i++)
320 etm_writel(etm, cpu, etm.ctxid_val[i], ETMCIDCVRn(i));
321 etm_writel(etm, cpu, etm.ctxid_mask, ETMCIDCMR);
322 etm_writel(etm, cpu, etm.sync_freq, ETMSYNCFR);
323 etm_writel(etm, cpu, 0x00000000, ETMEXTINSELR);
324 etm_writel(etm, cpu, etm.timestamp_event, ETMTSEVR);
325 etm_writel(etm, cpu, 0x00000000, ETMAUXCR);
Pratik Patel492b3012012-03-06 14:22:30 -0800326 etm_writel(etm, cpu, cpu+1, ETMTRACEIDR);
Pratik Patel61de7302012-03-07 12:06:10 -0800327 etm_writel(etm, cpu, 0x00000000, ETMVMIDCVR);
Pratik Patel17f3b822011-11-21 12:41:47 -0800328
Pratik Patel61de7302012-03-07 12:06:10 -0800329 etm_clr_prog(cpu);
Pratik Patel492b3012012-03-06 14:22:30 -0800330 ETM_LOCK(cpu);
Pratik Patel7831c082011-06-08 21:44:37 -0700331}
332
Pratik Patel61de7302012-03-07 12:06:10 -0800333static int etm_enable(void)
Pratik Patel7831c082011-06-08 21:44:37 -0700334{
Pratik Patel17f3b822011-11-21 12:41:47 -0800335 int ret, cpu;
Pratik Patel7831c082011-06-08 21:44:37 -0700336
Pratik Patel61de7302012-03-07 12:06:10 -0800337 if (etm.enabled) {
338 dev_err(etm.dev, "ETM tracing already enabled\n");
339 ret = -EPERM;
340 goto err;
341 }
342
Pratik Patelcc320a42011-12-22 10:48:14 -0800343 ret = qdss_clk_enable();
Pratik Patel7831c082011-06-08 21:44:37 -0700344 if (ret)
Pratik Patel61de7302012-03-07 12:06:10 -0800345 goto err;
Pratik Patel7831c082011-06-08 21:44:37 -0700346
Pratik Patel492b3012012-03-06 14:22:30 -0800347 wake_lock(&etm.wake_lock);
Pratik Patele5771792011-09-17 18:33:54 -0700348 /* 1. causes all online cpus to come out of idle PC
Pratik Patel7831c082011-06-08 21:44:37 -0700349 * 2. prevents idle PC until save restore flag is enabled atomically
Pratik Patele5771792011-09-17 18:33:54 -0700350 *
351 * we rely on the user to prevent hotplug on/off racing with this
352 * operation and to ensure cores where trace is expected to be turned
353 * on are already hotplugged on
Pratik Patel7831c082011-06-08 21:44:37 -0700354 */
Pratik Patel492b3012012-03-06 14:22:30 -0800355 pm_qos_update_request(&etm.qos_req, 0);
Pratik Patel7831c082011-06-08 21:44:37 -0700356
357 etb_disable();
358 tpiu_disable();
359 /* enable ETB first to avoid loosing any trace data */
360 etb_enable();
361 funnel_enable(0x0, 0x3);
Pratik Patel17f3b822011-11-21 12:41:47 -0800362 for_each_online_cpu(cpu)
Pratik Patel61de7302012-03-07 12:06:10 -0800363 __etm_enable(cpu);
Pratik Patel7831c082011-06-08 21:44:37 -0700364
Pratik Patel61de7302012-03-07 12:06:10 -0800365 etm.enabled = true;
Pratik Patel7831c082011-06-08 21:44:37 -0700366
Pratik Patel492b3012012-03-06 14:22:30 -0800367 pm_qos_update_request(&etm.qos_req, PM_QOS_DEFAULT_VALUE);
368 wake_unlock(&etm.wake_lock);
Pratik Patel7831c082011-06-08 21:44:37 -0700369
Pratik Patel61de7302012-03-07 12:06:10 -0800370 dev_info(etm.dev, "ETM tracing enabled\n");
Pratik Patel7831c082011-06-08 21:44:37 -0700371 return 0;
Pratik Patel61de7302012-03-07 12:06:10 -0800372err:
373 return ret;
Pratik Patel7831c082011-06-08 21:44:37 -0700374}
375
Pratik Patel61de7302012-03-07 12:06:10 -0800376static void __etm_disable(int cpu)
Pratik Patel7831c082011-06-08 21:44:37 -0700377{
Pratik Patel492b3012012-03-06 14:22:30 -0800378 ETM_UNLOCK(cpu);
379 etm_set_prog(cpu);
Pratik Patel7831c082011-06-08 21:44:37 -0700380
Pratik Patel17f3b822011-11-21 12:41:47 -0800381 /* program trace enable to low by using always false event */
Pratik Patel492b3012012-03-06 14:22:30 -0800382 etm_writel(etm, cpu, 0x6F | BIT(14), ETMTEEVR);
Pratik Patel7831c082011-06-08 21:44:37 -0700383
Pratik Patel17f3b822011-11-21 12:41:47 -0800384 /* Vote for ETM power/clock disable */
Pratik Patel61de7302012-03-07 12:06:10 -0800385 etm_set_pwrdwn(cpu);
Pratik Patel492b3012012-03-06 14:22:30 -0800386 ETM_LOCK(cpu);
Pratik Patel7831c082011-06-08 21:44:37 -0700387}
388
Pratik Patel61de7302012-03-07 12:06:10 -0800389static int etm_disable(void)
Pratik Patel7831c082011-06-08 21:44:37 -0700390{
Pratik Patel61de7302012-03-07 12:06:10 -0800391 int ret, cpu;
392
393 if (!etm.enabled) {
394 dev_err(etm.dev, "ETM tracing already disabled\n");
395 ret = -EPERM;
396 goto err;
397 }
Pratik Patel17f3b822011-11-21 12:41:47 -0800398
Pratik Patel492b3012012-03-06 14:22:30 -0800399 wake_lock(&etm.wake_lock);
Pratik Patele5771792011-09-17 18:33:54 -0700400 /* 1. causes all online cpus to come out of idle PC
Pratik Patel7831c082011-06-08 21:44:37 -0700401 * 2. prevents idle PC until save restore flag is disabled atomically
Pratik Patele5771792011-09-17 18:33:54 -0700402 *
403 * we rely on the user to prevent hotplug on/off racing with this
404 * operation and to ensure cores where trace is expected to be turned
405 * off are already hotplugged on
Pratik Patel7831c082011-06-08 21:44:37 -0700406 */
Pratik Patel492b3012012-03-06 14:22:30 -0800407 pm_qos_update_request(&etm.qos_req, 0);
Pratik Patel7831c082011-06-08 21:44:37 -0700408
Pratik Patel17f3b822011-11-21 12:41:47 -0800409 for_each_online_cpu(cpu)
Pratik Patel61de7302012-03-07 12:06:10 -0800410 __etm_disable(cpu);
Pratik Patel7831c082011-06-08 21:44:37 -0700411 etb_dump();
412 etb_disable();
413 funnel_disable(0x0, 0x3);
414
Pratik Patel61de7302012-03-07 12:06:10 -0800415 etm.enabled = false;
Pratik Patel7831c082011-06-08 21:44:37 -0700416
Pratik Patel492b3012012-03-06 14:22:30 -0800417 pm_qos_update_request(&etm.qos_req, PM_QOS_DEFAULT_VALUE);
418 wake_unlock(&etm.wake_lock);
Pratik Patel7831c082011-06-08 21:44:37 -0700419
Pratik Patelcc320a42011-12-22 10:48:14 -0800420 qdss_clk_disable();
Pratik Patel61de7302012-03-07 12:06:10 -0800421
422 dev_info(etm.dev, "ETM tracing disabled\n");
423 return 0;
424err:
425 return ret;
Pratik Patel7831c082011-06-08 21:44:37 -0700426}
427
Pratik Patel17f3b822011-11-21 12:41:47 -0800428/* Memory mapped writes to clear os lock not supported */
Pratik Patel492b3012012-03-06 14:22:30 -0800429static void etm_os_unlock(void *unused)
Pratik Patel17f3b822011-11-21 12:41:47 -0800430{
431 unsigned long value = 0x0;
432
433 asm("mcr p14, 1, %0, c1, c0, 4\n\t" : : "r" (value));
434 asm("isb\n\t");
435}
436
Pratik Patel6630ebe2012-03-06 16:44:22 -0800437#define ETM_STORE(__name, mask) \
438static ssize_t __name##_store(struct kobject *kobj, \
439 struct kobj_attribute *attr, \
440 const char *buf, size_t n) \
441{ \
442 unsigned long val; \
443 \
444 if (sscanf(buf, "%lx", &val) != 1) \
445 return -EINVAL; \
446 \
447 etm.__name = val & mask; \
448 return n; \
449}
450
451#define ETM_SHOW(__name) \
452static ssize_t __name##_show(struct kobject *kobj, \
453 struct kobj_attribute *attr, \
454 char *buf) \
455{ \
456 unsigned long val = etm.__name; \
457 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val); \
458}
459
460#define ETM_ATTR(__name) \
461static struct kobj_attribute __name##_attr = \
462 __ATTR(__name, S_IRUGO | S_IWUSR, __name##_show, __name##_store)
463#define ETM_ATTR_RO(__name) \
464static struct kobj_attribute __name##_attr = \
465 __ATTR(__name, S_IRUGO, __name##_show, NULL)
466
467static ssize_t enabled_store(struct kobject *kobj,
468 struct kobj_attribute *attr,
469 const char *buf, size_t n)
470{
471 int ret = 0;
472 unsigned long val;
473
474 if (sscanf(buf, "%lx", &val) != 1)
475 return -EINVAL;
476
477 mutex_lock(&etm.mutex);
478 if (val)
479 ret = etm_enable();
480 else
481 ret = etm_disable();
482 mutex_unlock(&etm.mutex);
483
484 if (ret)
485 return ret;
486 return n;
487}
488ETM_SHOW(enabled);
489ETM_ATTR(enabled);
490
491ETM_SHOW(nr_addr_cmp);
492ETM_ATTR_RO(nr_addr_cmp);
493ETM_SHOW(nr_cntr);
494ETM_ATTR_RO(nr_cntr);
495ETM_SHOW(nr_ctxid_cmp);
496ETM_ATTR_RO(nr_ctxid_cmp);
497
Pratik Pateld30deda2012-02-01 14:40:55 -0800498/* Reset to trace everything i.e. exclude nothing. */
499static ssize_t reset_store(struct kobject *kobj,
500 struct kobj_attribute *attr,
501 const char *buf, size_t n)
502{
503 int i;
504 unsigned long val;
505
506 if (sscanf(buf, "%lx", &val) != 1)
507 return -EINVAL;
508
509 mutex_lock(&etm.mutex);
510 if (val) {
511 etm.mode = 0x3;
512 etm.ctrl = 0x1000;
513 etm.trigger_event = 0x406F;
514 etm.startstop_ctrl = 0x0;
515 etm.enable_event = 0x6F;
516 etm.enable_ctrl1 = 0x1000000;
517 etm.fifofull_level = 0x28;
518 etm.addr_idx = 0x0;
519 for (i = 0; i < etm.nr_addr_cmp; i++) {
520 etm.addr_val[i] = 0x0;
521 etm.addr_acctype[i] = 0x0;
522 etm.addr_type[i] = ETM_ADDR_TYPE_NONE;
523 }
524 etm.cntr_idx = 0x0;
525 for (i = 0; i < etm.nr_cntr; i++) {
526 etm.cntr_rld_val[i] = 0x0;
527 etm.cntr_event[i] = 0x406F;
528 etm.cntr_rld_event[i] = 0x406F;
529 etm.cntr_val[i] = 0x0;
530 }
531 etm.seq_12_event = 0x406F;
532 etm.seq_21_event = 0x406F;
533 etm.seq_23_event = 0x406F;
534 etm.seq_31_event = 0x406F;
535 etm.seq_32_event = 0x406F;
536 etm.seq_13_event = 0x406F;
537 etm.seq_curr_state = 0x0;
538 etm.ctxid_idx = 0x0;
539 for (i = 0; i < etm.nr_ctxid_cmp; i++)
540 etm.ctxid_val[i] = 0x0;
541 etm.ctxid_mask = 0x0;
542 etm.sync_freq = 0x80;
543 etm.timestamp_event = 0x406F;
544 }
545 mutex_unlock(&etm.mutex);
546 return n;
547}
548ETM_SHOW(reset);
549ETM_ATTR(reset);
550
Pratik Patel6630ebe2012-03-06 16:44:22 -0800551static ssize_t mode_store(struct kobject *kobj,
552 struct kobj_attribute *attr,
553 const char *buf, size_t n)
554{
555 unsigned long val;
556
557 if (sscanf(buf, "%lx", &val) != 1)
558 return -EINVAL;
559
560 mutex_lock(&etm.mutex);
561 etm.mode = val & ETM_MODE_ALL;
562
563 if (etm.mode & ETM_MODE_EXCLUDE)
564 etm.enable_ctrl1 |= BIT(24);
565 else
566 etm.enable_ctrl1 &= ~BIT(24);
567
568 if (etm.mode & ETM_MODE_CYCACC)
569 etm.ctrl |= BIT(12);
570 else
571 etm.ctrl &= ~BIT(12);
572
573 if (etm.mode & ETM_MODE_STALL)
574 etm.ctrl |= BIT(7);
575 else
576 etm.ctrl &= ~BIT(7);
577
578 if (etm.mode & ETM_MODE_TIMESTAMP)
579 etm.ctrl |= BIT(28);
580 else
581 etm.ctrl &= ~BIT(28);
582 if (etm.mode & ETM_MODE_CTXID)
583 etm.ctrl |= (BIT(14) | BIT(15));
584 else
585 etm.ctrl &= ~(BIT(14) | BIT(15));
586 mutex_unlock(&etm.mutex);
587
588 return n;
589}
590ETM_SHOW(mode);
591ETM_ATTR(mode);
592
593ETM_STORE(trigger_event, ETM_EVENT_MASK);
594ETM_SHOW(trigger_event);
595ETM_ATTR(trigger_event);
596
597ETM_STORE(enable_event, ETM_EVENT_MASK);
598ETM_SHOW(enable_event);
599ETM_ATTR(enable_event);
600
601ETM_STORE(fifofull_level, ETM_ALL_MASK);
602ETM_SHOW(fifofull_level);
603ETM_ATTR(fifofull_level);
604
605static ssize_t addr_idx_store(struct kobject *kobj,
606 struct kobj_attribute *attr,
607 const char *buf, size_t n)
608{
609 unsigned long val;
610
611 if (sscanf(buf, "%lx", &val) != 1)
612 return -EINVAL;
613 if (val >= etm.nr_addr_cmp)
614 return -EINVAL;
615
616 /* Use mutex to ensure index doesn't change while it gets dereferenced
617 * multiple times within a mutex block elsewhere.
618 */
619 mutex_lock(&etm.mutex);
620 etm.addr_idx = val;
621 mutex_unlock(&etm.mutex);
622 return n;
623}
624ETM_SHOW(addr_idx);
625ETM_ATTR(addr_idx);
626
Pratik Patel6630ebe2012-03-06 16:44:22 -0800627static ssize_t addr_single_store(struct kobject *kobj,
628 struct kobj_attribute *attr,
629 const char *buf, size_t n)
630{
631 unsigned long val;
632 uint8_t idx;
633
634 if (sscanf(buf, "%lx", &val) != 1)
635 return -EINVAL;
636
637 mutex_lock(&etm.mutex);
638 idx = etm.addr_idx;
639 if (!(etm.addr_type[idx] == ETM_ADDR_TYPE_NONE ||
640 etm.addr_type[idx] == ETM_ADDR_TYPE_SINGLE)) {
641 mutex_unlock(&etm.mutex);
642 return -EPERM;
643 }
644
645 etm.addr_val[idx] = val;
646 etm.addr_type[idx] = ETM_ADDR_TYPE_SINGLE;
Pratik Patel6630ebe2012-03-06 16:44:22 -0800647 mutex_unlock(&etm.mutex);
648 return n;
649}
650static ssize_t addr_single_show(struct kobject *kobj,
651 struct kobj_attribute *attr,
652 char *buf)
653{
654 unsigned long val;
655 uint8_t idx;
656
657 mutex_lock(&etm.mutex);
658 idx = etm.addr_idx;
659 if (!(etm.addr_type[idx] == ETM_ADDR_TYPE_NONE ||
660 etm.addr_type[idx] == ETM_ADDR_TYPE_SINGLE)) {
661 mutex_unlock(&etm.mutex);
662 return -EPERM;
663 }
664
665 val = etm.addr_val[idx];
666 mutex_unlock(&etm.mutex);
667 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
668}
669ETM_ATTR(addr_single);
670
671static ssize_t addr_range_store(struct kobject *kobj,
672 struct kobj_attribute *attr,
673 const char *buf, size_t n)
674{
675 unsigned long val1, val2;
676 uint8_t idx;
677
678 if (sscanf(buf, "%lx %lx", &val1, &val2) != 2)
679 return -EINVAL;
680 /* lower address comparator cannot have a higher address value */
681 if (val1 > val2)
682 return -EINVAL;
683
684 mutex_lock(&etm.mutex);
685 idx = etm.addr_idx;
686 if (idx % 2 != 0) {
687 mutex_unlock(&etm.mutex);
688 return -EPERM;
689 }
690 if (!((etm.addr_type[idx] == ETM_ADDR_TYPE_NONE &&
691 etm.addr_type[idx + 1] == ETM_ADDR_TYPE_NONE) ||
692 (etm.addr_type[idx] == ETM_ADDR_TYPE_RANGE &&
693 etm.addr_type[idx + 1] == ETM_ADDR_TYPE_RANGE))) {
694 mutex_unlock(&etm.mutex);
695 return -EPERM;
696 }
697
698 etm.addr_val[idx] = val1;
699 etm.addr_type[idx] = ETM_ADDR_TYPE_RANGE;
700 etm.addr_val[idx + 1] = val2;
701 etm.addr_type[idx + 1] = ETM_ADDR_TYPE_RANGE;
702 etm.enable_ctrl1 |= (1 << (idx/2));
Pratik Patel6630ebe2012-03-06 16:44:22 -0800703 mutex_unlock(&etm.mutex);
704 return n;
705}
706static ssize_t addr_range_show(struct kobject *kobj,
707 struct kobj_attribute *attr,
708 char *buf)
709{
710 unsigned long val1, val2;
711 uint8_t idx;
712
713 mutex_lock(&etm.mutex);
714 idx = etm.addr_idx;
715 if (idx % 2 != 0) {
716 mutex_unlock(&etm.mutex);
717 return -EPERM;
718 }
719 if (!((etm.addr_type[idx] == ETM_ADDR_TYPE_NONE &&
720 etm.addr_type[idx + 1] == ETM_ADDR_TYPE_NONE) ||
721 (etm.addr_type[idx] == ETM_ADDR_TYPE_RANGE &&
722 etm.addr_type[idx + 1] == ETM_ADDR_TYPE_RANGE))) {
723 mutex_unlock(&etm.mutex);
724 return -EPERM;
725 }
726
727 val1 = etm.addr_val[idx];
728 val2 = etm.addr_val[idx + 1];
729 mutex_unlock(&etm.mutex);
730 return scnprintf(buf, PAGE_SIZE, "%#lx %#lx\n", val1, val2);
731}
732ETM_ATTR(addr_range);
733
734static ssize_t addr_start_store(struct kobject *kobj,
735 struct kobj_attribute *attr,
736 const char *buf, size_t n)
737{
738 unsigned long val;
739 uint8_t idx;
740
741 if (sscanf(buf, "%lx", &val) != 1)
742 return -EINVAL;
743
744 mutex_lock(&etm.mutex);
745 idx = etm.addr_idx;
746 if (!(etm.addr_type[idx] == ETM_ADDR_TYPE_NONE ||
747 etm.addr_type[idx] == ETM_ADDR_TYPE_START)) {
748 mutex_unlock(&etm.mutex);
749 return -EPERM;
750 }
751
752 etm.addr_val[idx] = val;
753 etm.addr_type[idx] = ETM_ADDR_TYPE_START;
754 etm.startstop_ctrl |= (1 << idx);
755 etm.enable_ctrl1 |= BIT(25);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800756 mutex_unlock(&etm.mutex);
757 return n;
758}
759static ssize_t addr_start_show(struct kobject *kobj,
760 struct kobj_attribute *attr,
761 char *buf)
762{
763 unsigned long val;
764 uint8_t idx;
765
766 mutex_lock(&etm.mutex);
767 idx = etm.addr_idx;
768 if (!(etm.addr_type[idx] == ETM_ADDR_TYPE_NONE ||
769 etm.addr_type[idx] == ETM_ADDR_TYPE_START)) {
770 mutex_unlock(&etm.mutex);
771 return -EPERM;
772 }
773
774 val = etm.addr_val[idx];
775 mutex_unlock(&etm.mutex);
776 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
777}
778ETM_ATTR(addr_start);
779
780static ssize_t addr_stop_store(struct kobject *kobj,
781 struct kobj_attribute *attr,
782 const char *buf, size_t n)
783{
784 unsigned long val;
785 uint8_t idx;
786
787 if (sscanf(buf, "%lx", &val) != 1)
788 return -EINVAL;
789
790 mutex_lock(&etm.mutex);
791 idx = etm.addr_idx;
792 if (!(etm.addr_type[idx] == ETM_ADDR_TYPE_NONE ||
793 etm.addr_type[idx] == ETM_ADDR_TYPE_STOP)) {
794 mutex_unlock(&etm.mutex);
795 return -EPERM;
796 }
797
798 etm.addr_val[idx] = val;
799 etm.addr_type[idx] = ETM_ADDR_TYPE_STOP;
800 etm.startstop_ctrl |= (1 << (idx + 16));
801 etm.enable_ctrl1 |= BIT(25);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800802 mutex_unlock(&etm.mutex);
803 return n;
804}
805static ssize_t addr_stop_show(struct kobject *kobj,
806 struct kobj_attribute *attr,
807 char *buf)
808{
809 unsigned long val;
810 uint8_t idx;
811
812 mutex_lock(&etm.mutex);
813 idx = etm.addr_idx;
814 if (!(etm.addr_type[idx] == ETM_ADDR_TYPE_NONE ||
815 etm.addr_type[idx] == ETM_ADDR_TYPE_STOP)) {
816 mutex_unlock(&etm.mutex);
817 return -EPERM;
818 }
819
820 val = etm.addr_val[idx];
821 mutex_unlock(&etm.mutex);
822 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
823}
824ETM_ATTR(addr_stop);
825
826static ssize_t addr_acctype_store(struct kobject *kobj,
827 struct kobj_attribute *attr,
828 const char *buf, size_t n)
829{
830 unsigned long val;
831
832 if (sscanf(buf, "%lx", &val) != 1)
833 return -EINVAL;
834
835 mutex_lock(&etm.mutex);
836 etm.addr_acctype[etm.addr_idx] = val;
Pratik Patel6630ebe2012-03-06 16:44:22 -0800837 mutex_unlock(&etm.mutex);
838 return n;
839}
840static ssize_t addr_acctype_show(struct kobject *kobj,
841 struct kobj_attribute *attr,
842 char *buf)
843{
844 unsigned long val;
845
846 mutex_lock(&etm.mutex);
847 val = etm.addr_acctype[etm.addr_idx];
848 mutex_unlock(&etm.mutex);
849 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
850}
851ETM_ATTR(addr_acctype);
852
853static ssize_t cntr_idx_store(struct kobject *kobj,
854 struct kobj_attribute *attr,
855 const char *buf, size_t n)
856{
857 unsigned long val;
858
859 if (sscanf(buf, "%lx", &val) != 1)
860 return -EINVAL;
861 if (val >= etm.nr_cntr)
862 return -EINVAL;
863
864 /* Use mutex to ensure index doesn't change while it gets dereferenced
865 * multiple times within a mutex block elsewhere.
866 */
867 mutex_lock(&etm.mutex);
868 etm.cntr_idx = val;
869 mutex_unlock(&etm.mutex);
870 return n;
871}
872ETM_SHOW(cntr_idx);
873ETM_ATTR(cntr_idx);
874
875static ssize_t cntr_rld_val_store(struct kobject *kobj,
876 struct kobj_attribute *attr,
877 const char *buf, size_t n)
878{
879 unsigned long val;
880
881 if (sscanf(buf, "%lx", &val) != 1)
882 return -EINVAL;
883
884 mutex_lock(&etm.mutex);
885 etm.cntr_rld_val[etm.cntr_idx] = val;
886 mutex_unlock(&etm.mutex);
887 return n;
888}
889static ssize_t cntr_rld_val_show(struct kobject *kobj,
890 struct kobj_attribute *attr,
891 char *buf)
892{
893 unsigned long val;
894 mutex_lock(&etm.mutex);
895 val = etm.cntr_rld_val[etm.cntr_idx];
896 mutex_unlock(&etm.mutex);
897 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
898}
899ETM_ATTR(cntr_rld_val);
900
901static ssize_t cntr_event_store(struct kobject *kobj,
902 struct kobj_attribute *attr,
903 const char *buf, size_t n)
904{
905 unsigned long val;
906
907 if (sscanf(buf, "%lx", &val) != 1)
908 return -EINVAL;
909
910 mutex_lock(&etm.mutex);
911 etm.cntr_event[etm.cntr_idx] = val & ETM_EVENT_MASK;
912 mutex_unlock(&etm.mutex);
913 return n;
914}
915static ssize_t cntr_event_show(struct kobject *kobj,
916 struct kobj_attribute *attr,
917 char *buf)
918{
919 unsigned long val;
920
921 mutex_lock(&etm.mutex);
922 val = etm.cntr_event[etm.cntr_idx];
923 mutex_unlock(&etm.mutex);
924 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
925}
926ETM_ATTR(cntr_event);
927
928static ssize_t cntr_rld_event_store(struct kobject *kobj,
929 struct kobj_attribute *attr,
930 const char *buf, size_t n)
931{
932 unsigned long val;
933
934 if (sscanf(buf, "%lx", &val) != 1)
935 return -EINVAL;
936
937 mutex_lock(&etm.mutex);
938 etm.cntr_rld_event[etm.cntr_idx] = val & ETM_EVENT_MASK;
939 mutex_unlock(&etm.mutex);
940 return n;
941}
942static ssize_t cntr_rld_event_show(struct kobject *kobj,
943 struct kobj_attribute *attr,
944 char *buf)
945{
946 unsigned long val;
947
948 mutex_lock(&etm.mutex);
949 val = etm.cntr_rld_event[etm.cntr_idx];
950 mutex_unlock(&etm.mutex);
951 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
952}
953ETM_ATTR(cntr_rld_event);
954
955static ssize_t cntr_val_store(struct kobject *kobj,
956 struct kobj_attribute *attr,
957 const char *buf, size_t n)
958{
959 unsigned long val;
960
961 if (sscanf(buf, "%lx", &val) != 1)
962 return -EINVAL;
963
964 mutex_lock(&etm.mutex);
965 etm.cntr_val[etm.cntr_idx] = val;
966 mutex_unlock(&etm.mutex);
967 return n;
968}
969static ssize_t cntr_val_show(struct kobject *kobj,
970 struct kobj_attribute *attr,
971 char *buf)
972{
973 unsigned long val;
974
975 mutex_lock(&etm.mutex);
976 val = etm.cntr_val[etm.cntr_idx];
977 mutex_unlock(&etm.mutex);
978 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
979}
980ETM_ATTR(cntr_val);
981
982ETM_STORE(seq_12_event, ETM_EVENT_MASK);
983ETM_SHOW(seq_12_event);
984ETM_ATTR(seq_12_event);
985
986ETM_STORE(seq_21_event, ETM_EVENT_MASK);
987ETM_SHOW(seq_21_event);
988ETM_ATTR(seq_21_event);
989
990ETM_STORE(seq_23_event, ETM_EVENT_MASK);
991ETM_SHOW(seq_23_event);
992ETM_ATTR(seq_23_event);
993
994ETM_STORE(seq_31_event, ETM_EVENT_MASK);
995ETM_SHOW(seq_31_event);
996ETM_ATTR(seq_31_event);
997
998ETM_STORE(seq_32_event, ETM_EVENT_MASK);
999ETM_SHOW(seq_32_event);
1000ETM_ATTR(seq_32_event);
1001
1002ETM_STORE(seq_13_event, ETM_EVENT_MASK);
1003ETM_SHOW(seq_13_event);
1004ETM_ATTR(seq_13_event);
1005
1006static ssize_t seq_curr_state_store(struct kobject *kobj,
1007 struct kobj_attribute *attr,
1008 const char *buf, size_t n)
1009{
1010 unsigned long val;
1011
1012 if (sscanf(buf, "%lx", &val) != 1)
1013 return -EINVAL;
1014 if (val > ETM_SEQ_STATE_MAX_VAL)
1015 return -EINVAL;
1016
1017 etm.seq_curr_state = val;
1018 return n;
1019}
1020ETM_SHOW(seq_curr_state);
1021ETM_ATTR(seq_curr_state);
1022
1023static ssize_t ctxid_idx_store(struct kobject *kobj,
1024 struct kobj_attribute *attr,
1025 const char *buf, size_t n)
1026{
1027 unsigned long val;
1028
1029 if (sscanf(buf, "%lx", &val) != 1)
1030 return -EINVAL;
1031 if (val >= etm.nr_ctxid_cmp)
1032 return -EINVAL;
1033
1034 /* Use mutex to ensure index doesn't change while it gets dereferenced
1035 * multiple times within a mutex block elsewhere.
1036 */
1037 mutex_lock(&etm.mutex);
1038 etm.ctxid_idx = val;
1039 mutex_unlock(&etm.mutex);
1040 return n;
1041}
1042ETM_SHOW(ctxid_idx);
1043ETM_ATTR(ctxid_idx);
1044
1045static ssize_t ctxid_val_store(struct kobject *kobj,
1046 struct kobj_attribute *attr,
1047 const char *buf, size_t n)
1048{
1049 unsigned long val;
1050
1051 if (sscanf(buf, "%lx", &val) != 1)
1052 return -EINVAL;
1053
1054 mutex_lock(&etm.mutex);
1055 etm.ctxid_val[etm.ctxid_idx] = val;
1056 mutex_unlock(&etm.mutex);
1057 return n;
1058}
1059static ssize_t ctxid_val_show(struct kobject *kobj,
1060 struct kobj_attribute *attr,
1061 char *buf)
1062{
1063 unsigned long val;
1064
1065 mutex_lock(&etm.mutex);
1066 val = etm.ctxid_val[etm.ctxid_idx];
1067 mutex_unlock(&etm.mutex);
1068 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
1069}
1070ETM_ATTR(ctxid_val);
1071
1072ETM_STORE(ctxid_mask, ETM_ALL_MASK);
1073ETM_SHOW(ctxid_mask);
1074ETM_ATTR(ctxid_mask);
1075
1076ETM_STORE(sync_freq, ETM_SYNC_MASK);
1077ETM_SHOW(sync_freq);
1078ETM_ATTR(sync_freq);
1079
1080ETM_STORE(timestamp_event, ETM_EVENT_MASK);
1081ETM_SHOW(timestamp_event);
1082ETM_ATTR(timestamp_event);
1083
1084static struct attribute *etm_attrs[] = {
1085 &nr_addr_cmp_attr.attr,
1086 &nr_cntr_attr.attr,
1087 &nr_ctxid_cmp_attr.attr,
Pratik Pateld30deda2012-02-01 14:40:55 -08001088 &reset_attr.attr,
Pratik Patel6630ebe2012-03-06 16:44:22 -08001089 &mode_attr.attr,
1090 &trigger_event_attr.attr,
1091 &enable_event_attr.attr,
1092 &fifofull_level_attr.attr,
1093 &addr_idx_attr.attr,
Pratik Patel6630ebe2012-03-06 16:44:22 -08001094 &addr_single_attr.attr,
1095 &addr_range_attr.attr,
1096 &addr_start_attr.attr,
1097 &addr_stop_attr.attr,
1098 &addr_acctype_attr.attr,
1099 &cntr_idx_attr.attr,
1100 &cntr_rld_val_attr.attr,
1101 &cntr_event_attr.attr,
1102 &cntr_rld_event_attr.attr,
1103 &cntr_val_attr.attr,
1104 &seq_12_event_attr.attr,
1105 &seq_21_event_attr.attr,
1106 &seq_23_event_attr.attr,
1107 &seq_31_event_attr.attr,
1108 &seq_32_event_attr.attr,
1109 &seq_13_event_attr.attr,
1110 &seq_curr_state_attr.attr,
1111 &ctxid_idx_attr.attr,
1112 &ctxid_val_attr.attr,
1113 &ctxid_mask_attr.attr,
1114 &sync_freq_attr.attr,
1115 &timestamp_event_attr.attr,
1116 NULL,
1117};
1118
1119static struct attribute_group etm_attr_grp = {
1120 .attrs = etm_attrs,
1121};
1122
1123static int __init etm_sysfs_init(void)
1124{
1125 int ret;
1126
1127 etm.kobj = kobject_create_and_add("etm", qdss_get_modulekobj());
1128 if (!etm.kobj) {
1129 dev_err(etm.dev, "failed to create ETM sysfs kobject\n");
1130 ret = -ENOMEM;
1131 goto err_create;
1132 }
1133
1134 ret = sysfs_create_file(etm.kobj, &enabled_attr.attr);
1135 if (ret) {
1136 dev_err(etm.dev, "failed to create ETM sysfs enabled"
1137 " attribute\n");
1138 goto err_file;
1139 }
1140
1141 if (sysfs_create_group(etm.kobj, &etm_attr_grp))
1142 dev_err(etm.dev, "failed to create ETM sysfs group\n");
1143
1144 return 0;
1145err_file:
1146 kobject_put(etm.kobj);
1147err_create:
1148 return ret;
1149}
1150
1151static void etm_sysfs_exit(void)
1152{
1153 sysfs_remove_group(etm.kobj, &etm_attr_grp);
1154 sysfs_remove_file(etm.kobj, &enabled_attr.attr);
1155 kobject_put(etm.kobj);
1156}
1157
Pratik Patel61de7302012-03-07 12:06:10 -08001158static bool etm_arch_supported(uint8_t arch)
Pratik Patel7831c082011-06-08 21:44:37 -07001159{
Pratik Patel61de7302012-03-07 12:06:10 -08001160 switch (arch) {
1161 case PFT_ARCH_V1_1:
1162 break;
1163 default:
1164 return false;
1165 }
1166 return true;
1167}
1168
1169static int __init etm_arch_init(void)
1170{
1171 int ret;
Pratik Patel7831c082011-06-08 21:44:37 -07001172 /* use cpu 0 for setup */
1173 int cpu = 0;
Pratik Patel61de7302012-03-07 12:06:10 -08001174 uint32_t etmidr;
1175 uint32_t etmccr;
Pratik Patel7831c082011-06-08 21:44:37 -07001176
Pratik Patel17f3b822011-11-21 12:41:47 -08001177 /* Unlock OS lock first to allow memory mapped reads and writes */
Pratik Patel492b3012012-03-06 14:22:30 -08001178 etm_os_unlock(NULL);
1179 smp_call_function(etm_os_unlock, NULL, 1);
1180 ETM_UNLOCK(cpu);
Pratik Patel17f3b822011-11-21 12:41:47 -08001181 /* Vote for ETM power/clock enable */
Pratik Patel61de7302012-03-07 12:06:10 -08001182 etm_clr_pwrdwn(cpu);
1183 /* Set prog bit. It will be set from reset but this is included to
1184 * ensure it is set
1185 */
Pratik Patel492b3012012-03-06 14:22:30 -08001186 etm_set_prog(cpu);
Pratik Patel7831c082011-06-08 21:44:37 -07001187
1188 /* find all capabilities */
Pratik Patel61de7302012-03-07 12:06:10 -08001189 etmidr = etm_readl(etm, cpu, ETMIDR);
1190 etm.arch = BMVAL(etmidr, 4, 11);
1191 if (etm_arch_supported(etm.arch) == false) {
1192 ret = -EINVAL;
1193 goto err;
1194 }
Pratik Patel7831c082011-06-08 21:44:37 -07001195
Pratik Patel61de7302012-03-07 12:06:10 -08001196 etmccr = etm_readl(etm, cpu, ETMCCR);
1197 etm.nr_addr_cmp = BMVAL(etmccr, 0, 3) * 2;
1198 etm.nr_cntr = BMVAL(etmccr, 13, 15);
1199 etm.nr_ext_inp = BMVAL(etmccr, 17, 19);
1200 etm.nr_ext_out = BMVAL(etmccr, 20, 22);
1201 etm.nr_ctxid_cmp = BMVAL(etmccr, 24, 25);
Pratik Patel7831c082011-06-08 21:44:37 -07001202
Pratik Patel17f3b822011-11-21 12:41:47 -08001203 /* Vote for ETM power/clock disable */
Pratik Patel61de7302012-03-07 12:06:10 -08001204 etm_set_pwrdwn(cpu);
Pratik Patel492b3012012-03-06 14:22:30 -08001205 ETM_LOCK(cpu);
Pratik Patel61de7302012-03-07 12:06:10 -08001206
1207 return 0;
1208err:
1209 return ret;
Pratik Patel7831c082011-06-08 21:44:37 -07001210}
1211
Pratik Patel492b3012012-03-06 14:22:30 -08001212static int __devinit etm_probe(struct platform_device *pdev)
Pratik Patel7831c082011-06-08 21:44:37 -07001213{
Pratik Patele5771792011-09-17 18:33:54 -07001214 int ret;
Pratik Patel7831c082011-06-08 21:44:37 -07001215 struct resource *res;
1216
1217 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1218 if (!res) {
1219 ret = -EINVAL;
1220 goto err_res;
1221 }
1222
Pratik Patel492b3012012-03-06 14:22:30 -08001223 etm.base = ioremap_nocache(res->start, resource_size(res));
1224 if (!etm.base) {
Pratik Patel7831c082011-06-08 21:44:37 -07001225 ret = -EINVAL;
1226 goto err_ioremap;
1227 }
1228
Pratik Patel492b3012012-03-06 14:22:30 -08001229 etm.dev = &pdev->dev;
Pratik Patel7831c082011-06-08 21:44:37 -07001230
Pratik Patel6630ebe2012-03-06 16:44:22 -08001231 mutex_init(&etm.mutex);
Pratik Patel61de7302012-03-07 12:06:10 -08001232 wake_lock_init(&etm.wake_lock, WAKE_LOCK_SUSPEND, "msm_etm");
1233 pm_qos_add_request(&etm.qos_req, PM_QOS_CPU_DMA_LATENCY,
1234 PM_QOS_DEFAULT_VALUE);
Pratik Patelcc320a42011-12-22 10:48:14 -08001235 ret = qdss_clk_enable();
Pratik Patel7831c082011-06-08 21:44:37 -07001236 if (ret)
Pratik Patelcc320a42011-12-22 10:48:14 -08001237 goto err_clk;
Pratik Patel7831c082011-06-08 21:44:37 -07001238
Pratik Patel61de7302012-03-07 12:06:10 -08001239 ret = etm_arch_init();
1240 if (ret)
1241 goto err_arch;
Pratik Patel7831c082011-06-08 21:44:37 -07001242
Pratik Patel6630ebe2012-03-06 16:44:22 -08001243 ret = etm_sysfs_init();
1244 if (ret)
1245 goto err_sysfs;
1246
Pratik Patel61de7302012-03-07 12:06:10 -08001247 etm.enabled = false;
Pratik Patel7831c082011-06-08 21:44:37 -07001248
Pratik Patelcc320a42011-12-22 10:48:14 -08001249 qdss_clk_disable();
Pratik Patel7831c082011-06-08 21:44:37 -07001250
Pratik Patel61de7302012-03-07 12:06:10 -08001251 dev_info(etm.dev, "ETM initialized\n");
Pratik Patel7831c082011-06-08 21:44:37 -07001252
Pratik Patel61de7302012-03-07 12:06:10 -08001253 if (etm_boot_enable)
1254 etm_enable();
Pratik Patel7831c082011-06-08 21:44:37 -07001255
1256 return 0;
1257
Pratik Patel6630ebe2012-03-06 16:44:22 -08001258err_sysfs:
Pratik Patel61de7302012-03-07 12:06:10 -08001259err_arch:
1260 qdss_clk_disable();
Pratik Patelcc320a42011-12-22 10:48:14 -08001261err_clk:
Pratik Patel61de7302012-03-07 12:06:10 -08001262 pm_qos_remove_request(&etm.qos_req);
1263 wake_lock_destroy(&etm.wake_lock);
Pratik Patel6630ebe2012-03-06 16:44:22 -08001264 mutex_destroy(&etm.mutex);
Pratik Patel492b3012012-03-06 14:22:30 -08001265 iounmap(etm.base);
Pratik Patel7831c082011-06-08 21:44:37 -07001266err_ioremap:
1267err_res:
Pratik Patel61de7302012-03-07 12:06:10 -08001268 dev_err(etm.dev, "ETM init failed\n");
Pratik Patel7831c082011-06-08 21:44:37 -07001269 return ret;
1270}
1271
Pratik Patel492b3012012-03-06 14:22:30 -08001272static int etm_remove(struct platform_device *pdev)
Pratik Patel7831c082011-06-08 21:44:37 -07001273{
Pratik Patel61de7302012-03-07 12:06:10 -08001274 if (etm.enabled)
1275 etm_disable();
Pratik Patel6630ebe2012-03-06 16:44:22 -08001276 etm_sysfs_exit();
Pratik Patel492b3012012-03-06 14:22:30 -08001277 pm_qos_remove_request(&etm.qos_req);
1278 wake_lock_destroy(&etm.wake_lock);
Pratik Patel6630ebe2012-03-06 16:44:22 -08001279 mutex_destroy(&etm.mutex);
Pratik Patel492b3012012-03-06 14:22:30 -08001280 iounmap(etm.base);
Pratik Patel7831c082011-06-08 21:44:37 -07001281
1282 return 0;
1283}
1284
Pratik Patel492b3012012-03-06 14:22:30 -08001285static struct platform_driver etm_driver = {
1286 .probe = etm_probe,
1287 .remove = etm_remove,
Pratik Patel7831c082011-06-08 21:44:37 -07001288 .driver = {
Pratik Patel492b3012012-03-06 14:22:30 -08001289 .name = "msm_etm",
Pratik Patel7831c082011-06-08 21:44:37 -07001290 },
1291};
1292
Pratik Patel492b3012012-03-06 14:22:30 -08001293int __init etm_init(void)
Pratik Patel7831c082011-06-08 21:44:37 -07001294{
Pratik Patel492b3012012-03-06 14:22:30 -08001295 return platform_driver_register(&etm_driver);
Pratik Patel7831c082011-06-08 21:44:37 -07001296}
Pratik Patel7831c082011-06-08 21:44:37 -07001297
Pratik Patel492b3012012-03-06 14:22:30 -08001298void etm_exit(void)
Pratik Patel7831c082011-06-08 21:44:37 -07001299{
Pratik Patel492b3012012-03-06 14:22:30 -08001300 platform_driver_unregister(&etm_driver);
Pratik Patel7831c082011-06-08 21:44:37 -07001301}