blob: 2ecbb3853e975a821aa6e0e641fe0ea8da4779b2 [file] [log] [blame]
rjw1f884582022-01-06 17:20:42 +08001/*
2 * Copyright (C) 2018 MediaTek Inc.
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14#ifndef MET_DRV
15#define MET_DRV
16
17#include <linux/version.h>
18#include <linux/preempt.h>
19#include <linux/device.h>
20#include <linux/percpu.h>
21#include <linux/hardirq.h>
22#include <linux/clk.h>
23
24extern int met_mode;
25extern int core_plf_init(void);
26extern void core_plf_exit(void);
27
28#define MET_MODE_TRACE_CMD_OFFSET (1)
29#define MET_MODE_TRACE_CMD (1<<MET_MODE_TRACE_CMD_OFFSET)
30
31#ifdef CONFIG_MET_MODULE
32#define my_preempt_enable() preempt_enable()
33#else
34#define my_preempt_enable() preempt_enable_no_resched()
35#endif
36
37#define MET_STRBUF_SIZE 1024
38DECLARE_PER_CPU(char[MET_STRBUF_SIZE], met_strbuf_nmi);
39DECLARE_PER_CPU(char[MET_STRBUF_SIZE], met_strbuf_irq);
40DECLARE_PER_CPU(char[MET_STRBUF_SIZE], met_strbuf_sirq);
41DECLARE_PER_CPU(char[MET_STRBUF_SIZE], met_strbuf);
42
43#ifdef CONFIG_TRACING
44#define TRACE_PUTS(p) \
45 do { \
46 trace_puts(p);; \
47 } while (0)
48#else
49#define TRACE_PUTS(p) do {} while (0)
50#endif
51
52#define GET_MET_TRACE_BUFFER_ENTER_CRITICAL() \
53 ({ \
54 char *pmet_strbuf; \
55 preempt_disable(); \
56 if (in_nmi()) \
57 pmet_strbuf = per_cpu(met_strbuf_nmi, smp_processor_id()); \
58 else if (in_irq()) \
59 pmet_strbuf = per_cpu(met_strbuf_irq, smp_processor_id()); \
60 else if (in_softirq()) \
61 pmet_strbuf = per_cpu(met_strbuf_sirq, smp_processor_id()); \
62 else \
63 pmet_strbuf = per_cpu(met_strbuf, smp_processor_id()); \
64 pmet_strbuf;\
65 })
66
67#define PUT_MET_TRACE_BUFFER_EXIT_CRITICAL(pmet_strbuf) \
68 do {\
69 if (pmet_strbuf)\
70 TRACE_PUTS(pmet_strbuf); \
71 my_preempt_enable(); \
72 } while (0)
73
74#define MET_TRACE(FORMAT, args...) \
75 do { \
76 char *pmet_strbuf; \
77 preempt_disable(); \
78 if (in_nmi()) \
79 pmet_strbuf = per_cpu(met_strbuf_nmi, smp_processor_id()); \
80 else if (in_irq()) \
81 pmet_strbuf = per_cpu(met_strbuf_irq, smp_processor_id()); \
82 else if (in_softirq()) \
83 pmet_strbuf = per_cpu(met_strbuf_sirq, smp_processor_id()); \
84 else \
85 pmet_strbuf = per_cpu(met_strbuf, smp_processor_id()); \
86 if (met_mode & MET_MODE_TRACE_CMD) \
87 snprintf(pmet_strbuf, MET_STRBUF_SIZE, "%s: " FORMAT, __func__, ##args); \
88 else \
89 snprintf(pmet_strbuf, MET_STRBUF_SIZE, FORMAT, ##args); \
90 TRACE_PUTS(pmet_strbuf); \
91 my_preempt_enable(); \
92 } while (0)
93
94/*
95 * SOB: start of buf
96 * EOB: end of buf
97 */
98#define MET_TRACE_GETBUF(pSOB, pEOB) \
99 ({ \
100 preempt_disable(); \
101 if (in_nmi()) \
102 *pSOB = per_cpu(met_strbuf_nmi, smp_processor_id()); \
103 else if (in_irq()) \
104 *pSOB = per_cpu(met_strbuf_irq, smp_processor_id()); \
105 else if (in_softirq()) \
106 *pSOB = per_cpu(met_strbuf_sirq, smp_processor_id()); \
107 else \
108 *pSOB = per_cpu(met_strbuf, smp_processor_id()); \
109 *pEOB = *pSOB; \
110 if (met_mode & MET_MODE_TRACE_CMD) \
111 *pEOB += snprintf(*pEOB, MET_STRBUF_SIZE, "%s: ", __func__); \
112 })
113
114#define MET_TRACE_PUTBUF(SOB, EOB) \
115 ({ \
116 __trace_puts(_THIS_IP_, (SOB), (uintptr_t)((EOB)-(SOB))); \
117 my_preempt_enable(); \
118 })
119
120#define MET_FTRACE_DUMP(TRACE_NAME, args...) \
121 do { \
122 trace_##TRACE_NAME(args);; \
123 } while (0)
124
125
126#define MET_TYPE_PMU 1
127#define MET_TYPE_BUS 2
128#define MET_TYPE_MISC 3
129
130struct metdevice {
131 struct list_head list;
132 int type;
133 const char *name;
134 struct module *owner;
135 struct kobject *kobj;
136
137 int (*create_subfs)(struct kobject *parent);
138 void (*delete_subfs)(void);
139 int mode;
140 int ondiemet_mode; /* new for ondiemet; 1: call ondiemet functions */
141 int cpu_related;
142 int polling_interval;
143 int polling_count_reload;
144 int __percpu *polling_count;
145 int header_read_again; /*for header size > 1 page */
146 void (*start)(void);
147 void (*stop)(void);
148 int (*reset)(void);
149 void (*timed_polling)(unsigned long long stamp, int cpu);
150 void (*tagged_polling)(unsigned long long stamp, int cpu);
151 int (*print_help)(char *buf, int len);
152 int (*print_header)(char *buf, int len);
153 int (*process_argument)(const char *arg, int len);
154
155 void (*ondiemet_start)(void);
156 void (*ondiemet_stop)(void);
157 int (*ondiemet_reset)(void);
158 int (*ondiemet_print_help)(char *buf, int len);
159 int (*ondiemet_print_header)(char *buf, int len);
160 int (*ondiemet_process_argument)(const char *arg, int len);
161 void (*ondiemet_timed_polling)(unsigned long long stamp, int cpu);
162 void (*ondiemet_tagged_polling)(unsigned long long stamp, int cpu);
163
164 struct list_head exlist; /* for linked list before register */
165 void (*suspend)(void);
166 void (*resume)(void);
167
168 unsigned long long prev_stamp;
169 spinlock_t my_lock;
170 void *reversed1;
171};
172
173int met_register(struct metdevice *met);
174int met_deregister(struct metdevice *met);
175int met_set_platform(const char *plf_name, int flag);
176int met_set_topology(const char *topology_name, int flag);
177int met_devlink_add(struct metdevice *met);
178int met_devlink_del(struct metdevice *met);
179int met_devlink_register_all(void);
180int met_devlink_deregister_all(void);
181
182int fs_reg(void);
183void fs_unreg(void);
184
185/******************************************************************************
186 * Tracepoints
187 ******************************************************************************/
188#define MET_DEFINE_PROBE(probe_name, proto) \
189 static void probe_##probe_name(void *data, PARAMS(proto))
190#define MET_REGISTER_TRACE(probe_name) \
191 register_trace_##probe_name(probe_##probe_name, NULL)
192#define MET_UNREGISTER_TRACE(probe_name) \
193 unregister_trace_##probe_name(probe_##probe_name, NULL)
194
195
196/* ====================== Tagging API ================================ */
197
198#define MAX_EVENT_CLASS 31
199#define MAX_TAGNAME_LEN 128
200#define MET_CLASS_ALL 0x80000000
201
202/* IOCTL commands of MET tagging */
203struct mtag_cmd_t {
204 unsigned int class_id;
205 unsigned int value;
206 unsigned int slen;
207 char tname[MAX_TAGNAME_LEN];
208 void *data;
209 unsigned int size;
210};
211
212#define TYPE_START 1
213#define TYPE_END 2
214#define TYPE_ONESHOT 3
215#define TYPE_ENABLE 4
216#define TYPE_DISABLE 5
217#define TYPE_REC_SET 6
218#define TYPE_DUMP 7
219#define TYPE_DUMP_SIZE 8
220#define TYPE_DUMP_SAVE 9
221#define TYPE_USRDATA 10
222#define TYPE_DUMP_AGAIN 11
223#define TYPE_ASYNC_START 12
224#define TYPE_ASYNC_END 13
225#define TYPE_MET_SUSPEND 15
226#define TYPE_MET_RESUME 16
227
228/* Use 'm' as magic number */
229#define MTAG_IOC_MAGIC 'm'
230/* Please use a different 8-bit number in your code */
231#define MTAG_CMD_START _IOW(MTAG_IOC_MAGIC, TYPE_START, struct mtag_cmd_t)
232#define MTAG_CMD_END _IOW(MTAG_IOC_MAGIC, TYPE_END, struct mtag_cmd_t)
233#define MTAG_CMD_ONESHOT _IOW(MTAG_IOC_MAGIC, TYPE_ONESHOT, struct mtag_cmd_t)
234#define MTAG_CMD_ENABLE _IOW(MTAG_IOC_MAGIC, TYPE_ENABLE, int)
235#define MTAG_CMD_DISABLE _IOW(MTAG_IOC_MAGIC, TYPE_DISABLE, int)
236#define MTAG_CMD_REC_SET _IOW(MTAG_IOC_MAGIC, TYPE_REC_SET, int)
237#define MTAG_CMD_DUMP _IOW(MTAG_IOC_MAGIC, TYPE_DUMP, struct mtag_cmd_t)
238#define MTAG_CMD_DUMP_SIZE _IOWR(MTAG_IOC_MAGIC, TYPE_DUMP_SIZE, int)
239#define MTAG_CMD_DUMP_SAVE _IOW(MTAG_IOC_MAGIC, TYPE_DUMP_SAVE, struct mtag_cmd_t)
240#define MTAG_CMD_USRDATA _IOW(MTAG_IOC_MAGIC, TYPE_USRDATA, struct mtag_cmd_t)
241#define MTAG_CMD_DUMP_AGAIN _IOW(MTAG_IOC_MAGIC, TYPE_DUMP_AGAIN, void *)
242#define MTAG_CMD_ASYNC_START _IOW(MTAG_IOC_MAGIC, TYPE_ASYNC_START, struct mtag_cmd_t)
243#define MTAG_CMD_ASYNC_END _IOW(MTAG_IOC_MAGIC, TYPE_ASYNC_END, struct mtag_cmd_t)
244
245/* include file */
246extern int met_tag_start_real(unsigned int class_id, const char *name);
247extern int met_tag_end_real(unsigned int class_id, const char *name);
248extern int met_tag_async_start_real(unsigned int class_id, const char *name, unsigned int cookie);
249extern int met_tag_async_end_real(unsigned int class_id, const char *name, unsigned int cookie);
250extern int met_tag_oneshot_real(unsigned int class_id, const char *name, unsigned int value);
251extern int met_tag_userdata_real(char *pData);
252extern int met_tag_dump_real(unsigned int class_id, const char *name, void *data, unsigned int length);
253extern int met_tag_disable_real(unsigned int class_id);
254extern int met_tag_enable_real(unsigned int class_id);
255extern int met_set_dump_buffer_real(int size);
256extern int met_save_dump_buffer_real(const char *pathname);
257extern int met_save_log_real(const char *pathname);
258extern int met_show_bw_limiter_real(void);
259extern int met_reg_bw_limiter_real(void *fp);
260extern int met_show_clk_tree_real(const char *name, unsigned int addr, unsigned int status);
261extern int met_reg_clk_tree_real(void *fp);
262extern int enable_met_backlight_tag(void);
263extern int output_met_backlight_tag(int level);
264
265#endif /* MET_DRV */