blob: 4bc3f495358b49c4cd625d2ea38558737d51a1ba [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 Patel2d0c7b62012-02-24 19:04:37 -080030#include <mach/socinfo.h>
Pratik Patel7831c082011-06-08 21:44:37 -070031
32#include "qdss.h"
33
Pratik Patel492b3012012-03-06 14:22:30 -080034#define etm_writel(etm, cpu, val, off) \
35 __raw_writel((val), etm.base + (SZ_4K * cpu) + off)
36#define etm_readl(etm, cpu, off) \
37 __raw_readl(etm.base + (SZ_4K * cpu) + off)
Pratik Patel7831c082011-06-08 21:44:37 -070038
39/*
40 * Device registers:
41 * 0x000 - 0x2FC: Trace registers
42 * 0x300 - 0x314: Management registers
43 * 0x318 - 0xEFC: Trace registers
44 *
45 * Coresight registers
46 * 0xF00 - 0xF9C: Management registers
47 * 0xFA0 - 0xFA4: Management registers in PFTv1.0
48 * Trace registers in PFTv1.1
49 * 0xFA8 - 0xFFC: Management registers
50 */
51
52/* Trace registers (0x000-0x2FC) */
53#define ETMCR (0x000)
54#define ETMCCR (0x004)
55#define ETMTRIGGER (0x008)
56#define ETMSR (0x010)
57#define ETMSCR (0x014)
58#define ETMTSSCR (0x018)
59#define ETMTEEVR (0x020)
60#define ETMTECR1 (0x024)
61#define ETMFFLR (0x02C)
62#define ETMACVRn(n) (0x040 + (n * 4))
63#define ETMACTRn(n) (0x080 + (n * 4))
64#define ETMCNTRLDVRn(n) (0x140 + (n * 4))
65#define ETMCNTENRn(n) (0x150 + (n * 4))
66#define ETMCNTRLDEVRn(n) (0x160 + (n * 4))
67#define ETMCNTVRn(n) (0x170 + (n * 4))
68#define ETMSQ12EVR (0x180)
69#define ETMSQ21EVR (0x184)
70#define ETMSQ23EVR (0x188)
Pratik Pateld5bbc762012-01-29 14:13:21 -080071#define ETMSQ31EVR (0x18C)
72#define ETMSQ32EVR (0x190)
73#define ETMSQ13EVR (0x194)
Pratik Patel7831c082011-06-08 21:44:37 -070074#define ETMSQR (0x19C)
75#define ETMEXTOUTEVRn(n) (0x1A0 + (n * 4))
76#define ETMCIDCVRn(n) (0x1B0 + (n * 4))
77#define ETMCIDCMR (0x1BC)
78#define ETMIMPSPEC0 (0x1C0)
79#define ETMIMPSPEC1 (0x1C4)
80#define ETMIMPSPEC2 (0x1C8)
81#define ETMIMPSPEC3 (0x1CC)
82#define ETMIMPSPEC4 (0x1D0)
83#define ETMIMPSPEC5 (0x1D4)
84#define ETMIMPSPEC6 (0x1D8)
85#define ETMIMPSPEC7 (0x1DC)
86#define ETMSYNCFR (0x1E0)
87#define ETMIDR (0x1E4)
88#define ETMCCER (0x1E8)
89#define ETMEXTINSELR (0x1EC)
90#define ETMTESSEICR (0x1F0)
91#define ETMEIBCR (0x1F4)
92#define ETMTSEVR (0x1F8)
93#define ETMAUXCR (0x1FC)
94#define ETMTRACEIDR (0x200)
Pratik Pateld5bbc762012-01-29 14:13:21 -080095#define ETMVMIDCVR (0x240)
Pratik Patel7831c082011-06-08 21:44:37 -070096/* Management registers (0x300-0x314) */
97#define ETMOSLAR (0x300)
98#define ETMOSLSR (0x304)
99#define ETMOSSRR (0x308)
100#define ETMPDCR (0x310)
101#define ETMPDSR (0x314)
102
Pratik Patel61de7302012-03-07 12:06:10 -0800103#define ETM_MAX_ADDR_CMP (16)
104#define ETM_MAX_CNTR (4)
105#define ETM_MAX_CTXID_CMP (3)
106
Pratik Patel6630ebe2012-03-06 16:44:22 -0800107#define ETM_MODE_EXCLUDE BIT(0)
108#define ETM_MODE_CYCACC BIT(1)
109#define ETM_MODE_STALL BIT(2)
110#define ETM_MODE_TIMESTAMP BIT(3)
111#define ETM_MODE_CTXID BIT(4)
112#define ETM_MODE_ALL (0x1F)
113
114#define ETM_EVENT_MASK (0x1FFFF)
115#define ETM_SYNC_MASK (0xFFF)
116#define ETM_ALL_MASK (0xFFFFFFFF)
117
118#define ETM_SEQ_STATE_MAX_VAL (0x2)
119
120enum {
121 ETM_ADDR_TYPE_NONE,
122 ETM_ADDR_TYPE_SINGLE,
123 ETM_ADDR_TYPE_RANGE,
124 ETM_ADDR_TYPE_START,
125 ETM_ADDR_TYPE_STOP,
126};
127
Pratik Patel492b3012012-03-06 14:22:30 -0800128#define ETM_LOCK(cpu) \
Pratik Patel7831c082011-06-08 21:44:37 -0700129do { \
130 mb(); \
Pratik Patel492b3012012-03-06 14:22:30 -0800131 etm_writel(etm, cpu, 0x0, CS_LAR); \
Pratik Patel7831c082011-06-08 21:44:37 -0700132} while (0)
Pratik Patel492b3012012-03-06 14:22:30 -0800133#define ETM_UNLOCK(cpu) \
Pratik Patel7831c082011-06-08 21:44:37 -0700134do { \
Pratik Patel492b3012012-03-06 14:22:30 -0800135 etm_writel(etm, cpu, CS_UNLOCK_MAGIC, CS_LAR); \
Pratik Patel7831c082011-06-08 21:44:37 -0700136 mb(); \
137} while (0)
138
Pratik Patel7831c082011-06-08 21:44:37 -0700139
Pratik Patel6630ebe2012-03-06 16:44:22 -0800140#ifdef MODULE_PARAM_PREFIX
141#undef MODULE_PARAM_PREFIX
142#endif
143#define MODULE_PARAM_PREFIX "qdss."
144
Pratik Patel29cba152012-01-03 11:40:26 -0800145#ifdef CONFIG_MSM_QDSS_ETM_DEFAULT_ENABLE
Pratik Patel61de7302012-03-07 12:06:10 -0800146static int etm_boot_enable = 1;
Pratik Patel29cba152012-01-03 11:40:26 -0800147#else
Pratik Patel61de7302012-03-07 12:06:10 -0800148static int etm_boot_enable;
Pratik Patel29cba152012-01-03 11:40:26 -0800149#endif
Pratik Patel7831c082011-06-08 21:44:37 -0700150module_param_named(
Pratik Patel61de7302012-03-07 12:06:10 -0800151 etm_boot_enable, etm_boot_enable, int, S_IRUGO
Pratik Patel7831c082011-06-08 21:44:37 -0700152);
153
Pratik Patel492b3012012-03-06 14:22:30 -0800154struct etm_ctx {
Pratik Patel7831c082011-06-08 21:44:37 -0700155 void __iomem *base;
Pratik Patel61de7302012-03-07 12:06:10 -0800156 bool enabled;
Pratik Patel7831c082011-06-08 21:44:37 -0700157 struct wake_lock wake_lock;
158 struct pm_qos_request_list qos_req;
Pratik Patel6630ebe2012-03-06 16:44:22 -0800159 struct mutex mutex;
Pratik Patel7831c082011-06-08 21:44:37 -0700160 struct device *dev;
Pratik Patel6630ebe2012-03-06 16:44:22 -0800161 struct kobject *kobj;
Pratik Patel61de7302012-03-07 12:06:10 -0800162 uint8_t arch;
163 uint8_t nr_addr_cmp;
164 uint8_t nr_cntr;
165 uint8_t nr_ext_inp;
166 uint8_t nr_ext_out;
167 uint8_t nr_ctxid_cmp;
Pratik Pateld30deda2012-02-01 14:40:55 -0800168 uint8_t reset;
Pratik Patel6630ebe2012-03-06 16:44:22 -0800169 uint32_t mode;
Pratik Patel61de7302012-03-07 12:06:10 -0800170 uint32_t ctrl;
171 uint32_t trigger_event;
172 uint32_t startstop_ctrl;
173 uint32_t enable_event;
174 uint32_t enable_ctrl1;
175 uint32_t fifofull_level;
Pratik Patel6630ebe2012-03-06 16:44:22 -0800176 uint8_t addr_idx;
Pratik Patel61de7302012-03-07 12:06:10 -0800177 uint32_t addr_val[ETM_MAX_ADDR_CMP];
178 uint32_t addr_acctype[ETM_MAX_ADDR_CMP];
Pratik Patel6630ebe2012-03-06 16:44:22 -0800179 uint32_t addr_type[ETM_MAX_ADDR_CMP];
180 uint8_t cntr_idx;
Pratik Patel61de7302012-03-07 12:06:10 -0800181 uint32_t cntr_rld_val[ETM_MAX_CNTR];
182 uint32_t cntr_event[ETM_MAX_CNTR];
183 uint32_t cntr_rld_event[ETM_MAX_CNTR];
184 uint32_t cntr_val[ETM_MAX_CNTR];
185 uint32_t seq_12_event;
186 uint32_t seq_21_event;
187 uint32_t seq_23_event;
188 uint32_t seq_31_event;
189 uint32_t seq_32_event;
190 uint32_t seq_13_event;
191 uint32_t seq_curr_state;
Pratik Patel6630ebe2012-03-06 16:44:22 -0800192 uint8_t ctxid_idx;
Pratik Patel61de7302012-03-07 12:06:10 -0800193 uint32_t ctxid_val[ETM_MAX_CTXID_CMP];
194 uint32_t ctxid_mask;
195 uint32_t sync_freq;
196 uint32_t timestamp_event;
Pratik Patel7831c082011-06-08 21:44:37 -0700197};
198
Pratik Patel61de7302012-03-07 12:06:10 -0800199static struct etm_ctx etm = {
Pratik Patel61de7302012-03-07 12:06:10 -0800200 .trigger_event = 0x406F,
201 .enable_event = 0x6F,
Pratik Pateld30deda2012-02-01 14:40:55 -0800202 .enable_ctrl1 = 0x1,
Pratik Patel61de7302012-03-07 12:06:10 -0800203 .fifofull_level = 0x28,
Pratik Pateld30deda2012-02-01 14:40:55 -0800204 .addr_val = {(uint32_t) _stext, (uint32_t) _etext},
205 .addr_type = {ETM_ADDR_TYPE_RANGE, ETM_ADDR_TYPE_RANGE},
Pratik Patel61de7302012-03-07 12:06:10 -0800206 .cntr_event = {[0 ... (ETM_MAX_CNTR - 1)] = 0x406F},
207 .cntr_rld_event = {[0 ... (ETM_MAX_CNTR - 1)] = 0x406F},
208 .seq_12_event = 0x406F,
209 .seq_21_event = 0x406F,
210 .seq_23_event = 0x406F,
211 .seq_31_event = 0x406F,
212 .seq_32_event = 0x406F,
213 .seq_13_event = 0x406F,
214 .sync_freq = 0x80,
215 .timestamp_event = 0x406F,
216};
Pratik Patel7831c082011-06-08 21:44:37 -0700217
Pratik Patel7831c082011-06-08 21:44:37 -0700218
Pratik Patel17f3b822011-11-21 12:41:47 -0800219/* ETM clock is derived from the processor clock and gets enabled on a
220 * logical OR of below items on Krait (pass2 onwards):
221 * 1.CPMR[ETMCLKEN] is 1
222 * 2.ETMCR[PD] is 0
223 * 3.ETMPDCR[PU] is 1
224 * 4.Reset is asserted (core or debug)
225 * 5.APB memory mapped requests (eg. EDAP access)
226 *
227 * 1., 2. and 3. above are permanent enables whereas 4. and 5. are temporary
228 * enables
229 *
230 * We rely on 5. to be able to access ETMCR and then use 2. above for ETM
231 * clock vote in the driver and the save-restore code uses 1. above
232 * for its vote
233 */
Pratik Patel61de7302012-03-07 12:06:10 -0800234static void etm_set_pwrdwn(int cpu)
Pratik Patel7831c082011-06-08 21:44:37 -0700235{
236 uint32_t etmcr;
237
Pratik Patel492b3012012-03-06 14:22:30 -0800238 etmcr = etm_readl(etm, cpu, ETMCR);
Pratik Patel7831c082011-06-08 21:44:37 -0700239 etmcr |= BIT(0);
Pratik Patel492b3012012-03-06 14:22:30 -0800240 etm_writel(etm, cpu, etmcr, ETMCR);
Pratik Patel7831c082011-06-08 21:44:37 -0700241}
242
Pratik Patel61de7302012-03-07 12:06:10 -0800243static void etm_clr_pwrdwn(int cpu)
Pratik Patel7831c082011-06-08 21:44:37 -0700244{
245 uint32_t etmcr;
246
Pratik Patel492b3012012-03-06 14:22:30 -0800247 etmcr = etm_readl(etm, cpu, ETMCR);
Pratik Patel7831c082011-06-08 21:44:37 -0700248 etmcr &= ~BIT(0);
Pratik Patel492b3012012-03-06 14:22:30 -0800249 etm_writel(etm, cpu, etmcr, ETMCR);
Pratik Patel7831c082011-06-08 21:44:37 -0700250}
251
Pratik Patel492b3012012-03-06 14:22:30 -0800252static void etm_set_prog(int cpu)
Pratik Patel7831c082011-06-08 21:44:37 -0700253{
254 uint32_t etmcr;
255 int count;
256
Pratik Patel492b3012012-03-06 14:22:30 -0800257 etmcr = etm_readl(etm, cpu, ETMCR);
Pratik Patel7831c082011-06-08 21:44:37 -0700258 etmcr |= BIT(10);
Pratik Patel492b3012012-03-06 14:22:30 -0800259 etm_writel(etm, cpu, etmcr, ETMCR);
Pratik Patel7831c082011-06-08 21:44:37 -0700260
Pratik Patel492b3012012-03-06 14:22:30 -0800261 for (count = TIMEOUT_US; BVAL(etm_readl(etm, cpu, ETMSR), 1) != 1
Pratik Patel7831c082011-06-08 21:44:37 -0700262 && count > 0; count--)
263 udelay(1);
Pratik Patel61de7302012-03-07 12:06:10 -0800264 WARN(count == 0, "timeout while setting prog bit, ETMSR: %#x\n",
265 etm_readl(etm, cpu, ETMSR));
Pratik Patel7831c082011-06-08 21:44:37 -0700266}
267
Pratik Patel61de7302012-03-07 12:06:10 -0800268static void etm_clr_prog(int cpu)
Pratik Patel7831c082011-06-08 21:44:37 -0700269{
270 uint32_t etmcr;
271 int count;
272
Pratik Patel492b3012012-03-06 14:22:30 -0800273 etmcr = etm_readl(etm, cpu, ETMCR);
Pratik Patel7831c082011-06-08 21:44:37 -0700274 etmcr &= ~BIT(10);
Pratik Patel492b3012012-03-06 14:22:30 -0800275 etm_writel(etm, cpu, etmcr, ETMCR);
Pratik Patel7831c082011-06-08 21:44:37 -0700276
Pratik Patel492b3012012-03-06 14:22:30 -0800277 for (count = TIMEOUT_US; BVAL(etm_readl(etm, cpu, ETMSR), 1) != 0
Pratik Patel7831c082011-06-08 21:44:37 -0700278 && count > 0; count--)
279 udelay(1);
Pratik Patel61de7302012-03-07 12:06:10 -0800280 WARN(count == 0, "timeout while clearing prog bit, ETMSR: %#x\n",
281 etm_readl(etm, cpu, ETMSR));
Pratik Patel7831c082011-06-08 21:44:37 -0700282}
283
Pratik Patel61de7302012-03-07 12:06:10 -0800284static void __etm_enable(int cpu)
Pratik Patel7831c082011-06-08 21:44:37 -0700285{
Pratik Patel17f3b822011-11-21 12:41:47 -0800286 int i;
Pratik Patel7831c082011-06-08 21:44:37 -0700287
Pratik Patel492b3012012-03-06 14:22:30 -0800288 ETM_UNLOCK(cpu);
Pratik Patel17f3b822011-11-21 12:41:47 -0800289 /* Vote for ETM power/clock enable */
Pratik Patel61de7302012-03-07 12:06:10 -0800290 etm_clr_pwrdwn(cpu);
Pratik Patel492b3012012-03-06 14:22:30 -0800291 etm_set_prog(cpu);
Pratik Patel7831c082011-06-08 21:44:37 -0700292
Pratik Patel61de7302012-03-07 12:06:10 -0800293 etm_writel(etm, cpu, etm.ctrl | BIT(10), ETMCR);
294 etm_writel(etm, cpu, etm.trigger_event, ETMTRIGGER);
295 etm_writel(etm, cpu, etm.startstop_ctrl, ETMTSSCR);
296 etm_writel(etm, cpu, etm.enable_event, ETMTEEVR);
297 etm_writel(etm, cpu, etm.enable_ctrl1, ETMTECR1);
298 etm_writel(etm, cpu, etm.fifofull_level, ETMFFLR);
299 for (i = 0; i < etm.nr_addr_cmp; i++) {
300 etm_writel(etm, cpu, etm.addr_val[i], ETMACVRn(i));
301 etm_writel(etm, cpu, etm.addr_acctype[i], ETMACTRn(i));
Pratik Patel7831c082011-06-08 21:44:37 -0700302 }
Pratik Patel61de7302012-03-07 12:06:10 -0800303 for (i = 0; i < etm.nr_cntr; i++) {
304 etm_writel(etm, cpu, etm.cntr_rld_val[i], ETMCNTRLDVRn(i));
305 etm_writel(etm, cpu, etm.cntr_event[i], ETMCNTENRn(i));
306 etm_writel(etm, cpu, etm.cntr_rld_event[i], ETMCNTRLDEVRn(i));
307 etm_writel(etm, cpu, etm.cntr_val[i], ETMCNTVRn(i));
Pratik Patel17f3b822011-11-21 12:41:47 -0800308 }
Pratik Patel61de7302012-03-07 12:06:10 -0800309 etm_writel(etm, cpu, etm.seq_12_event, ETMSQ12EVR);
310 etm_writel(etm, cpu, etm.seq_21_event, ETMSQ21EVR);
311 etm_writel(etm, cpu, etm.seq_23_event, ETMSQ23EVR);
312 etm_writel(etm, cpu, etm.seq_31_event, ETMSQ31EVR);
313 etm_writel(etm, cpu, etm.seq_32_event, ETMSQ32EVR);
314 etm_writel(etm, cpu, etm.seq_13_event, ETMSQ13EVR);
315 etm_writel(etm, cpu, etm.seq_curr_state, ETMSQR);
316 for (i = 0; i < etm.nr_ext_out; i++)
317 etm_writel(etm, cpu, 0x0000406F, ETMEXTOUTEVRn(i));
318 for (i = 0; i < etm.nr_ctxid_cmp; i++)
319 etm_writel(etm, cpu, etm.ctxid_val[i], ETMCIDCVRn(i));
320 etm_writel(etm, cpu, etm.ctxid_mask, ETMCIDCMR);
321 etm_writel(etm, cpu, etm.sync_freq, ETMSYNCFR);
322 etm_writel(etm, cpu, 0x00000000, ETMEXTINSELR);
323 etm_writel(etm, cpu, etm.timestamp_event, ETMTSEVR);
324 etm_writel(etm, cpu, 0x00000000, ETMAUXCR);
Pratik Patel492b3012012-03-06 14:22:30 -0800325 etm_writel(etm, cpu, cpu+1, ETMTRACEIDR);
Pratik Patel61de7302012-03-07 12:06:10 -0800326 etm_writel(etm, cpu, 0x00000000, ETMVMIDCVR);
Pratik Patel17f3b822011-11-21 12:41:47 -0800327
Pratik Patel61de7302012-03-07 12:06:10 -0800328 etm_clr_prog(cpu);
Pratik Patel492b3012012-03-06 14:22:30 -0800329 ETM_LOCK(cpu);
Pratik Patel7831c082011-06-08 21:44:37 -0700330}
331
Pratik Patel61de7302012-03-07 12:06:10 -0800332static int etm_enable(void)
Pratik Patel7831c082011-06-08 21:44:37 -0700333{
Pratik Patel17f3b822011-11-21 12:41:47 -0800334 int ret, cpu;
Pratik Patel7831c082011-06-08 21:44:37 -0700335
Pratik Patel61de7302012-03-07 12:06:10 -0800336 if (etm.enabled) {
337 dev_err(etm.dev, "ETM tracing already enabled\n");
338 ret = -EPERM;
339 goto err;
340 }
341
Pratik Patelcc320a42011-12-22 10:48:14 -0800342 ret = qdss_clk_enable();
Pratik Patel7831c082011-06-08 21:44:37 -0700343 if (ret)
Pratik Patel61de7302012-03-07 12:06:10 -0800344 goto err;
Pratik Patel7831c082011-06-08 21:44:37 -0700345
Pratik Patel492b3012012-03-06 14:22:30 -0800346 wake_lock(&etm.wake_lock);
Pratik Patele5771792011-09-17 18:33:54 -0700347 /* 1. causes all online cpus to come out of idle PC
Pratik Patel7831c082011-06-08 21:44:37 -0700348 * 2. prevents idle PC until save restore flag is enabled atomically
Pratik Patele5771792011-09-17 18:33:54 -0700349 *
350 * we rely on the user to prevent hotplug on/off racing with this
351 * operation and to ensure cores where trace is expected to be turned
352 * on are already hotplugged on
Pratik Patel7831c082011-06-08 21:44:37 -0700353 */
Pratik Patel492b3012012-03-06 14:22:30 -0800354 pm_qos_update_request(&etm.qos_req, 0);
Pratik Patel7831c082011-06-08 21:44:37 -0700355
356 etb_disable();
357 tpiu_disable();
358 /* enable ETB first to avoid loosing any trace data */
359 etb_enable();
360 funnel_enable(0x0, 0x3);
Pratik Patel17f3b822011-11-21 12:41:47 -0800361 for_each_online_cpu(cpu)
Pratik Patel61de7302012-03-07 12:06:10 -0800362 __etm_enable(cpu);
Pratik Patel7831c082011-06-08 21:44:37 -0700363
Pratik Patel61de7302012-03-07 12:06:10 -0800364 etm.enabled = true;
Pratik Patel7831c082011-06-08 21:44:37 -0700365
Pratik Patel492b3012012-03-06 14:22:30 -0800366 pm_qos_update_request(&etm.qos_req, PM_QOS_DEFAULT_VALUE);
367 wake_unlock(&etm.wake_lock);
Pratik Patel7831c082011-06-08 21:44:37 -0700368
Pratik Patel61de7302012-03-07 12:06:10 -0800369 dev_info(etm.dev, "ETM tracing enabled\n");
Pratik Patel7831c082011-06-08 21:44:37 -0700370 return 0;
Pratik Patel61de7302012-03-07 12:06:10 -0800371err:
372 return ret;
Pratik Patel7831c082011-06-08 21:44:37 -0700373}
374
Pratik Patel61de7302012-03-07 12:06:10 -0800375static void __etm_disable(int cpu)
Pratik Patel7831c082011-06-08 21:44:37 -0700376{
Pratik Patel492b3012012-03-06 14:22:30 -0800377 ETM_UNLOCK(cpu);
378 etm_set_prog(cpu);
Pratik Patel7831c082011-06-08 21:44:37 -0700379
Pratik Patel17f3b822011-11-21 12:41:47 -0800380 /* program trace enable to low by using always false event */
Pratik Patel492b3012012-03-06 14:22:30 -0800381 etm_writel(etm, cpu, 0x6F | BIT(14), ETMTEEVR);
Pratik Patel7831c082011-06-08 21:44:37 -0700382
Pratik Patel17f3b822011-11-21 12:41:47 -0800383 /* Vote for ETM power/clock disable */
Pratik Patel61de7302012-03-07 12:06:10 -0800384 etm_set_pwrdwn(cpu);
Pratik Patel492b3012012-03-06 14:22:30 -0800385 ETM_LOCK(cpu);
Pratik Patel7831c082011-06-08 21:44:37 -0700386}
387
Pratik Patel61de7302012-03-07 12:06:10 -0800388static int etm_disable(void)
Pratik Patel7831c082011-06-08 21:44:37 -0700389{
Pratik Patel61de7302012-03-07 12:06:10 -0800390 int ret, cpu;
391
392 if (!etm.enabled) {
393 dev_err(etm.dev, "ETM tracing already disabled\n");
394 ret = -EPERM;
395 goto err;
396 }
Pratik Patel17f3b822011-11-21 12:41:47 -0800397
Pratik Patel492b3012012-03-06 14:22:30 -0800398 wake_lock(&etm.wake_lock);
Pratik Patele5771792011-09-17 18:33:54 -0700399 /* 1. causes all online cpus to come out of idle PC
Pratik Patel7831c082011-06-08 21:44:37 -0700400 * 2. prevents idle PC until save restore flag is disabled atomically
Pratik Patele5771792011-09-17 18:33:54 -0700401 *
402 * we rely on the user to prevent hotplug on/off racing with this
403 * operation and to ensure cores where trace is expected to be turned
404 * off are already hotplugged on
Pratik Patel7831c082011-06-08 21:44:37 -0700405 */
Pratik Patel492b3012012-03-06 14:22:30 -0800406 pm_qos_update_request(&etm.qos_req, 0);
Pratik Patel7831c082011-06-08 21:44:37 -0700407
Pratik Patel17f3b822011-11-21 12:41:47 -0800408 for_each_online_cpu(cpu)
Pratik Patel61de7302012-03-07 12:06:10 -0800409 __etm_disable(cpu);
Pratik Patel7831c082011-06-08 21:44:37 -0700410 etb_dump();
411 etb_disable();
412 funnel_disable(0x0, 0x3);
413
Pratik Patel61de7302012-03-07 12:06:10 -0800414 etm.enabled = false;
Pratik Patel7831c082011-06-08 21:44:37 -0700415
Pratik Patel492b3012012-03-06 14:22:30 -0800416 pm_qos_update_request(&etm.qos_req, PM_QOS_DEFAULT_VALUE);
417 wake_unlock(&etm.wake_lock);
Pratik Patel7831c082011-06-08 21:44:37 -0700418
Pratik Patelcc320a42011-12-22 10:48:14 -0800419 qdss_clk_disable();
Pratik Patel61de7302012-03-07 12:06:10 -0800420
421 dev_info(etm.dev, "ETM tracing disabled\n");
422 return 0;
423err:
424 return ret;
Pratik Patel7831c082011-06-08 21:44:37 -0700425}
426
Pratik Patel17f3b822011-11-21 12:41:47 -0800427/* Memory mapped writes to clear os lock not supported */
Pratik Patel492b3012012-03-06 14:22:30 -0800428static void etm_os_unlock(void *unused)
Pratik Patel17f3b822011-11-21 12:41:47 -0800429{
430 unsigned long value = 0x0;
431
432 asm("mcr p14, 1, %0, c1, c0, 4\n\t" : : "r" (value));
433 asm("isb\n\t");
434}
435
Pratik Patel6630ebe2012-03-06 16:44:22 -0800436#define ETM_STORE(__name, mask) \
437static ssize_t __name##_store(struct kobject *kobj, \
438 struct kobj_attribute *attr, \
439 const char *buf, size_t n) \
440{ \
441 unsigned long val; \
442 \
443 if (sscanf(buf, "%lx", &val) != 1) \
444 return -EINVAL; \
445 \
446 etm.__name = val & mask; \
447 return n; \
448}
449
450#define ETM_SHOW(__name) \
451static ssize_t __name##_show(struct kobject *kobj, \
452 struct kobj_attribute *attr, \
453 char *buf) \
454{ \
455 unsigned long val = etm.__name; \
456 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val); \
457}
458
459#define ETM_ATTR(__name) \
460static struct kobj_attribute __name##_attr = \
461 __ATTR(__name, S_IRUGO | S_IWUSR, __name##_show, __name##_store)
462#define ETM_ATTR_RO(__name) \
463static struct kobj_attribute __name##_attr = \
464 __ATTR(__name, S_IRUGO, __name##_show, NULL)
465
466static ssize_t enabled_store(struct kobject *kobj,
467 struct kobj_attribute *attr,
468 const char *buf, size_t n)
469{
470 int ret = 0;
471 unsigned long val;
472
473 if (sscanf(buf, "%lx", &val) != 1)
474 return -EINVAL;
475
476 mutex_lock(&etm.mutex);
477 if (val)
478 ret = etm_enable();
479 else
480 ret = etm_disable();
481 mutex_unlock(&etm.mutex);
482
483 if (ret)
484 return ret;
485 return n;
486}
487ETM_SHOW(enabled);
488ETM_ATTR(enabled);
489
490ETM_SHOW(nr_addr_cmp);
491ETM_ATTR_RO(nr_addr_cmp);
492ETM_SHOW(nr_cntr);
493ETM_ATTR_RO(nr_cntr);
494ETM_SHOW(nr_ctxid_cmp);
495ETM_ATTR_RO(nr_ctxid_cmp);
496
Pratik Pateld30deda2012-02-01 14:40:55 -0800497/* Reset to trace everything i.e. exclude nothing. */
498static ssize_t reset_store(struct kobject *kobj,
499 struct kobj_attribute *attr,
500 const char *buf, size_t n)
501{
502 int i;
503 unsigned long val;
504
505 if (sscanf(buf, "%lx", &val) != 1)
506 return -EINVAL;
507
508 mutex_lock(&etm.mutex);
509 if (val) {
Pratik Patel2d0c7b62012-02-24 19:04:37 -0800510 etm.mode = ETM_MODE_EXCLUDE;
511 etm.ctrl = 0x0;
512 if (cpu_is_krait_v1()) {
513 etm.mode |= ETM_MODE_CYCACC;
514 etm.ctrl |= BIT(12);
515 }
Pratik Pateld30deda2012-02-01 14:40:55 -0800516 etm.trigger_event = 0x406F;
517 etm.startstop_ctrl = 0x0;
518 etm.enable_event = 0x6F;
519 etm.enable_ctrl1 = 0x1000000;
520 etm.fifofull_level = 0x28;
521 etm.addr_idx = 0x0;
522 for (i = 0; i < etm.nr_addr_cmp; i++) {
523 etm.addr_val[i] = 0x0;
524 etm.addr_acctype[i] = 0x0;
525 etm.addr_type[i] = ETM_ADDR_TYPE_NONE;
526 }
527 etm.cntr_idx = 0x0;
528 for (i = 0; i < etm.nr_cntr; i++) {
529 etm.cntr_rld_val[i] = 0x0;
530 etm.cntr_event[i] = 0x406F;
531 etm.cntr_rld_event[i] = 0x406F;
532 etm.cntr_val[i] = 0x0;
533 }
534 etm.seq_12_event = 0x406F;
535 etm.seq_21_event = 0x406F;
536 etm.seq_23_event = 0x406F;
537 etm.seq_31_event = 0x406F;
538 etm.seq_32_event = 0x406F;
539 etm.seq_13_event = 0x406F;
540 etm.seq_curr_state = 0x0;
541 etm.ctxid_idx = 0x0;
542 for (i = 0; i < etm.nr_ctxid_cmp; i++)
543 etm.ctxid_val[i] = 0x0;
544 etm.ctxid_mask = 0x0;
545 etm.sync_freq = 0x80;
546 etm.timestamp_event = 0x406F;
547 }
548 mutex_unlock(&etm.mutex);
549 return n;
550}
551ETM_SHOW(reset);
552ETM_ATTR(reset);
553
Pratik Patel6630ebe2012-03-06 16:44:22 -0800554static ssize_t mode_store(struct kobject *kobj,
555 struct kobj_attribute *attr,
556 const char *buf, size_t n)
557{
558 unsigned long val;
559
560 if (sscanf(buf, "%lx", &val) != 1)
561 return -EINVAL;
562
563 mutex_lock(&etm.mutex);
564 etm.mode = val & ETM_MODE_ALL;
565
566 if (etm.mode & ETM_MODE_EXCLUDE)
567 etm.enable_ctrl1 |= BIT(24);
568 else
569 etm.enable_ctrl1 &= ~BIT(24);
570
571 if (etm.mode & ETM_MODE_CYCACC)
572 etm.ctrl |= BIT(12);
573 else
574 etm.ctrl &= ~BIT(12);
575
576 if (etm.mode & ETM_MODE_STALL)
577 etm.ctrl |= BIT(7);
578 else
579 etm.ctrl &= ~BIT(7);
580
581 if (etm.mode & ETM_MODE_TIMESTAMP)
582 etm.ctrl |= BIT(28);
583 else
584 etm.ctrl &= ~BIT(28);
585 if (etm.mode & ETM_MODE_CTXID)
586 etm.ctrl |= (BIT(14) | BIT(15));
587 else
588 etm.ctrl &= ~(BIT(14) | BIT(15));
589 mutex_unlock(&etm.mutex);
590
591 return n;
592}
593ETM_SHOW(mode);
594ETM_ATTR(mode);
595
596ETM_STORE(trigger_event, ETM_EVENT_MASK);
597ETM_SHOW(trigger_event);
598ETM_ATTR(trigger_event);
599
600ETM_STORE(enable_event, ETM_EVENT_MASK);
601ETM_SHOW(enable_event);
602ETM_ATTR(enable_event);
603
604ETM_STORE(fifofull_level, ETM_ALL_MASK);
605ETM_SHOW(fifofull_level);
606ETM_ATTR(fifofull_level);
607
608static ssize_t addr_idx_store(struct kobject *kobj,
609 struct kobj_attribute *attr,
610 const char *buf, size_t n)
611{
612 unsigned long val;
613
614 if (sscanf(buf, "%lx", &val) != 1)
615 return -EINVAL;
616 if (val >= etm.nr_addr_cmp)
617 return -EINVAL;
618
619 /* Use mutex to ensure index doesn't change while it gets dereferenced
620 * multiple times within a mutex block elsewhere.
621 */
622 mutex_lock(&etm.mutex);
623 etm.addr_idx = val;
624 mutex_unlock(&etm.mutex);
625 return n;
626}
627ETM_SHOW(addr_idx);
628ETM_ATTR(addr_idx);
629
Pratik Patel6630ebe2012-03-06 16:44:22 -0800630static ssize_t addr_single_store(struct kobject *kobj,
631 struct kobj_attribute *attr,
632 const char *buf, size_t n)
633{
634 unsigned long val;
635 uint8_t idx;
636
637 if (sscanf(buf, "%lx", &val) != 1)
638 return -EINVAL;
639
640 mutex_lock(&etm.mutex);
641 idx = etm.addr_idx;
642 if (!(etm.addr_type[idx] == ETM_ADDR_TYPE_NONE ||
643 etm.addr_type[idx] == ETM_ADDR_TYPE_SINGLE)) {
644 mutex_unlock(&etm.mutex);
645 return -EPERM;
646 }
647
648 etm.addr_val[idx] = val;
649 etm.addr_type[idx] = ETM_ADDR_TYPE_SINGLE;
Pratik Patel6630ebe2012-03-06 16:44:22 -0800650 mutex_unlock(&etm.mutex);
651 return n;
652}
653static ssize_t addr_single_show(struct kobject *kobj,
654 struct kobj_attribute *attr,
655 char *buf)
656{
657 unsigned long val;
658 uint8_t idx;
659
660 mutex_lock(&etm.mutex);
661 idx = etm.addr_idx;
662 if (!(etm.addr_type[idx] == ETM_ADDR_TYPE_NONE ||
663 etm.addr_type[idx] == ETM_ADDR_TYPE_SINGLE)) {
664 mutex_unlock(&etm.mutex);
665 return -EPERM;
666 }
667
668 val = etm.addr_val[idx];
669 mutex_unlock(&etm.mutex);
670 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
671}
672ETM_ATTR(addr_single);
673
674static ssize_t addr_range_store(struct kobject *kobj,
675 struct kobj_attribute *attr,
676 const char *buf, size_t n)
677{
678 unsigned long val1, val2;
679 uint8_t idx;
680
681 if (sscanf(buf, "%lx %lx", &val1, &val2) != 2)
682 return -EINVAL;
683 /* lower address comparator cannot have a higher address value */
684 if (val1 > val2)
685 return -EINVAL;
686
687 mutex_lock(&etm.mutex);
688 idx = etm.addr_idx;
689 if (idx % 2 != 0) {
690 mutex_unlock(&etm.mutex);
691 return -EPERM;
692 }
693 if (!((etm.addr_type[idx] == ETM_ADDR_TYPE_NONE &&
694 etm.addr_type[idx + 1] == ETM_ADDR_TYPE_NONE) ||
695 (etm.addr_type[idx] == ETM_ADDR_TYPE_RANGE &&
696 etm.addr_type[idx + 1] == ETM_ADDR_TYPE_RANGE))) {
697 mutex_unlock(&etm.mutex);
698 return -EPERM;
699 }
700
701 etm.addr_val[idx] = val1;
702 etm.addr_type[idx] = ETM_ADDR_TYPE_RANGE;
703 etm.addr_val[idx + 1] = val2;
704 etm.addr_type[idx + 1] = ETM_ADDR_TYPE_RANGE;
705 etm.enable_ctrl1 |= (1 << (idx/2));
Pratik Patel6630ebe2012-03-06 16:44:22 -0800706 mutex_unlock(&etm.mutex);
707 return n;
708}
709static ssize_t addr_range_show(struct kobject *kobj,
710 struct kobj_attribute *attr,
711 char *buf)
712{
713 unsigned long val1, val2;
714 uint8_t idx;
715
716 mutex_lock(&etm.mutex);
717 idx = etm.addr_idx;
718 if (idx % 2 != 0) {
719 mutex_unlock(&etm.mutex);
720 return -EPERM;
721 }
722 if (!((etm.addr_type[idx] == ETM_ADDR_TYPE_NONE &&
723 etm.addr_type[idx + 1] == ETM_ADDR_TYPE_NONE) ||
724 (etm.addr_type[idx] == ETM_ADDR_TYPE_RANGE &&
725 etm.addr_type[idx + 1] == ETM_ADDR_TYPE_RANGE))) {
726 mutex_unlock(&etm.mutex);
727 return -EPERM;
728 }
729
730 val1 = etm.addr_val[idx];
731 val2 = etm.addr_val[idx + 1];
732 mutex_unlock(&etm.mutex);
733 return scnprintf(buf, PAGE_SIZE, "%#lx %#lx\n", val1, val2);
734}
735ETM_ATTR(addr_range);
736
737static ssize_t addr_start_store(struct kobject *kobj,
738 struct kobj_attribute *attr,
739 const char *buf, size_t n)
740{
741 unsigned long val;
742 uint8_t idx;
743
744 if (sscanf(buf, "%lx", &val) != 1)
745 return -EINVAL;
746
747 mutex_lock(&etm.mutex);
748 idx = etm.addr_idx;
749 if (!(etm.addr_type[idx] == ETM_ADDR_TYPE_NONE ||
750 etm.addr_type[idx] == ETM_ADDR_TYPE_START)) {
751 mutex_unlock(&etm.mutex);
752 return -EPERM;
753 }
754
755 etm.addr_val[idx] = val;
756 etm.addr_type[idx] = ETM_ADDR_TYPE_START;
757 etm.startstop_ctrl |= (1 << idx);
758 etm.enable_ctrl1 |= BIT(25);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800759 mutex_unlock(&etm.mutex);
760 return n;
761}
762static ssize_t addr_start_show(struct kobject *kobj,
763 struct kobj_attribute *attr,
764 char *buf)
765{
766 unsigned long val;
767 uint8_t idx;
768
769 mutex_lock(&etm.mutex);
770 idx = etm.addr_idx;
771 if (!(etm.addr_type[idx] == ETM_ADDR_TYPE_NONE ||
772 etm.addr_type[idx] == ETM_ADDR_TYPE_START)) {
773 mutex_unlock(&etm.mutex);
774 return -EPERM;
775 }
776
777 val = etm.addr_val[idx];
778 mutex_unlock(&etm.mutex);
779 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
780}
781ETM_ATTR(addr_start);
782
783static ssize_t addr_stop_store(struct kobject *kobj,
784 struct kobj_attribute *attr,
785 const char *buf, size_t n)
786{
787 unsigned long val;
788 uint8_t idx;
789
790 if (sscanf(buf, "%lx", &val) != 1)
791 return -EINVAL;
792
793 mutex_lock(&etm.mutex);
794 idx = etm.addr_idx;
795 if (!(etm.addr_type[idx] == ETM_ADDR_TYPE_NONE ||
796 etm.addr_type[idx] == ETM_ADDR_TYPE_STOP)) {
797 mutex_unlock(&etm.mutex);
798 return -EPERM;
799 }
800
801 etm.addr_val[idx] = val;
802 etm.addr_type[idx] = ETM_ADDR_TYPE_STOP;
803 etm.startstop_ctrl |= (1 << (idx + 16));
804 etm.enable_ctrl1 |= BIT(25);
Pratik Patel6630ebe2012-03-06 16:44:22 -0800805 mutex_unlock(&etm.mutex);
806 return n;
807}
808static ssize_t addr_stop_show(struct kobject *kobj,
809 struct kobj_attribute *attr,
810 char *buf)
811{
812 unsigned long val;
813 uint8_t idx;
814
815 mutex_lock(&etm.mutex);
816 idx = etm.addr_idx;
817 if (!(etm.addr_type[idx] == ETM_ADDR_TYPE_NONE ||
818 etm.addr_type[idx] == ETM_ADDR_TYPE_STOP)) {
819 mutex_unlock(&etm.mutex);
820 return -EPERM;
821 }
822
823 val = etm.addr_val[idx];
824 mutex_unlock(&etm.mutex);
825 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
826}
827ETM_ATTR(addr_stop);
828
829static ssize_t addr_acctype_store(struct kobject *kobj,
830 struct kobj_attribute *attr,
831 const char *buf, size_t n)
832{
833 unsigned long val;
834
835 if (sscanf(buf, "%lx", &val) != 1)
836 return -EINVAL;
837
838 mutex_lock(&etm.mutex);
839 etm.addr_acctype[etm.addr_idx] = val;
Pratik Patel6630ebe2012-03-06 16:44:22 -0800840 mutex_unlock(&etm.mutex);
841 return n;
842}
843static ssize_t addr_acctype_show(struct kobject *kobj,
844 struct kobj_attribute *attr,
845 char *buf)
846{
847 unsigned long val;
848
849 mutex_lock(&etm.mutex);
850 val = etm.addr_acctype[etm.addr_idx];
851 mutex_unlock(&etm.mutex);
852 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
853}
854ETM_ATTR(addr_acctype);
855
856static ssize_t cntr_idx_store(struct kobject *kobj,
857 struct kobj_attribute *attr,
858 const char *buf, size_t n)
859{
860 unsigned long val;
861
862 if (sscanf(buf, "%lx", &val) != 1)
863 return -EINVAL;
864 if (val >= etm.nr_cntr)
865 return -EINVAL;
866
867 /* Use mutex to ensure index doesn't change while it gets dereferenced
868 * multiple times within a mutex block elsewhere.
869 */
870 mutex_lock(&etm.mutex);
871 etm.cntr_idx = val;
872 mutex_unlock(&etm.mutex);
873 return n;
874}
875ETM_SHOW(cntr_idx);
876ETM_ATTR(cntr_idx);
877
878static ssize_t cntr_rld_val_store(struct kobject *kobj,
879 struct kobj_attribute *attr,
880 const char *buf, size_t n)
881{
882 unsigned long val;
883
884 if (sscanf(buf, "%lx", &val) != 1)
885 return -EINVAL;
886
887 mutex_lock(&etm.mutex);
888 etm.cntr_rld_val[etm.cntr_idx] = val;
889 mutex_unlock(&etm.mutex);
890 return n;
891}
892static ssize_t cntr_rld_val_show(struct kobject *kobj,
893 struct kobj_attribute *attr,
894 char *buf)
895{
896 unsigned long val;
897 mutex_lock(&etm.mutex);
898 val = etm.cntr_rld_val[etm.cntr_idx];
899 mutex_unlock(&etm.mutex);
900 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
901}
902ETM_ATTR(cntr_rld_val);
903
904static ssize_t cntr_event_store(struct kobject *kobj,
905 struct kobj_attribute *attr,
906 const char *buf, size_t n)
907{
908 unsigned long val;
909
910 if (sscanf(buf, "%lx", &val) != 1)
911 return -EINVAL;
912
913 mutex_lock(&etm.mutex);
914 etm.cntr_event[etm.cntr_idx] = val & ETM_EVENT_MASK;
915 mutex_unlock(&etm.mutex);
916 return n;
917}
918static ssize_t cntr_event_show(struct kobject *kobj,
919 struct kobj_attribute *attr,
920 char *buf)
921{
922 unsigned long val;
923
924 mutex_lock(&etm.mutex);
925 val = etm.cntr_event[etm.cntr_idx];
926 mutex_unlock(&etm.mutex);
927 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
928}
929ETM_ATTR(cntr_event);
930
931static ssize_t cntr_rld_event_store(struct kobject *kobj,
932 struct kobj_attribute *attr,
933 const char *buf, size_t n)
934{
935 unsigned long val;
936
937 if (sscanf(buf, "%lx", &val) != 1)
938 return -EINVAL;
939
940 mutex_lock(&etm.mutex);
941 etm.cntr_rld_event[etm.cntr_idx] = val & ETM_EVENT_MASK;
942 mutex_unlock(&etm.mutex);
943 return n;
944}
945static ssize_t cntr_rld_event_show(struct kobject *kobj,
946 struct kobj_attribute *attr,
947 char *buf)
948{
949 unsigned long val;
950
951 mutex_lock(&etm.mutex);
952 val = etm.cntr_rld_event[etm.cntr_idx];
953 mutex_unlock(&etm.mutex);
954 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
955}
956ETM_ATTR(cntr_rld_event);
957
958static ssize_t cntr_val_store(struct kobject *kobj,
959 struct kobj_attribute *attr,
960 const char *buf, size_t n)
961{
962 unsigned long val;
963
964 if (sscanf(buf, "%lx", &val) != 1)
965 return -EINVAL;
966
967 mutex_lock(&etm.mutex);
968 etm.cntr_val[etm.cntr_idx] = val;
969 mutex_unlock(&etm.mutex);
970 return n;
971}
972static ssize_t cntr_val_show(struct kobject *kobj,
973 struct kobj_attribute *attr,
974 char *buf)
975{
976 unsigned long val;
977
978 mutex_lock(&etm.mutex);
979 val = etm.cntr_val[etm.cntr_idx];
980 mutex_unlock(&etm.mutex);
981 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
982}
983ETM_ATTR(cntr_val);
984
985ETM_STORE(seq_12_event, ETM_EVENT_MASK);
986ETM_SHOW(seq_12_event);
987ETM_ATTR(seq_12_event);
988
989ETM_STORE(seq_21_event, ETM_EVENT_MASK);
990ETM_SHOW(seq_21_event);
991ETM_ATTR(seq_21_event);
992
993ETM_STORE(seq_23_event, ETM_EVENT_MASK);
994ETM_SHOW(seq_23_event);
995ETM_ATTR(seq_23_event);
996
997ETM_STORE(seq_31_event, ETM_EVENT_MASK);
998ETM_SHOW(seq_31_event);
999ETM_ATTR(seq_31_event);
1000
1001ETM_STORE(seq_32_event, ETM_EVENT_MASK);
1002ETM_SHOW(seq_32_event);
1003ETM_ATTR(seq_32_event);
1004
1005ETM_STORE(seq_13_event, ETM_EVENT_MASK);
1006ETM_SHOW(seq_13_event);
1007ETM_ATTR(seq_13_event);
1008
1009static ssize_t seq_curr_state_store(struct kobject *kobj,
1010 struct kobj_attribute *attr,
1011 const char *buf, size_t n)
1012{
1013 unsigned long val;
1014
1015 if (sscanf(buf, "%lx", &val) != 1)
1016 return -EINVAL;
1017 if (val > ETM_SEQ_STATE_MAX_VAL)
1018 return -EINVAL;
1019
1020 etm.seq_curr_state = val;
1021 return n;
1022}
1023ETM_SHOW(seq_curr_state);
1024ETM_ATTR(seq_curr_state);
1025
1026static ssize_t ctxid_idx_store(struct kobject *kobj,
1027 struct kobj_attribute *attr,
1028 const char *buf, size_t n)
1029{
1030 unsigned long val;
1031
1032 if (sscanf(buf, "%lx", &val) != 1)
1033 return -EINVAL;
1034 if (val >= etm.nr_ctxid_cmp)
1035 return -EINVAL;
1036
1037 /* Use mutex to ensure index doesn't change while it gets dereferenced
1038 * multiple times within a mutex block elsewhere.
1039 */
1040 mutex_lock(&etm.mutex);
1041 etm.ctxid_idx = val;
1042 mutex_unlock(&etm.mutex);
1043 return n;
1044}
1045ETM_SHOW(ctxid_idx);
1046ETM_ATTR(ctxid_idx);
1047
1048static ssize_t ctxid_val_store(struct kobject *kobj,
1049 struct kobj_attribute *attr,
1050 const char *buf, size_t n)
1051{
1052 unsigned long val;
1053
1054 if (sscanf(buf, "%lx", &val) != 1)
1055 return -EINVAL;
1056
1057 mutex_lock(&etm.mutex);
1058 etm.ctxid_val[etm.ctxid_idx] = val;
1059 mutex_unlock(&etm.mutex);
1060 return n;
1061}
1062static ssize_t ctxid_val_show(struct kobject *kobj,
1063 struct kobj_attribute *attr,
1064 char *buf)
1065{
1066 unsigned long val;
1067
1068 mutex_lock(&etm.mutex);
1069 val = etm.ctxid_val[etm.ctxid_idx];
1070 mutex_unlock(&etm.mutex);
1071 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
1072}
1073ETM_ATTR(ctxid_val);
1074
1075ETM_STORE(ctxid_mask, ETM_ALL_MASK);
1076ETM_SHOW(ctxid_mask);
1077ETM_ATTR(ctxid_mask);
1078
1079ETM_STORE(sync_freq, ETM_SYNC_MASK);
1080ETM_SHOW(sync_freq);
1081ETM_ATTR(sync_freq);
1082
1083ETM_STORE(timestamp_event, ETM_EVENT_MASK);
1084ETM_SHOW(timestamp_event);
1085ETM_ATTR(timestamp_event);
1086
1087static struct attribute *etm_attrs[] = {
1088 &nr_addr_cmp_attr.attr,
1089 &nr_cntr_attr.attr,
1090 &nr_ctxid_cmp_attr.attr,
Pratik Pateld30deda2012-02-01 14:40:55 -08001091 &reset_attr.attr,
Pratik Patel6630ebe2012-03-06 16:44:22 -08001092 &mode_attr.attr,
1093 &trigger_event_attr.attr,
1094 &enable_event_attr.attr,
1095 &fifofull_level_attr.attr,
1096 &addr_idx_attr.attr,
Pratik Patel6630ebe2012-03-06 16:44:22 -08001097 &addr_single_attr.attr,
1098 &addr_range_attr.attr,
1099 &addr_start_attr.attr,
1100 &addr_stop_attr.attr,
1101 &addr_acctype_attr.attr,
1102 &cntr_idx_attr.attr,
1103 &cntr_rld_val_attr.attr,
1104 &cntr_event_attr.attr,
1105 &cntr_rld_event_attr.attr,
1106 &cntr_val_attr.attr,
1107 &seq_12_event_attr.attr,
1108 &seq_21_event_attr.attr,
1109 &seq_23_event_attr.attr,
1110 &seq_31_event_attr.attr,
1111 &seq_32_event_attr.attr,
1112 &seq_13_event_attr.attr,
1113 &seq_curr_state_attr.attr,
1114 &ctxid_idx_attr.attr,
1115 &ctxid_val_attr.attr,
1116 &ctxid_mask_attr.attr,
1117 &sync_freq_attr.attr,
1118 &timestamp_event_attr.attr,
1119 NULL,
1120};
1121
1122static struct attribute_group etm_attr_grp = {
1123 .attrs = etm_attrs,
1124};
1125
1126static int __init etm_sysfs_init(void)
1127{
1128 int ret;
1129
1130 etm.kobj = kobject_create_and_add("etm", qdss_get_modulekobj());
1131 if (!etm.kobj) {
1132 dev_err(etm.dev, "failed to create ETM sysfs kobject\n");
1133 ret = -ENOMEM;
1134 goto err_create;
1135 }
1136
1137 ret = sysfs_create_file(etm.kobj, &enabled_attr.attr);
1138 if (ret) {
1139 dev_err(etm.dev, "failed to create ETM sysfs enabled"
1140 " attribute\n");
1141 goto err_file;
1142 }
1143
1144 if (sysfs_create_group(etm.kobj, &etm_attr_grp))
1145 dev_err(etm.dev, "failed to create ETM sysfs group\n");
1146
1147 return 0;
1148err_file:
1149 kobject_put(etm.kobj);
1150err_create:
1151 return ret;
1152}
1153
1154static void etm_sysfs_exit(void)
1155{
1156 sysfs_remove_group(etm.kobj, &etm_attr_grp);
1157 sysfs_remove_file(etm.kobj, &enabled_attr.attr);
1158 kobject_put(etm.kobj);
1159}
1160
Pratik Patel61de7302012-03-07 12:06:10 -08001161static bool etm_arch_supported(uint8_t arch)
Pratik Patel7831c082011-06-08 21:44:37 -07001162{
Pratik Patel61de7302012-03-07 12:06:10 -08001163 switch (arch) {
1164 case PFT_ARCH_V1_1:
1165 break;
1166 default:
1167 return false;
1168 }
1169 return true;
1170}
1171
1172static int __init etm_arch_init(void)
1173{
Pratik Patel2d0c7b62012-02-24 19:04:37 -08001174 int ret, i;
Pratik Patel7831c082011-06-08 21:44:37 -07001175 /* use cpu 0 for setup */
1176 int cpu = 0;
Pratik Patel61de7302012-03-07 12:06:10 -08001177 uint32_t etmidr;
1178 uint32_t etmccr;
Pratik Patel7831c082011-06-08 21:44:37 -07001179
Pratik Patel17f3b822011-11-21 12:41:47 -08001180 /* Unlock OS lock first to allow memory mapped reads and writes */
Pratik Patel492b3012012-03-06 14:22:30 -08001181 etm_os_unlock(NULL);
1182 smp_call_function(etm_os_unlock, NULL, 1);
1183 ETM_UNLOCK(cpu);
Pratik Patel17f3b822011-11-21 12:41:47 -08001184 /* Vote for ETM power/clock enable */
Pratik Patel61de7302012-03-07 12:06:10 -08001185 etm_clr_pwrdwn(cpu);
1186 /* Set prog bit. It will be set from reset but this is included to
1187 * ensure it is set
1188 */
Pratik Patel492b3012012-03-06 14:22:30 -08001189 etm_set_prog(cpu);
Pratik Patel7831c082011-06-08 21:44:37 -07001190
1191 /* find all capabilities */
Pratik Patel61de7302012-03-07 12:06:10 -08001192 etmidr = etm_readl(etm, cpu, ETMIDR);
1193 etm.arch = BMVAL(etmidr, 4, 11);
1194 if (etm_arch_supported(etm.arch) == false) {
1195 ret = -EINVAL;
1196 goto err;
1197 }
Pratik Patel7831c082011-06-08 21:44:37 -07001198
Pratik Patel61de7302012-03-07 12:06:10 -08001199 etmccr = etm_readl(etm, cpu, ETMCCR);
1200 etm.nr_addr_cmp = BMVAL(etmccr, 0, 3) * 2;
1201 etm.nr_cntr = BMVAL(etmccr, 13, 15);
1202 etm.nr_ext_inp = BMVAL(etmccr, 17, 19);
1203 etm.nr_ext_out = BMVAL(etmccr, 20, 22);
1204 etm.nr_ctxid_cmp = BMVAL(etmccr, 24, 25);
Pratik Patel7831c082011-06-08 21:44:37 -07001205
Pratik Patel2d0c7b62012-02-24 19:04:37 -08001206 if (cpu_is_krait_v1()) {
1207 /* Krait pass1 doesn't support include filtering and non-cycle
1208 * accurate tracing
1209 */
1210 etm.mode = (ETM_MODE_EXCLUDE | ETM_MODE_CYCACC);
1211 etm.ctrl = 0x1000;
1212 etm.enable_ctrl1 = 0x1000000;
1213 for (i = 0; i < etm.nr_addr_cmp; i++) {
1214 etm.addr_val[i] = 0x0;
1215 etm.addr_acctype[i] = 0x0;
1216 etm.addr_type[i] = ETM_ADDR_TYPE_NONE;
1217 }
1218 }
1219
Pratik Patel17f3b822011-11-21 12:41:47 -08001220 /* Vote for ETM power/clock disable */
Pratik Patel61de7302012-03-07 12:06:10 -08001221 etm_set_pwrdwn(cpu);
Pratik Patel492b3012012-03-06 14:22:30 -08001222 ETM_LOCK(cpu);
Pratik Patel61de7302012-03-07 12:06:10 -08001223
1224 return 0;
1225err:
1226 return ret;
Pratik Patel7831c082011-06-08 21:44:37 -07001227}
1228
Pratik Patel492b3012012-03-06 14:22:30 -08001229static int __devinit etm_probe(struct platform_device *pdev)
Pratik Patel7831c082011-06-08 21:44:37 -07001230{
Pratik Patele5771792011-09-17 18:33:54 -07001231 int ret;
Pratik Patel7831c082011-06-08 21:44:37 -07001232 struct resource *res;
1233
1234 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1235 if (!res) {
1236 ret = -EINVAL;
1237 goto err_res;
1238 }
1239
Pratik Patel492b3012012-03-06 14:22:30 -08001240 etm.base = ioremap_nocache(res->start, resource_size(res));
1241 if (!etm.base) {
Pratik Patel7831c082011-06-08 21:44:37 -07001242 ret = -EINVAL;
1243 goto err_ioremap;
1244 }
1245
Pratik Patel492b3012012-03-06 14:22:30 -08001246 etm.dev = &pdev->dev;
Pratik Patel7831c082011-06-08 21:44:37 -07001247
Pratik Patel6630ebe2012-03-06 16:44:22 -08001248 mutex_init(&etm.mutex);
Pratik Patel61de7302012-03-07 12:06:10 -08001249 wake_lock_init(&etm.wake_lock, WAKE_LOCK_SUSPEND, "msm_etm");
1250 pm_qos_add_request(&etm.qos_req, PM_QOS_CPU_DMA_LATENCY,
1251 PM_QOS_DEFAULT_VALUE);
Pratik Patelcc320a42011-12-22 10:48:14 -08001252 ret = qdss_clk_enable();
Pratik Patel7831c082011-06-08 21:44:37 -07001253 if (ret)
Pratik Patelcc320a42011-12-22 10:48:14 -08001254 goto err_clk;
Pratik Patel7831c082011-06-08 21:44:37 -07001255
Pratik Patel61de7302012-03-07 12:06:10 -08001256 ret = etm_arch_init();
1257 if (ret)
1258 goto err_arch;
Pratik Patel7831c082011-06-08 21:44:37 -07001259
Pratik Patel6630ebe2012-03-06 16:44:22 -08001260 ret = etm_sysfs_init();
1261 if (ret)
1262 goto err_sysfs;
1263
Pratik Patel61de7302012-03-07 12:06:10 -08001264 etm.enabled = false;
Pratik Patel7831c082011-06-08 21:44:37 -07001265
Pratik Patelcc320a42011-12-22 10:48:14 -08001266 qdss_clk_disable();
Pratik Patel7831c082011-06-08 21:44:37 -07001267
Pratik Patel61de7302012-03-07 12:06:10 -08001268 dev_info(etm.dev, "ETM initialized\n");
Pratik Patel7831c082011-06-08 21:44:37 -07001269
Pratik Patel61de7302012-03-07 12:06:10 -08001270 if (etm_boot_enable)
1271 etm_enable();
Pratik Patel7831c082011-06-08 21:44:37 -07001272
1273 return 0;
1274
Pratik Patel6630ebe2012-03-06 16:44:22 -08001275err_sysfs:
Pratik Patel61de7302012-03-07 12:06:10 -08001276err_arch:
1277 qdss_clk_disable();
Pratik Patelcc320a42011-12-22 10:48:14 -08001278err_clk:
Pratik Patel61de7302012-03-07 12:06:10 -08001279 pm_qos_remove_request(&etm.qos_req);
1280 wake_lock_destroy(&etm.wake_lock);
Pratik Patel6630ebe2012-03-06 16:44:22 -08001281 mutex_destroy(&etm.mutex);
Pratik Patel492b3012012-03-06 14:22:30 -08001282 iounmap(etm.base);
Pratik Patel7831c082011-06-08 21:44:37 -07001283err_ioremap:
1284err_res:
Pratik Patel61de7302012-03-07 12:06:10 -08001285 dev_err(etm.dev, "ETM init failed\n");
Pratik Patel7831c082011-06-08 21:44:37 -07001286 return ret;
1287}
1288
Pratik Patel492b3012012-03-06 14:22:30 -08001289static int etm_remove(struct platform_device *pdev)
Pratik Patel7831c082011-06-08 21:44:37 -07001290{
Pratik Patel61de7302012-03-07 12:06:10 -08001291 if (etm.enabled)
1292 etm_disable();
Pratik Patel6630ebe2012-03-06 16:44:22 -08001293 etm_sysfs_exit();
Pratik Patel492b3012012-03-06 14:22:30 -08001294 pm_qos_remove_request(&etm.qos_req);
1295 wake_lock_destroy(&etm.wake_lock);
Pratik Patel6630ebe2012-03-06 16:44:22 -08001296 mutex_destroy(&etm.mutex);
Pratik Patel492b3012012-03-06 14:22:30 -08001297 iounmap(etm.base);
Pratik Patel7831c082011-06-08 21:44:37 -07001298
1299 return 0;
1300}
1301
Pratik Patel492b3012012-03-06 14:22:30 -08001302static struct platform_driver etm_driver = {
1303 .probe = etm_probe,
1304 .remove = etm_remove,
Pratik Patel7831c082011-06-08 21:44:37 -07001305 .driver = {
Pratik Patel492b3012012-03-06 14:22:30 -08001306 .name = "msm_etm",
Pratik Patel7831c082011-06-08 21:44:37 -07001307 },
1308};
1309
Pratik Patel492b3012012-03-06 14:22:30 -08001310int __init etm_init(void)
Pratik Patel7831c082011-06-08 21:44:37 -07001311{
Pratik Patel492b3012012-03-06 14:22:30 -08001312 return platform_driver_register(&etm_driver);
Pratik Patel7831c082011-06-08 21:44:37 -07001313}
Pratik Patel7831c082011-06-08 21:44:37 -07001314
Pratik Patel492b3012012-03-06 14:22:30 -08001315void etm_exit(void)
Pratik Patel7831c082011-06-08 21:44:37 -07001316{
Pratik Patel492b3012012-03-06 14:22:30 -08001317 platform_driver_unregister(&etm_driver);
Pratik Patel7831c082011-06-08 21:44:37 -07001318}