blob: 5ee32c64b9861522d71a290785905f27d52ceacf [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 Patel7831c082011-06-08 21:44:37 -070029
30#include "qdss.h"
31
Pratik Patel492b3012012-03-06 14:22:30 -080032#define etm_writel(etm, cpu, val, off) \
33 __raw_writel((val), etm.base + (SZ_4K * cpu) + off)
34#define etm_readl(etm, cpu, off) \
35 __raw_readl(etm.base + (SZ_4K * cpu) + off)
Pratik Patel7831c082011-06-08 21:44:37 -070036
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)
Pratik Pateld5bbc762012-01-29 14:13:21 -080069#define ETMSQ31EVR (0x18C)
70#define ETMSQ32EVR (0x190)
71#define ETMSQ13EVR (0x194)
Pratik Patel7831c082011-06-08 21:44:37 -070072#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)
Pratik Pateld5bbc762012-01-29 14:13:21 -080093#define ETMVMIDCVR (0x240)
Pratik Patel7831c082011-06-08 21:44:37 -070094/* 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
Pratik Patel61de7302012-03-07 12:06:10 -0800101#define ETM_MAX_ADDR_CMP (16)
102#define ETM_MAX_CNTR (4)
103#define ETM_MAX_CTXID_CMP (3)
104
Pratik Patel6630ebe2012-03-06 16:44:22 -0800105#define ETM_MODE_EXCLUDE BIT(0)
106#define ETM_MODE_CYCACC BIT(1)
107#define ETM_MODE_STALL BIT(2)
108#define ETM_MODE_TIMESTAMP BIT(3)
109#define ETM_MODE_CTXID BIT(4)
110#define ETM_MODE_ALL (0x1F)
111
112#define ETM_EVENT_MASK (0x1FFFF)
113#define ETM_SYNC_MASK (0xFFF)
114#define ETM_ALL_MASK (0xFFFFFFFF)
115
116#define ETM_SEQ_STATE_MAX_VAL (0x2)
117
118enum {
119 ETM_ADDR_TYPE_NONE,
120 ETM_ADDR_TYPE_SINGLE,
121 ETM_ADDR_TYPE_RANGE,
122 ETM_ADDR_TYPE_START,
123 ETM_ADDR_TYPE_STOP,
124};
125
Pratik Patel492b3012012-03-06 14:22:30 -0800126#define ETM_LOCK(cpu) \
Pratik Patel7831c082011-06-08 21:44:37 -0700127do { \
128 mb(); \
Pratik Patel492b3012012-03-06 14:22:30 -0800129 etm_writel(etm, cpu, 0x0, CS_LAR); \
Pratik Patel7831c082011-06-08 21:44:37 -0700130} while (0)
Pratik Patel492b3012012-03-06 14:22:30 -0800131#define ETM_UNLOCK(cpu) \
Pratik Patel7831c082011-06-08 21:44:37 -0700132do { \
Pratik Patel492b3012012-03-06 14:22:30 -0800133 etm_writel(etm, cpu, CS_UNLOCK_MAGIC, CS_LAR); \
Pratik Patel7831c082011-06-08 21:44:37 -0700134 mb(); \
135} while (0)
136
Pratik Patel7831c082011-06-08 21:44:37 -0700137
Pratik Patel6630ebe2012-03-06 16:44:22 -0800138#ifdef MODULE_PARAM_PREFIX
139#undef MODULE_PARAM_PREFIX
140#endif
141#define MODULE_PARAM_PREFIX "qdss."
142
Pratik Patel29cba152012-01-03 11:40:26 -0800143#ifdef CONFIG_MSM_QDSS_ETM_DEFAULT_ENABLE
Pratik Patel61de7302012-03-07 12:06:10 -0800144static int etm_boot_enable = 1;
Pratik Patel29cba152012-01-03 11:40:26 -0800145#else
Pratik Patel61de7302012-03-07 12:06:10 -0800146static int etm_boot_enable;
Pratik Patel29cba152012-01-03 11:40:26 -0800147#endif
Pratik Patel7831c082011-06-08 21:44:37 -0700148module_param_named(
Pratik Patel61de7302012-03-07 12:06:10 -0800149 etm_boot_enable, etm_boot_enable, int, S_IRUGO
Pratik Patel7831c082011-06-08 21:44:37 -0700150);
151
Pratik Patel492b3012012-03-06 14:22:30 -0800152struct etm_ctx {
Pratik Patel7831c082011-06-08 21:44:37 -0700153 void __iomem *base;
Pratik Patel61de7302012-03-07 12:06:10 -0800154 bool enabled;
Pratik Patel7831c082011-06-08 21:44:37 -0700155 struct wake_lock wake_lock;
156 struct pm_qos_request_list qos_req;
Pratik Patel6630ebe2012-03-06 16:44:22 -0800157 struct mutex mutex;
Pratik Patel7831c082011-06-08 21:44:37 -0700158 struct device *dev;
Pratik Patel6630ebe2012-03-06 16:44:22 -0800159 struct kobject *kobj;
Pratik Patel61de7302012-03-07 12:06:10 -0800160 uint8_t arch;
161 uint8_t nr_addr_cmp;
162 uint8_t nr_cntr;
163 uint8_t nr_ext_inp;
164 uint8_t nr_ext_out;
165 uint8_t nr_ctxid_cmp;
Pratik Patel6630ebe2012-03-06 16:44:22 -0800166 uint32_t mode;
Pratik Patel61de7302012-03-07 12:06:10 -0800167 uint32_t ctrl;
168 uint32_t trigger_event;
169 uint32_t startstop_ctrl;
170 uint32_t enable_event;
171 uint32_t enable_ctrl1;
172 uint32_t fifofull_level;
Pratik Patel6630ebe2012-03-06 16:44:22 -0800173 uint8_t addr_idx;
174 uint8_t addr_reset;
Pratik Patel61de7302012-03-07 12:06:10 -0800175 uint32_t addr_val[ETM_MAX_ADDR_CMP];
176 uint32_t addr_acctype[ETM_MAX_ADDR_CMP];
Pratik Patel6630ebe2012-03-06 16:44:22 -0800177 uint32_t addr_type[ETM_MAX_ADDR_CMP];
178 uint8_t cntr_idx;
Pratik Patel61de7302012-03-07 12:06:10 -0800179 uint32_t cntr_rld_val[ETM_MAX_CNTR];
180 uint32_t cntr_event[ETM_MAX_CNTR];
181 uint32_t cntr_rld_event[ETM_MAX_CNTR];
182 uint32_t cntr_val[ETM_MAX_CNTR];
183 uint32_t seq_12_event;
184 uint32_t seq_21_event;
185 uint32_t seq_23_event;
186 uint32_t seq_31_event;
187 uint32_t seq_32_event;
188 uint32_t seq_13_event;
189 uint32_t seq_curr_state;
Pratik Patel6630ebe2012-03-06 16:44:22 -0800190 uint8_t ctxid_idx;
Pratik Patel61de7302012-03-07 12:06:10 -0800191 uint32_t ctxid_val[ETM_MAX_CTXID_CMP];
192 uint32_t ctxid_mask;
193 uint32_t sync_freq;
194 uint32_t timestamp_event;
Pratik Patel7831c082011-06-08 21:44:37 -0700195};
196
Pratik Patel61de7302012-03-07 12:06:10 -0800197static struct etm_ctx etm = {
Pratik Patel6630ebe2012-03-06 16:44:22 -0800198 .mode = 0x3,
Pratik Patel61de7302012-03-07 12:06:10 -0800199 .ctrl = 0x1000,
200 .trigger_event = 0x406F,
201 .enable_event = 0x6F,
202 .enable_ctrl1 = 0x1000000,
203 .fifofull_level = 0x28,
Pratik Patel6630ebe2012-03-06 16:44:22 -0800204 .addr_reset = 0x1,
Pratik Patel61de7302012-03-07 12:06:10 -0800205 .cntr_event = {[0 ... (ETM_MAX_CNTR - 1)] = 0x406F},
206 .cntr_rld_event = {[0 ... (ETM_MAX_CNTR - 1)] = 0x406F},
207 .seq_12_event = 0x406F,
208 .seq_21_event = 0x406F,
209 .seq_23_event = 0x406F,
210 .seq_31_event = 0x406F,
211 .seq_32_event = 0x406F,
212 .seq_13_event = 0x406F,
213 .sync_freq = 0x80,
214 .timestamp_event = 0x406F,
215};
Pratik Patel7831c082011-06-08 21:44:37 -0700216
Pratik Patel7831c082011-06-08 21:44:37 -0700217
Pratik Patel17f3b822011-11-21 12:41:47 -0800218/* ETM clock is derived from the processor clock and gets enabled on a
219 * logical OR of below items on Krait (pass2 onwards):
220 * 1.CPMR[ETMCLKEN] is 1
221 * 2.ETMCR[PD] is 0
222 * 3.ETMPDCR[PU] is 1
223 * 4.Reset is asserted (core or debug)
224 * 5.APB memory mapped requests (eg. EDAP access)
225 *
226 * 1., 2. and 3. above are permanent enables whereas 4. and 5. are temporary
227 * enables
228 *
229 * We rely on 5. to be able to access ETMCR and then use 2. above for ETM
230 * clock vote in the driver and the save-restore code uses 1. above
231 * for its vote
232 */
Pratik Patel61de7302012-03-07 12:06:10 -0800233static void etm_set_pwrdwn(int cpu)
Pratik Patel7831c082011-06-08 21:44:37 -0700234{
235 uint32_t etmcr;
236
Pratik Patel492b3012012-03-06 14:22:30 -0800237 etmcr = etm_readl(etm, cpu, ETMCR);
Pratik Patel7831c082011-06-08 21:44:37 -0700238 etmcr |= BIT(0);
Pratik Patel492b3012012-03-06 14:22:30 -0800239 etm_writel(etm, cpu, etmcr, ETMCR);
Pratik Patel7831c082011-06-08 21:44:37 -0700240}
241
Pratik Patel61de7302012-03-07 12:06:10 -0800242static void etm_clr_pwrdwn(int cpu)
Pratik Patel7831c082011-06-08 21:44:37 -0700243{
244 uint32_t etmcr;
245
Pratik Patel492b3012012-03-06 14:22:30 -0800246 etmcr = etm_readl(etm, cpu, ETMCR);
Pratik Patel7831c082011-06-08 21:44:37 -0700247 etmcr &= ~BIT(0);
Pratik Patel492b3012012-03-06 14:22:30 -0800248 etm_writel(etm, cpu, etmcr, ETMCR);
Pratik Patel7831c082011-06-08 21:44:37 -0700249}
250
Pratik Patel492b3012012-03-06 14:22:30 -0800251static void etm_set_prog(int cpu)
Pratik Patel7831c082011-06-08 21:44:37 -0700252{
253 uint32_t etmcr;
254 int count;
255
Pratik Patel492b3012012-03-06 14:22:30 -0800256 etmcr = etm_readl(etm, cpu, ETMCR);
Pratik Patel7831c082011-06-08 21:44:37 -0700257 etmcr |= BIT(10);
Pratik Patel492b3012012-03-06 14:22:30 -0800258 etm_writel(etm, cpu, etmcr, ETMCR);
Pratik Patel7831c082011-06-08 21:44:37 -0700259
Pratik Patel492b3012012-03-06 14:22:30 -0800260 for (count = TIMEOUT_US; BVAL(etm_readl(etm, cpu, ETMSR), 1) != 1
Pratik Patel7831c082011-06-08 21:44:37 -0700261 && count > 0; count--)
262 udelay(1);
Pratik Patel61de7302012-03-07 12:06:10 -0800263 WARN(count == 0, "timeout while setting prog bit, ETMSR: %#x\n",
264 etm_readl(etm, cpu, ETMSR));
Pratik Patel7831c082011-06-08 21:44:37 -0700265}
266
Pratik Patel61de7302012-03-07 12:06:10 -0800267static void etm_clr_prog(int cpu)
Pratik Patel7831c082011-06-08 21:44:37 -0700268{
269 uint32_t etmcr;
270 int count;
271
Pratik Patel492b3012012-03-06 14:22:30 -0800272 etmcr = etm_readl(etm, cpu, ETMCR);
Pratik Patel7831c082011-06-08 21:44:37 -0700273 etmcr &= ~BIT(10);
Pratik Patel492b3012012-03-06 14:22:30 -0800274 etm_writel(etm, cpu, etmcr, ETMCR);
Pratik Patel7831c082011-06-08 21:44:37 -0700275
Pratik Patel492b3012012-03-06 14:22:30 -0800276 for (count = TIMEOUT_US; BVAL(etm_readl(etm, cpu, ETMSR), 1) != 0
Pratik Patel7831c082011-06-08 21:44:37 -0700277 && count > 0; count--)
278 udelay(1);
Pratik Patel61de7302012-03-07 12:06:10 -0800279 WARN(count == 0, "timeout while clearing prog bit, ETMSR: %#x\n",
280 etm_readl(etm, cpu, ETMSR));
Pratik Patel7831c082011-06-08 21:44:37 -0700281}
282
Pratik Patel61de7302012-03-07 12:06:10 -0800283static void __etm_enable(int cpu)
Pratik Patel7831c082011-06-08 21:44:37 -0700284{
Pratik Patel17f3b822011-11-21 12:41:47 -0800285 int i;
Pratik Patel7831c082011-06-08 21:44:37 -0700286
Pratik Patel492b3012012-03-06 14:22:30 -0800287 ETM_UNLOCK(cpu);
Pratik Patel17f3b822011-11-21 12:41:47 -0800288 /* Vote for ETM power/clock enable */
Pratik Patel61de7302012-03-07 12:06:10 -0800289 etm_clr_pwrdwn(cpu);
Pratik Patel492b3012012-03-06 14:22:30 -0800290 etm_set_prog(cpu);
Pratik Patel7831c082011-06-08 21:44:37 -0700291
Pratik Patel61de7302012-03-07 12:06:10 -0800292 etm_writel(etm, cpu, etm.ctrl | BIT(10), ETMCR);
293 etm_writel(etm, cpu, etm.trigger_event, ETMTRIGGER);
294 etm_writel(etm, cpu, etm.startstop_ctrl, ETMTSSCR);
295 etm_writel(etm, cpu, etm.enable_event, ETMTEEVR);
296 etm_writel(etm, cpu, etm.enable_ctrl1, ETMTECR1);
297 etm_writel(etm, cpu, etm.fifofull_level, ETMFFLR);
298 for (i = 0; i < etm.nr_addr_cmp; i++) {
299 etm_writel(etm, cpu, etm.addr_val[i], ETMACVRn(i));
300 etm_writel(etm, cpu, etm.addr_acctype[i], ETMACTRn(i));
Pratik Patel7831c082011-06-08 21:44:37 -0700301 }
Pratik Patel61de7302012-03-07 12:06:10 -0800302 for (i = 0; i < etm.nr_cntr; i++) {
303 etm_writel(etm, cpu, etm.cntr_rld_val[i], ETMCNTRLDVRn(i));
304 etm_writel(etm, cpu, etm.cntr_event[i], ETMCNTENRn(i));
305 etm_writel(etm, cpu, etm.cntr_rld_event[i], ETMCNTRLDEVRn(i));
306 etm_writel(etm, cpu, etm.cntr_val[i], ETMCNTVRn(i));
Pratik Patel17f3b822011-11-21 12:41:47 -0800307 }
Pratik Patel61de7302012-03-07 12:06:10 -0800308 etm_writel(etm, cpu, etm.seq_12_event, ETMSQ12EVR);
309 etm_writel(etm, cpu, etm.seq_21_event, ETMSQ21EVR);
310 etm_writel(etm, cpu, etm.seq_23_event, ETMSQ23EVR);
311 etm_writel(etm, cpu, etm.seq_31_event, ETMSQ31EVR);
312 etm_writel(etm, cpu, etm.seq_32_event, ETMSQ32EVR);
313 etm_writel(etm, cpu, etm.seq_13_event, ETMSQ13EVR);
314 etm_writel(etm, cpu, etm.seq_curr_state, ETMSQR);
315 for (i = 0; i < etm.nr_ext_out; i++)
316 etm_writel(etm, cpu, 0x0000406F, ETMEXTOUTEVRn(i));
317 for (i = 0; i < etm.nr_ctxid_cmp; i++)
318 etm_writel(etm, cpu, etm.ctxid_val[i], ETMCIDCVRn(i));
319 etm_writel(etm, cpu, etm.ctxid_mask, ETMCIDCMR);
320 etm_writel(etm, cpu, etm.sync_freq, ETMSYNCFR);
321 etm_writel(etm, cpu, 0x00000000, ETMEXTINSELR);
322 etm_writel(etm, cpu, etm.timestamp_event, ETMTSEVR);
323 etm_writel(etm, cpu, 0x00000000, ETMAUXCR);
Pratik Patel492b3012012-03-06 14:22:30 -0800324 etm_writel(etm, cpu, cpu+1, ETMTRACEIDR);
Pratik Patel61de7302012-03-07 12:06:10 -0800325 etm_writel(etm, cpu, 0x00000000, ETMVMIDCVR);
Pratik Patel17f3b822011-11-21 12:41:47 -0800326
Pratik Patel61de7302012-03-07 12:06:10 -0800327 etm_clr_prog(cpu);
Pratik Patel492b3012012-03-06 14:22:30 -0800328 ETM_LOCK(cpu);
Pratik Patel7831c082011-06-08 21:44:37 -0700329}
330
Pratik Patel61de7302012-03-07 12:06:10 -0800331static int etm_enable(void)
Pratik Patel7831c082011-06-08 21:44:37 -0700332{
Pratik Patel17f3b822011-11-21 12:41:47 -0800333 int ret, cpu;
Pratik Patel7831c082011-06-08 21:44:37 -0700334
Pratik Patel61de7302012-03-07 12:06:10 -0800335 if (etm.enabled) {
336 dev_err(etm.dev, "ETM tracing already enabled\n");
337 ret = -EPERM;
338 goto err;
339 }
340
Pratik Patelcc320a42011-12-22 10:48:14 -0800341 ret = qdss_clk_enable();
Pratik Patel7831c082011-06-08 21:44:37 -0700342 if (ret)
Pratik Patel61de7302012-03-07 12:06:10 -0800343 goto err;
Pratik Patel7831c082011-06-08 21:44:37 -0700344
Pratik Patel492b3012012-03-06 14:22:30 -0800345 wake_lock(&etm.wake_lock);
Pratik Patele5771792011-09-17 18:33:54 -0700346 /* 1. causes all online cpus to come out of idle PC
Pratik Patel7831c082011-06-08 21:44:37 -0700347 * 2. prevents idle PC until save restore flag is enabled atomically
Pratik Patele5771792011-09-17 18:33:54 -0700348 *
349 * we rely on the user to prevent hotplug on/off racing with this
350 * operation and to ensure cores where trace is expected to be turned
351 * on are already hotplugged on
Pratik Patel7831c082011-06-08 21:44:37 -0700352 */
Pratik Patel492b3012012-03-06 14:22:30 -0800353 pm_qos_update_request(&etm.qos_req, 0);
Pratik Patel7831c082011-06-08 21:44:37 -0700354
355 etb_disable();
356 tpiu_disable();
357 /* enable ETB first to avoid loosing any trace data */
358 etb_enable();
359 funnel_enable(0x0, 0x3);
Pratik Patel17f3b822011-11-21 12:41:47 -0800360 for_each_online_cpu(cpu)
Pratik Patel61de7302012-03-07 12:06:10 -0800361 __etm_enable(cpu);
Pratik Patel7831c082011-06-08 21:44:37 -0700362
Pratik Patel61de7302012-03-07 12:06:10 -0800363 etm.enabled = true;
Pratik Patel7831c082011-06-08 21:44:37 -0700364
Pratik Patel492b3012012-03-06 14:22:30 -0800365 pm_qos_update_request(&etm.qos_req, PM_QOS_DEFAULT_VALUE);
366 wake_unlock(&etm.wake_lock);
Pratik Patel7831c082011-06-08 21:44:37 -0700367
Pratik Patel61de7302012-03-07 12:06:10 -0800368 dev_info(etm.dev, "ETM tracing enabled\n");
Pratik Patel7831c082011-06-08 21:44:37 -0700369 return 0;
Pratik Patel61de7302012-03-07 12:06:10 -0800370err:
371 return ret;
Pratik Patel7831c082011-06-08 21:44:37 -0700372}
373
Pratik Patel61de7302012-03-07 12:06:10 -0800374static void __etm_disable(int cpu)
Pratik Patel7831c082011-06-08 21:44:37 -0700375{
Pratik Patel492b3012012-03-06 14:22:30 -0800376 ETM_UNLOCK(cpu);
377 etm_set_prog(cpu);
Pratik Patel7831c082011-06-08 21:44:37 -0700378
Pratik Patel17f3b822011-11-21 12:41:47 -0800379 /* program trace enable to low by using always false event */
Pratik Patel492b3012012-03-06 14:22:30 -0800380 etm_writel(etm, cpu, 0x6F | BIT(14), ETMTEEVR);
Pratik Patel7831c082011-06-08 21:44:37 -0700381
Pratik Patel17f3b822011-11-21 12:41:47 -0800382 /* Vote for ETM power/clock disable */
Pratik Patel61de7302012-03-07 12:06:10 -0800383 etm_set_pwrdwn(cpu);
Pratik Patel492b3012012-03-06 14:22:30 -0800384 ETM_LOCK(cpu);
Pratik Patel7831c082011-06-08 21:44:37 -0700385}
386
Pratik Patel61de7302012-03-07 12:06:10 -0800387static int etm_disable(void)
Pratik Patel7831c082011-06-08 21:44:37 -0700388{
Pratik Patel61de7302012-03-07 12:06:10 -0800389 int ret, cpu;
390
391 if (!etm.enabled) {
392 dev_err(etm.dev, "ETM tracing already disabled\n");
393 ret = -EPERM;
394 goto err;
395 }
Pratik Patel17f3b822011-11-21 12:41:47 -0800396
Pratik Patel492b3012012-03-06 14:22:30 -0800397 wake_lock(&etm.wake_lock);
Pratik Patele5771792011-09-17 18:33:54 -0700398 /* 1. causes all online cpus to come out of idle PC
Pratik Patel7831c082011-06-08 21:44:37 -0700399 * 2. prevents idle PC until save restore flag is disabled atomically
Pratik Patele5771792011-09-17 18:33:54 -0700400 *
401 * we rely on the user to prevent hotplug on/off racing with this
402 * operation and to ensure cores where trace is expected to be turned
403 * off are already hotplugged on
Pratik Patel7831c082011-06-08 21:44:37 -0700404 */
Pratik Patel492b3012012-03-06 14:22:30 -0800405 pm_qos_update_request(&etm.qos_req, 0);
Pratik Patel7831c082011-06-08 21:44:37 -0700406
Pratik Patel17f3b822011-11-21 12:41:47 -0800407 for_each_online_cpu(cpu)
Pratik Patel61de7302012-03-07 12:06:10 -0800408 __etm_disable(cpu);
Pratik Patel7831c082011-06-08 21:44:37 -0700409 etb_dump();
410 etb_disable();
411 funnel_disable(0x0, 0x3);
412
Pratik Patel61de7302012-03-07 12:06:10 -0800413 etm.enabled = false;
Pratik Patel7831c082011-06-08 21:44:37 -0700414
Pratik Patel492b3012012-03-06 14:22:30 -0800415 pm_qos_update_request(&etm.qos_req, PM_QOS_DEFAULT_VALUE);
416 wake_unlock(&etm.wake_lock);
Pratik Patel7831c082011-06-08 21:44:37 -0700417
Pratik Patelcc320a42011-12-22 10:48:14 -0800418 qdss_clk_disable();
Pratik Patel61de7302012-03-07 12:06:10 -0800419
420 dev_info(etm.dev, "ETM tracing disabled\n");
421 return 0;
422err:
423 return ret;
Pratik Patel7831c082011-06-08 21:44:37 -0700424}
425
Pratik Patel17f3b822011-11-21 12:41:47 -0800426/* Memory mapped writes to clear os lock not supported */
Pratik Patel492b3012012-03-06 14:22:30 -0800427static void etm_os_unlock(void *unused)
Pratik Patel17f3b822011-11-21 12:41:47 -0800428{
429 unsigned long value = 0x0;
430
431 asm("mcr p14, 1, %0, c1, c0, 4\n\t" : : "r" (value));
432 asm("isb\n\t");
433}
434
Pratik Patel6630ebe2012-03-06 16:44:22 -0800435#define ETM_STORE(__name, mask) \
436static ssize_t __name##_store(struct kobject *kobj, \
437 struct kobj_attribute *attr, \
438 const char *buf, size_t n) \
439{ \
440 unsigned long val; \
441 \
442 if (sscanf(buf, "%lx", &val) != 1) \
443 return -EINVAL; \
444 \
445 etm.__name = val & mask; \
446 return n; \
447}
448
449#define ETM_SHOW(__name) \
450static ssize_t __name##_show(struct kobject *kobj, \
451 struct kobj_attribute *attr, \
452 char *buf) \
453{ \
454 unsigned long val = etm.__name; \
455 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val); \
456}
457
458#define ETM_ATTR(__name) \
459static struct kobj_attribute __name##_attr = \
460 __ATTR(__name, S_IRUGO | S_IWUSR, __name##_show, __name##_store)
461#define ETM_ATTR_RO(__name) \
462static struct kobj_attribute __name##_attr = \
463 __ATTR(__name, S_IRUGO, __name##_show, NULL)
464
465static ssize_t enabled_store(struct kobject *kobj,
466 struct kobj_attribute *attr,
467 const char *buf, size_t n)
468{
469 int ret = 0;
470 unsigned long val;
471
472 if (sscanf(buf, "%lx", &val) != 1)
473 return -EINVAL;
474
475 mutex_lock(&etm.mutex);
476 if (val)
477 ret = etm_enable();
478 else
479 ret = etm_disable();
480 mutex_unlock(&etm.mutex);
481
482 if (ret)
483 return ret;
484 return n;
485}
486ETM_SHOW(enabled);
487ETM_ATTR(enabled);
488
489ETM_SHOW(nr_addr_cmp);
490ETM_ATTR_RO(nr_addr_cmp);
491ETM_SHOW(nr_cntr);
492ETM_ATTR_RO(nr_cntr);
493ETM_SHOW(nr_ctxid_cmp);
494ETM_ATTR_RO(nr_ctxid_cmp);
495
496static ssize_t mode_store(struct kobject *kobj,
497 struct kobj_attribute *attr,
498 const char *buf, size_t n)
499{
500 unsigned long val;
501
502 if (sscanf(buf, "%lx", &val) != 1)
503 return -EINVAL;
504
505 mutex_lock(&etm.mutex);
506 etm.mode = val & ETM_MODE_ALL;
507
508 if (etm.mode & ETM_MODE_EXCLUDE)
509 etm.enable_ctrl1 |= BIT(24);
510 else
511 etm.enable_ctrl1 &= ~BIT(24);
512
513 if (etm.mode & ETM_MODE_CYCACC)
514 etm.ctrl |= BIT(12);
515 else
516 etm.ctrl &= ~BIT(12);
517
518 if (etm.mode & ETM_MODE_STALL)
519 etm.ctrl |= BIT(7);
520 else
521 etm.ctrl &= ~BIT(7);
522
523 if (etm.mode & ETM_MODE_TIMESTAMP)
524 etm.ctrl |= BIT(28);
525 else
526 etm.ctrl &= ~BIT(28);
527 if (etm.mode & ETM_MODE_CTXID)
528 etm.ctrl |= (BIT(14) | BIT(15));
529 else
530 etm.ctrl &= ~(BIT(14) | BIT(15));
531 mutex_unlock(&etm.mutex);
532
533 return n;
534}
535ETM_SHOW(mode);
536ETM_ATTR(mode);
537
538ETM_STORE(trigger_event, ETM_EVENT_MASK);
539ETM_SHOW(trigger_event);
540ETM_ATTR(trigger_event);
541
542ETM_STORE(enable_event, ETM_EVENT_MASK);
543ETM_SHOW(enable_event);
544ETM_ATTR(enable_event);
545
546ETM_STORE(fifofull_level, ETM_ALL_MASK);
547ETM_SHOW(fifofull_level);
548ETM_ATTR(fifofull_level);
549
550static ssize_t addr_idx_store(struct kobject *kobj,
551 struct kobj_attribute *attr,
552 const char *buf, size_t n)
553{
554 unsigned long val;
555
556 if (sscanf(buf, "%lx", &val) != 1)
557 return -EINVAL;
558 if (val >= etm.nr_addr_cmp)
559 return -EINVAL;
560
561 /* Use mutex to ensure index doesn't change while it gets dereferenced
562 * multiple times within a mutex block elsewhere.
563 */
564 mutex_lock(&etm.mutex);
565 etm.addr_idx = val;
566 mutex_unlock(&etm.mutex);
567 return n;
568}
569ETM_SHOW(addr_idx);
570ETM_ATTR(addr_idx);
571
572/* Takes care of resetting addr_* nodes and the exclude/include
573 * mode field. Does not reset enable_event.
574 */
575static ssize_t addr_reset_store(struct kobject *kobj,
576 struct kobj_attribute *attr,
577 const char *buf, size_t n)
578{
579 int i;
580 unsigned long val;
581
582 if (sscanf(buf, "%lx", &val) != 1)
583 return -EINVAL;
584
585 mutex_lock(&etm.mutex);
586 if (val) {
587 etm.addr_idx = 0x0;
588 for (i = 0; i < etm.nr_addr_cmp; i++) {
589 etm.addr_val[i] = 0x0;
590 etm.addr_acctype[i] = 0x0;
591 etm.addr_type[i] = ETM_ADDR_TYPE_NONE;
592 }
593 etm.startstop_ctrl = 0x0;
594 etm.mode |= ETM_MODE_EXCLUDE;
595 etm.enable_ctrl1 = 0x1000000;
596 etm.addr_reset = 0x1;
597 }
598 mutex_unlock(&etm.mutex);
599 return n;
600}
601ETM_SHOW(addr_reset);
602ETM_ATTR(addr_reset);
603
604static ssize_t addr_single_store(struct kobject *kobj,
605 struct kobj_attribute *attr,
606 const char *buf, size_t n)
607{
608 unsigned long val;
609 uint8_t idx;
610
611 if (sscanf(buf, "%lx", &val) != 1)
612 return -EINVAL;
613
614 mutex_lock(&etm.mutex);
615 idx = etm.addr_idx;
616 if (!(etm.addr_type[idx] == ETM_ADDR_TYPE_NONE ||
617 etm.addr_type[idx] == ETM_ADDR_TYPE_SINGLE)) {
618 mutex_unlock(&etm.mutex);
619 return -EPERM;
620 }
621
622 etm.addr_val[idx] = val;
623 etm.addr_type[idx] = ETM_ADDR_TYPE_SINGLE;
624 etm.addr_reset = 0x0;
625 mutex_unlock(&etm.mutex);
626 return n;
627}
628static ssize_t addr_single_show(struct kobject *kobj,
629 struct kobj_attribute *attr,
630 char *buf)
631{
632 unsigned long val;
633 uint8_t idx;
634
635 mutex_lock(&etm.mutex);
636 idx = etm.addr_idx;
637 if (!(etm.addr_type[idx] == ETM_ADDR_TYPE_NONE ||
638 etm.addr_type[idx] == ETM_ADDR_TYPE_SINGLE)) {
639 mutex_unlock(&etm.mutex);
640 return -EPERM;
641 }
642
643 val = etm.addr_val[idx];
644 mutex_unlock(&etm.mutex);
645 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
646}
647ETM_ATTR(addr_single);
648
649static ssize_t addr_range_store(struct kobject *kobj,
650 struct kobj_attribute *attr,
651 const char *buf, size_t n)
652{
653 unsigned long val1, val2;
654 uint8_t idx;
655
656 if (sscanf(buf, "%lx %lx", &val1, &val2) != 2)
657 return -EINVAL;
658 /* lower address comparator cannot have a higher address value */
659 if (val1 > val2)
660 return -EINVAL;
661
662 mutex_lock(&etm.mutex);
663 idx = etm.addr_idx;
664 if (idx % 2 != 0) {
665 mutex_unlock(&etm.mutex);
666 return -EPERM;
667 }
668 if (!((etm.addr_type[idx] == ETM_ADDR_TYPE_NONE &&
669 etm.addr_type[idx + 1] == ETM_ADDR_TYPE_NONE) ||
670 (etm.addr_type[idx] == ETM_ADDR_TYPE_RANGE &&
671 etm.addr_type[idx + 1] == ETM_ADDR_TYPE_RANGE))) {
672 mutex_unlock(&etm.mutex);
673 return -EPERM;
674 }
675
676 etm.addr_val[idx] = val1;
677 etm.addr_type[idx] = ETM_ADDR_TYPE_RANGE;
678 etm.addr_val[idx + 1] = val2;
679 etm.addr_type[idx + 1] = ETM_ADDR_TYPE_RANGE;
680 etm.enable_ctrl1 |= (1 << (idx/2));
681 etm.addr_reset = 0x0;
682 mutex_unlock(&etm.mutex);
683 return n;
684}
685static ssize_t addr_range_show(struct kobject *kobj,
686 struct kobj_attribute *attr,
687 char *buf)
688{
689 unsigned long val1, val2;
690 uint8_t idx;
691
692 mutex_lock(&etm.mutex);
693 idx = etm.addr_idx;
694 if (idx % 2 != 0) {
695 mutex_unlock(&etm.mutex);
696 return -EPERM;
697 }
698 if (!((etm.addr_type[idx] == ETM_ADDR_TYPE_NONE &&
699 etm.addr_type[idx + 1] == ETM_ADDR_TYPE_NONE) ||
700 (etm.addr_type[idx] == ETM_ADDR_TYPE_RANGE &&
701 etm.addr_type[idx + 1] == ETM_ADDR_TYPE_RANGE))) {
702 mutex_unlock(&etm.mutex);
703 return -EPERM;
704 }
705
706 val1 = etm.addr_val[idx];
707 val2 = etm.addr_val[idx + 1];
708 mutex_unlock(&etm.mutex);
709 return scnprintf(buf, PAGE_SIZE, "%#lx %#lx\n", val1, val2);
710}
711ETM_ATTR(addr_range);
712
713static ssize_t addr_start_store(struct kobject *kobj,
714 struct kobj_attribute *attr,
715 const char *buf, size_t n)
716{
717 unsigned long val;
718 uint8_t idx;
719
720 if (sscanf(buf, "%lx", &val) != 1)
721 return -EINVAL;
722
723 mutex_lock(&etm.mutex);
724 idx = etm.addr_idx;
725 if (!(etm.addr_type[idx] == ETM_ADDR_TYPE_NONE ||
726 etm.addr_type[idx] == ETM_ADDR_TYPE_START)) {
727 mutex_unlock(&etm.mutex);
728 return -EPERM;
729 }
730
731 etm.addr_val[idx] = val;
732 etm.addr_type[idx] = ETM_ADDR_TYPE_START;
733 etm.startstop_ctrl |= (1 << idx);
734 etm.enable_ctrl1 |= BIT(25);
735 etm.addr_reset = 0x0;
736 mutex_unlock(&etm.mutex);
737 return n;
738}
739static ssize_t addr_start_show(struct kobject *kobj,
740 struct kobj_attribute *attr,
741 char *buf)
742{
743 unsigned long val;
744 uint8_t idx;
745
746 mutex_lock(&etm.mutex);
747 idx = etm.addr_idx;
748 if (!(etm.addr_type[idx] == ETM_ADDR_TYPE_NONE ||
749 etm.addr_type[idx] == ETM_ADDR_TYPE_START)) {
750 mutex_unlock(&etm.mutex);
751 return -EPERM;
752 }
753
754 val = etm.addr_val[idx];
755 mutex_unlock(&etm.mutex);
756 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
757}
758ETM_ATTR(addr_start);
759
760static ssize_t addr_stop_store(struct kobject *kobj,
761 struct kobj_attribute *attr,
762 const char *buf, size_t n)
763{
764 unsigned long val;
765 uint8_t idx;
766
767 if (sscanf(buf, "%lx", &val) != 1)
768 return -EINVAL;
769
770 mutex_lock(&etm.mutex);
771 idx = etm.addr_idx;
772 if (!(etm.addr_type[idx] == ETM_ADDR_TYPE_NONE ||
773 etm.addr_type[idx] == ETM_ADDR_TYPE_STOP)) {
774 mutex_unlock(&etm.mutex);
775 return -EPERM;
776 }
777
778 etm.addr_val[idx] = val;
779 etm.addr_type[idx] = ETM_ADDR_TYPE_STOP;
780 etm.startstop_ctrl |= (1 << (idx + 16));
781 etm.enable_ctrl1 |= BIT(25);
782 etm.addr_reset = 0x0;
783 mutex_unlock(&etm.mutex);
784 return n;
785}
786static ssize_t addr_stop_show(struct kobject *kobj,
787 struct kobj_attribute *attr,
788 char *buf)
789{
790 unsigned long val;
791 uint8_t idx;
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 val = etm.addr_val[idx];
802 mutex_unlock(&etm.mutex);
803 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
804}
805ETM_ATTR(addr_stop);
806
807static ssize_t addr_acctype_store(struct kobject *kobj,
808 struct kobj_attribute *attr,
809 const char *buf, size_t n)
810{
811 unsigned long val;
812
813 if (sscanf(buf, "%lx", &val) != 1)
814 return -EINVAL;
815
816 mutex_lock(&etm.mutex);
817 etm.addr_acctype[etm.addr_idx] = val;
818 etm.addr_reset = 0x0;
819 mutex_unlock(&etm.mutex);
820 return n;
821}
822static ssize_t addr_acctype_show(struct kobject *kobj,
823 struct kobj_attribute *attr,
824 char *buf)
825{
826 unsigned long val;
827
828 mutex_lock(&etm.mutex);
829 val = etm.addr_acctype[etm.addr_idx];
830 mutex_unlock(&etm.mutex);
831 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
832}
833ETM_ATTR(addr_acctype);
834
835static ssize_t cntr_idx_store(struct kobject *kobj,
836 struct kobj_attribute *attr,
837 const char *buf, size_t n)
838{
839 unsigned long val;
840
841 if (sscanf(buf, "%lx", &val) != 1)
842 return -EINVAL;
843 if (val >= etm.nr_cntr)
844 return -EINVAL;
845
846 /* Use mutex to ensure index doesn't change while it gets dereferenced
847 * multiple times within a mutex block elsewhere.
848 */
849 mutex_lock(&etm.mutex);
850 etm.cntr_idx = val;
851 mutex_unlock(&etm.mutex);
852 return n;
853}
854ETM_SHOW(cntr_idx);
855ETM_ATTR(cntr_idx);
856
857static ssize_t cntr_rld_val_store(struct kobject *kobj,
858 struct kobj_attribute *attr,
859 const char *buf, size_t n)
860{
861 unsigned long val;
862
863 if (sscanf(buf, "%lx", &val) != 1)
864 return -EINVAL;
865
866 mutex_lock(&etm.mutex);
867 etm.cntr_rld_val[etm.cntr_idx] = val;
868 mutex_unlock(&etm.mutex);
869 return n;
870}
871static ssize_t cntr_rld_val_show(struct kobject *kobj,
872 struct kobj_attribute *attr,
873 char *buf)
874{
875 unsigned long val;
876 mutex_lock(&etm.mutex);
877 val = etm.cntr_rld_val[etm.cntr_idx];
878 mutex_unlock(&etm.mutex);
879 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
880}
881ETM_ATTR(cntr_rld_val);
882
883static ssize_t cntr_event_store(struct kobject *kobj,
884 struct kobj_attribute *attr,
885 const char *buf, size_t n)
886{
887 unsigned long val;
888
889 if (sscanf(buf, "%lx", &val) != 1)
890 return -EINVAL;
891
892 mutex_lock(&etm.mutex);
893 etm.cntr_event[etm.cntr_idx] = val & ETM_EVENT_MASK;
894 mutex_unlock(&etm.mutex);
895 return n;
896}
897static ssize_t cntr_event_show(struct kobject *kobj,
898 struct kobj_attribute *attr,
899 char *buf)
900{
901 unsigned long val;
902
903 mutex_lock(&etm.mutex);
904 val = etm.cntr_event[etm.cntr_idx];
905 mutex_unlock(&etm.mutex);
906 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
907}
908ETM_ATTR(cntr_event);
909
910static ssize_t cntr_rld_event_store(struct kobject *kobj,
911 struct kobj_attribute *attr,
912 const char *buf, size_t n)
913{
914 unsigned long val;
915
916 if (sscanf(buf, "%lx", &val) != 1)
917 return -EINVAL;
918
919 mutex_lock(&etm.mutex);
920 etm.cntr_rld_event[etm.cntr_idx] = val & ETM_EVENT_MASK;
921 mutex_unlock(&etm.mutex);
922 return n;
923}
924static ssize_t cntr_rld_event_show(struct kobject *kobj,
925 struct kobj_attribute *attr,
926 char *buf)
927{
928 unsigned long val;
929
930 mutex_lock(&etm.mutex);
931 val = etm.cntr_rld_event[etm.cntr_idx];
932 mutex_unlock(&etm.mutex);
933 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
934}
935ETM_ATTR(cntr_rld_event);
936
937static ssize_t cntr_val_store(struct kobject *kobj,
938 struct kobj_attribute *attr,
939 const char *buf, size_t n)
940{
941 unsigned long val;
942
943 if (sscanf(buf, "%lx", &val) != 1)
944 return -EINVAL;
945
946 mutex_lock(&etm.mutex);
947 etm.cntr_val[etm.cntr_idx] = val;
948 mutex_unlock(&etm.mutex);
949 return n;
950}
951static ssize_t cntr_val_show(struct kobject *kobj,
952 struct kobj_attribute *attr,
953 char *buf)
954{
955 unsigned long val;
956
957 mutex_lock(&etm.mutex);
958 val = etm.cntr_val[etm.cntr_idx];
959 mutex_unlock(&etm.mutex);
960 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
961}
962ETM_ATTR(cntr_val);
963
964ETM_STORE(seq_12_event, ETM_EVENT_MASK);
965ETM_SHOW(seq_12_event);
966ETM_ATTR(seq_12_event);
967
968ETM_STORE(seq_21_event, ETM_EVENT_MASK);
969ETM_SHOW(seq_21_event);
970ETM_ATTR(seq_21_event);
971
972ETM_STORE(seq_23_event, ETM_EVENT_MASK);
973ETM_SHOW(seq_23_event);
974ETM_ATTR(seq_23_event);
975
976ETM_STORE(seq_31_event, ETM_EVENT_MASK);
977ETM_SHOW(seq_31_event);
978ETM_ATTR(seq_31_event);
979
980ETM_STORE(seq_32_event, ETM_EVENT_MASK);
981ETM_SHOW(seq_32_event);
982ETM_ATTR(seq_32_event);
983
984ETM_STORE(seq_13_event, ETM_EVENT_MASK);
985ETM_SHOW(seq_13_event);
986ETM_ATTR(seq_13_event);
987
988static ssize_t seq_curr_state_store(struct kobject *kobj,
989 struct kobj_attribute *attr,
990 const char *buf, size_t n)
991{
992 unsigned long val;
993
994 if (sscanf(buf, "%lx", &val) != 1)
995 return -EINVAL;
996 if (val > ETM_SEQ_STATE_MAX_VAL)
997 return -EINVAL;
998
999 etm.seq_curr_state = val;
1000 return n;
1001}
1002ETM_SHOW(seq_curr_state);
1003ETM_ATTR(seq_curr_state);
1004
1005static ssize_t ctxid_idx_store(struct kobject *kobj,
1006 struct kobj_attribute *attr,
1007 const char *buf, size_t n)
1008{
1009 unsigned long val;
1010
1011 if (sscanf(buf, "%lx", &val) != 1)
1012 return -EINVAL;
1013 if (val >= etm.nr_ctxid_cmp)
1014 return -EINVAL;
1015
1016 /* Use mutex to ensure index doesn't change while it gets dereferenced
1017 * multiple times within a mutex block elsewhere.
1018 */
1019 mutex_lock(&etm.mutex);
1020 etm.ctxid_idx = val;
1021 mutex_unlock(&etm.mutex);
1022 return n;
1023}
1024ETM_SHOW(ctxid_idx);
1025ETM_ATTR(ctxid_idx);
1026
1027static ssize_t ctxid_val_store(struct kobject *kobj,
1028 struct kobj_attribute *attr,
1029 const char *buf, size_t n)
1030{
1031 unsigned long val;
1032
1033 if (sscanf(buf, "%lx", &val) != 1)
1034 return -EINVAL;
1035
1036 mutex_lock(&etm.mutex);
1037 etm.ctxid_val[etm.ctxid_idx] = val;
1038 mutex_unlock(&etm.mutex);
1039 return n;
1040}
1041static ssize_t ctxid_val_show(struct kobject *kobj,
1042 struct kobj_attribute *attr,
1043 char *buf)
1044{
1045 unsigned long val;
1046
1047 mutex_lock(&etm.mutex);
1048 val = etm.ctxid_val[etm.ctxid_idx];
1049 mutex_unlock(&etm.mutex);
1050 return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
1051}
1052ETM_ATTR(ctxid_val);
1053
1054ETM_STORE(ctxid_mask, ETM_ALL_MASK);
1055ETM_SHOW(ctxid_mask);
1056ETM_ATTR(ctxid_mask);
1057
1058ETM_STORE(sync_freq, ETM_SYNC_MASK);
1059ETM_SHOW(sync_freq);
1060ETM_ATTR(sync_freq);
1061
1062ETM_STORE(timestamp_event, ETM_EVENT_MASK);
1063ETM_SHOW(timestamp_event);
1064ETM_ATTR(timestamp_event);
1065
1066static struct attribute *etm_attrs[] = {
1067 &nr_addr_cmp_attr.attr,
1068 &nr_cntr_attr.attr,
1069 &nr_ctxid_cmp_attr.attr,
1070 &mode_attr.attr,
1071 &trigger_event_attr.attr,
1072 &enable_event_attr.attr,
1073 &fifofull_level_attr.attr,
1074 &addr_idx_attr.attr,
1075 &addr_reset_attr.attr,
1076 &addr_single_attr.attr,
1077 &addr_range_attr.attr,
1078 &addr_start_attr.attr,
1079 &addr_stop_attr.attr,
1080 &addr_acctype_attr.attr,
1081 &cntr_idx_attr.attr,
1082 &cntr_rld_val_attr.attr,
1083 &cntr_event_attr.attr,
1084 &cntr_rld_event_attr.attr,
1085 &cntr_val_attr.attr,
1086 &seq_12_event_attr.attr,
1087 &seq_21_event_attr.attr,
1088 &seq_23_event_attr.attr,
1089 &seq_31_event_attr.attr,
1090 &seq_32_event_attr.attr,
1091 &seq_13_event_attr.attr,
1092 &seq_curr_state_attr.attr,
1093 &ctxid_idx_attr.attr,
1094 &ctxid_val_attr.attr,
1095 &ctxid_mask_attr.attr,
1096 &sync_freq_attr.attr,
1097 &timestamp_event_attr.attr,
1098 NULL,
1099};
1100
1101static struct attribute_group etm_attr_grp = {
1102 .attrs = etm_attrs,
1103};
1104
1105static int __init etm_sysfs_init(void)
1106{
1107 int ret;
1108
1109 etm.kobj = kobject_create_and_add("etm", qdss_get_modulekobj());
1110 if (!etm.kobj) {
1111 dev_err(etm.dev, "failed to create ETM sysfs kobject\n");
1112 ret = -ENOMEM;
1113 goto err_create;
1114 }
1115
1116 ret = sysfs_create_file(etm.kobj, &enabled_attr.attr);
1117 if (ret) {
1118 dev_err(etm.dev, "failed to create ETM sysfs enabled"
1119 " attribute\n");
1120 goto err_file;
1121 }
1122
1123 if (sysfs_create_group(etm.kobj, &etm_attr_grp))
1124 dev_err(etm.dev, "failed to create ETM sysfs group\n");
1125
1126 return 0;
1127err_file:
1128 kobject_put(etm.kobj);
1129err_create:
1130 return ret;
1131}
1132
1133static void etm_sysfs_exit(void)
1134{
1135 sysfs_remove_group(etm.kobj, &etm_attr_grp);
1136 sysfs_remove_file(etm.kobj, &enabled_attr.attr);
1137 kobject_put(etm.kobj);
1138}
1139
Pratik Patel61de7302012-03-07 12:06:10 -08001140static bool etm_arch_supported(uint8_t arch)
Pratik Patel7831c082011-06-08 21:44:37 -07001141{
Pratik Patel61de7302012-03-07 12:06:10 -08001142 switch (arch) {
1143 case PFT_ARCH_V1_1:
1144 break;
1145 default:
1146 return false;
1147 }
1148 return true;
1149}
1150
1151static int __init etm_arch_init(void)
1152{
1153 int ret;
Pratik Patel7831c082011-06-08 21:44:37 -07001154 /* use cpu 0 for setup */
1155 int cpu = 0;
Pratik Patel61de7302012-03-07 12:06:10 -08001156 uint32_t etmidr;
1157 uint32_t etmccr;
Pratik Patel7831c082011-06-08 21:44:37 -07001158
Pratik Patel17f3b822011-11-21 12:41:47 -08001159 /* Unlock OS lock first to allow memory mapped reads and writes */
Pratik Patel492b3012012-03-06 14:22:30 -08001160 etm_os_unlock(NULL);
1161 smp_call_function(etm_os_unlock, NULL, 1);
1162 ETM_UNLOCK(cpu);
Pratik Patel17f3b822011-11-21 12:41:47 -08001163 /* Vote for ETM power/clock enable */
Pratik Patel61de7302012-03-07 12:06:10 -08001164 etm_clr_pwrdwn(cpu);
1165 /* Set prog bit. It will be set from reset but this is included to
1166 * ensure it is set
1167 */
Pratik Patel492b3012012-03-06 14:22:30 -08001168 etm_set_prog(cpu);
Pratik Patel7831c082011-06-08 21:44:37 -07001169
1170 /* find all capabilities */
Pratik Patel61de7302012-03-07 12:06:10 -08001171 etmidr = etm_readl(etm, cpu, ETMIDR);
1172 etm.arch = BMVAL(etmidr, 4, 11);
1173 if (etm_arch_supported(etm.arch) == false) {
1174 ret = -EINVAL;
1175 goto err;
1176 }
Pratik Patel7831c082011-06-08 21:44:37 -07001177
Pratik Patel61de7302012-03-07 12:06:10 -08001178 etmccr = etm_readl(etm, cpu, ETMCCR);
1179 etm.nr_addr_cmp = BMVAL(etmccr, 0, 3) * 2;
1180 etm.nr_cntr = BMVAL(etmccr, 13, 15);
1181 etm.nr_ext_inp = BMVAL(etmccr, 17, 19);
1182 etm.nr_ext_out = BMVAL(etmccr, 20, 22);
1183 etm.nr_ctxid_cmp = BMVAL(etmccr, 24, 25);
Pratik Patel7831c082011-06-08 21:44:37 -07001184
Pratik Patel17f3b822011-11-21 12:41:47 -08001185 /* Vote for ETM power/clock disable */
Pratik Patel61de7302012-03-07 12:06:10 -08001186 etm_set_pwrdwn(cpu);
Pratik Patel492b3012012-03-06 14:22:30 -08001187 ETM_LOCK(cpu);
Pratik Patel61de7302012-03-07 12:06:10 -08001188
1189 return 0;
1190err:
1191 return ret;
Pratik Patel7831c082011-06-08 21:44:37 -07001192}
1193
Pratik Patel492b3012012-03-06 14:22:30 -08001194static int __devinit etm_probe(struct platform_device *pdev)
Pratik Patel7831c082011-06-08 21:44:37 -07001195{
Pratik Patele5771792011-09-17 18:33:54 -07001196 int ret;
Pratik Patel7831c082011-06-08 21:44:37 -07001197 struct resource *res;
1198
1199 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1200 if (!res) {
1201 ret = -EINVAL;
1202 goto err_res;
1203 }
1204
Pratik Patel492b3012012-03-06 14:22:30 -08001205 etm.base = ioremap_nocache(res->start, resource_size(res));
1206 if (!etm.base) {
Pratik Patel7831c082011-06-08 21:44:37 -07001207 ret = -EINVAL;
1208 goto err_ioremap;
1209 }
1210
Pratik Patel492b3012012-03-06 14:22:30 -08001211 etm.dev = &pdev->dev;
Pratik Patel7831c082011-06-08 21:44:37 -07001212
Pratik Patel6630ebe2012-03-06 16:44:22 -08001213 mutex_init(&etm.mutex);
Pratik Patel61de7302012-03-07 12:06:10 -08001214 wake_lock_init(&etm.wake_lock, WAKE_LOCK_SUSPEND, "msm_etm");
1215 pm_qos_add_request(&etm.qos_req, PM_QOS_CPU_DMA_LATENCY,
1216 PM_QOS_DEFAULT_VALUE);
Pratik Patelcc320a42011-12-22 10:48:14 -08001217 ret = qdss_clk_enable();
Pratik Patel7831c082011-06-08 21:44:37 -07001218 if (ret)
Pratik Patelcc320a42011-12-22 10:48:14 -08001219 goto err_clk;
Pratik Patel7831c082011-06-08 21:44:37 -07001220
Pratik Patel61de7302012-03-07 12:06:10 -08001221 ret = etm_arch_init();
1222 if (ret)
1223 goto err_arch;
Pratik Patel7831c082011-06-08 21:44:37 -07001224
Pratik Patel6630ebe2012-03-06 16:44:22 -08001225 ret = etm_sysfs_init();
1226 if (ret)
1227 goto err_sysfs;
1228
Pratik Patel61de7302012-03-07 12:06:10 -08001229 etm.enabled = false;
Pratik Patel7831c082011-06-08 21:44:37 -07001230
Pratik Patelcc320a42011-12-22 10:48:14 -08001231 qdss_clk_disable();
Pratik Patel7831c082011-06-08 21:44:37 -07001232
Pratik Patel61de7302012-03-07 12:06:10 -08001233 dev_info(etm.dev, "ETM initialized\n");
Pratik Patel7831c082011-06-08 21:44:37 -07001234
Pratik Patel61de7302012-03-07 12:06:10 -08001235 if (etm_boot_enable)
1236 etm_enable();
Pratik Patel7831c082011-06-08 21:44:37 -07001237
1238 return 0;
1239
Pratik Patel6630ebe2012-03-06 16:44:22 -08001240err_sysfs:
Pratik Patel61de7302012-03-07 12:06:10 -08001241err_arch:
1242 qdss_clk_disable();
Pratik Patelcc320a42011-12-22 10:48:14 -08001243err_clk:
Pratik Patel61de7302012-03-07 12:06:10 -08001244 pm_qos_remove_request(&etm.qos_req);
1245 wake_lock_destroy(&etm.wake_lock);
Pratik Patel6630ebe2012-03-06 16:44:22 -08001246 mutex_destroy(&etm.mutex);
Pratik Patel492b3012012-03-06 14:22:30 -08001247 iounmap(etm.base);
Pratik Patel7831c082011-06-08 21:44:37 -07001248err_ioremap:
1249err_res:
Pratik Patel61de7302012-03-07 12:06:10 -08001250 dev_err(etm.dev, "ETM init failed\n");
Pratik Patel7831c082011-06-08 21:44:37 -07001251 return ret;
1252}
1253
Pratik Patel492b3012012-03-06 14:22:30 -08001254static int etm_remove(struct platform_device *pdev)
Pratik Patel7831c082011-06-08 21:44:37 -07001255{
Pratik Patel61de7302012-03-07 12:06:10 -08001256 if (etm.enabled)
1257 etm_disable();
Pratik Patel6630ebe2012-03-06 16:44:22 -08001258 etm_sysfs_exit();
Pratik Patel492b3012012-03-06 14:22:30 -08001259 pm_qos_remove_request(&etm.qos_req);
1260 wake_lock_destroy(&etm.wake_lock);
Pratik Patel6630ebe2012-03-06 16:44:22 -08001261 mutex_destroy(&etm.mutex);
Pratik Patel492b3012012-03-06 14:22:30 -08001262 iounmap(etm.base);
Pratik Patel7831c082011-06-08 21:44:37 -07001263
1264 return 0;
1265}
1266
Pratik Patel492b3012012-03-06 14:22:30 -08001267static struct platform_driver etm_driver = {
1268 .probe = etm_probe,
1269 .remove = etm_remove,
Pratik Patel7831c082011-06-08 21:44:37 -07001270 .driver = {
Pratik Patel492b3012012-03-06 14:22:30 -08001271 .name = "msm_etm",
Pratik Patel7831c082011-06-08 21:44:37 -07001272 },
1273};
1274
Pratik Patel492b3012012-03-06 14:22:30 -08001275int __init etm_init(void)
Pratik Patel7831c082011-06-08 21:44:37 -07001276{
Pratik Patel492b3012012-03-06 14:22:30 -08001277 return platform_driver_register(&etm_driver);
Pratik Patel7831c082011-06-08 21:44:37 -07001278}
Pratik Patel7831c082011-06-08 21:44:37 -07001279
Pratik Patel492b3012012-03-06 14:22:30 -08001280void etm_exit(void)
Pratik Patel7831c082011-06-08 21:44:37 -07001281{
Pratik Patel492b3012012-03-06 14:22:30 -08001282 platform_driver_unregister(&etm_driver);
Pratik Patel7831c082011-06-08 21:44:37 -07001283}