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