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