2 * Intel SoC Core Telemetry Driver
3 * Copyright (C) 2015, Intel Corporation.
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * Telemetry Framework provides platform related PM and performance statistics.
16 * This file provides the core telemetry API implementation.
18 #include <linux/module.h>
19 #include <linux/init.h>
20 #include <linux/device.h>
22 #include <asm/intel_telemetry.h>
24 #define DRIVER_NAME "intel_telemetry_core"
26 struct telemetry_core_config
{
27 struct telemetry_plt_config
*plt_config
;
28 const struct telemetry_core_ops
*telem_ops
;
31 static struct telemetry_core_config telm_core_conf
;
33 static int telemetry_def_update_events(struct telemetry_evtconfig pss_evtconfig
,
34 struct telemetry_evtconfig ioss_evtconfig
)
39 static int telemetry_def_set_sampling_period(u8 pss_period
, u8 ioss_period
)
44 static int telemetry_def_get_sampling_period(u8
*pss_min_period
,
52 static int telemetry_def_get_eventconfig(
53 struct telemetry_evtconfig
*pss_evtconfig
,
54 struct telemetry_evtconfig
*ioss_evtconfig
,
55 int pss_len
, int ioss_len
)
60 static int telemetry_def_get_trace_verbosity(enum telemetry_unit telem_unit
,
67 static int telemetry_def_set_trace_verbosity(enum telemetry_unit telem_unit
,
73 static int telemetry_def_raw_read_eventlog(enum telemetry_unit telem_unit
,
74 struct telemetry_evtlog
*evtlog
,
75 int len
, int log_all_evts
)
80 static int telemetry_def_read_eventlog(enum telemetry_unit telem_unit
,
81 struct telemetry_evtlog
*evtlog
,
82 int len
, int log_all_evts
)
87 static int telemetry_def_add_events(u8 num_pss_evts
, u8 num_ioss_evts
,
88 u32
*pss_evtmap
, u32
*ioss_evtmap
)
93 static int telemetry_def_reset_events(void)
98 static const struct telemetry_core_ops telm_defpltops
= {
99 .set_sampling_period
= telemetry_def_set_sampling_period
,
100 .get_sampling_period
= telemetry_def_get_sampling_period
,
101 .get_trace_verbosity
= telemetry_def_get_trace_verbosity
,
102 .set_trace_verbosity
= telemetry_def_set_trace_verbosity
,
103 .raw_read_eventlog
= telemetry_def_raw_read_eventlog
,
104 .get_eventconfig
= telemetry_def_get_eventconfig
,
105 .read_eventlog
= telemetry_def_read_eventlog
,
106 .update_events
= telemetry_def_update_events
,
107 .reset_events
= telemetry_def_reset_events
,
108 .add_events
= telemetry_def_add_events
,
112 * telemetry_update_events() - Update telemetry Configuration
113 * @pss_evtconfig: PSS related config. No change if num_evts = 0.
114 * @pss_evtconfig: IOSS related config. No change if num_evts = 0.
116 * This API updates the IOSS & PSS Telemetry configuration. Old config
117 * is overwritten. Call telemetry_reset_events when logging is over
118 * All sample period values should be in the form of:
119 * bits[6:3] -> value; bits [0:2]-> Exponent; Period = (Value *16^Exponent)
121 * Return: 0 success, < 0 for failure
123 int telemetry_update_events(struct telemetry_evtconfig pss_evtconfig
,
124 struct telemetry_evtconfig ioss_evtconfig
)
126 return telm_core_conf
.telem_ops
->update_events(pss_evtconfig
,
129 EXPORT_SYMBOL_GPL(telemetry_update_events
);
133 * telemetry_set_sampling_period() - Sets the IOSS & PSS sampling period
134 * @pss_period: placeholder for PSS Period to be set.
135 * Set to 0 if not required to be updated
136 * @ioss_period: placeholder for IOSS Period to be set
137 * Set to 0 if not required to be updated
139 * All values should be in the form of:
140 * bits[6:3] -> value; bits [0:2]-> Exponent; Period = (Value *16^Exponent)
142 * Return: 0 success, < 0 for failure
144 int telemetry_set_sampling_period(u8 pss_period
, u8 ioss_period
)
146 return telm_core_conf
.telem_ops
->set_sampling_period(pss_period
,
149 EXPORT_SYMBOL_GPL(telemetry_set_sampling_period
);
152 * telemetry_get_sampling_period() - Get IOSS & PSS min & max sampling period
153 * @pss_min_period: placeholder for PSS Min Period supported
154 * @pss_max_period: placeholder for PSS Max Period supported
155 * @ioss_min_period: placeholder for IOSS Min Period supported
156 * @ioss_max_period: placeholder for IOSS Max Period supported
158 * All values should be in the form of:
159 * bits[6:3] -> value; bits [0:2]-> Exponent; Period = (Value *16^Exponent)
161 * Return: 0 success, < 0 for failure
163 int telemetry_get_sampling_period(u8
*pss_min_period
, u8
*pss_max_period
,
164 u8
*ioss_min_period
, u8
*ioss_max_period
)
166 return telm_core_conf
.telem_ops
->get_sampling_period(pss_min_period
,
171 EXPORT_SYMBOL_GPL(telemetry_get_sampling_period
);
175 * telemetry_reset_events() - Restore the IOSS & PSS configuration to default
177 * Return: 0 success, < 0 for failure
179 int telemetry_reset_events(void)
181 return telm_core_conf
.telem_ops
->reset_events();
183 EXPORT_SYMBOL_GPL(telemetry_reset_events
);
186 * telemetry_get_eventconfig() - Returns the pss and ioss events enabled
187 * @pss_evtconfig: Pointer to PSS related configuration.
188 * @pss_evtconfig: Pointer to IOSS related configuration.
189 * @pss_len: Number of u32 elements allocated for pss_evtconfig array
190 * @ioss_len: Number of u32 elements allocated for ioss_evtconfig array
192 * Return: 0 success, < 0 for failure
194 int telemetry_get_eventconfig(struct telemetry_evtconfig
*pss_evtconfig
,
195 struct telemetry_evtconfig
*ioss_evtconfig
,
196 int pss_len
, int ioss_len
)
198 return telm_core_conf
.telem_ops
->get_eventconfig(pss_evtconfig
,
202 EXPORT_SYMBOL_GPL(telemetry_get_eventconfig
);
205 * telemetry_add_events() - Add IOSS & PSS configuration to existing settings.
206 * @num_pss_evts: Number of PSS Events (<29) in pss_evtmap. Can be 0.
207 * @num_ioss_evts: Number of IOSS Events (<29) in ioss_evtmap. Can be 0.
208 * @pss_evtmap: Array of PSS Event-IDs to Enable
209 * @ioss_evtmap: Array of PSS Event-IDs to Enable
211 * Events are appended to Old Configuration. In case of total events > 28, it
212 * returns error. Call telemetry_reset_events to reset after eventlog done
214 * Return: 0 success, < 0 for failure
216 int telemetry_add_events(u8 num_pss_evts
, u8 num_ioss_evts
,
217 u32
*pss_evtmap
, u32
*ioss_evtmap
)
219 return telm_core_conf
.telem_ops
->add_events(num_pss_evts
,
220 num_ioss_evts
, pss_evtmap
,
223 EXPORT_SYMBOL_GPL(telemetry_add_events
);
226 * telemetry_read_events() - Fetches samples as specified by evtlog.telem_evt_id
227 * @telem_unit: Specify whether IOSS or PSS Read
228 * @evtlog: Array of telemetry_evtlog structs to fill data
229 * evtlog.telem_evt_id specifies the ids to read
230 * @len: Length of array of evtlog
232 * Return: number of eventlogs read for success, < 0 for failure
234 int telemetry_read_events(enum telemetry_unit telem_unit
,
235 struct telemetry_evtlog
*evtlog
, int len
)
237 return telm_core_conf
.telem_ops
->read_eventlog(telem_unit
, evtlog
,
240 EXPORT_SYMBOL_GPL(telemetry_read_events
);
243 * telemetry_raw_read_events() - Fetch samples specified by evtlog.telem_evt_id
244 * @telem_unit: Specify whether IOSS or PSS Read
245 * @evtlog: Array of telemetry_evtlog structs to fill data
246 * evtlog.telem_evt_id specifies the ids to read
247 * @len: Length of array of evtlog
249 * The caller must take care of locking in this case.
251 * Return: number of eventlogs read for success, < 0 for failure
253 int telemetry_raw_read_events(enum telemetry_unit telem_unit
,
254 struct telemetry_evtlog
*evtlog
, int len
)
256 return telm_core_conf
.telem_ops
->raw_read_eventlog(telem_unit
, evtlog
,
259 EXPORT_SYMBOL_GPL(telemetry_raw_read_events
);
262 * telemetry_read_eventlog() - Fetch the Telemetry log from PSS or IOSS
263 * @telem_unit: Specify whether IOSS or PSS Read
264 * @evtlog: Array of telemetry_evtlog structs to fill data
265 * @len: Length of array of evtlog
267 * Return: number of eventlogs read for success, < 0 for failure
269 int telemetry_read_eventlog(enum telemetry_unit telem_unit
,
270 struct telemetry_evtlog
*evtlog
, int len
)
272 return telm_core_conf
.telem_ops
->read_eventlog(telem_unit
, evtlog
,
275 EXPORT_SYMBOL_GPL(telemetry_read_eventlog
);
278 * telemetry_raw_read_eventlog() - Fetch the Telemetry log from PSS or IOSS
279 * @telem_unit: Specify whether IOSS or PSS Read
280 * @evtlog: Array of telemetry_evtlog structs to fill data
281 * @len: Length of array of evtlog
283 * The caller must take care of locking in this case.
285 * Return: number of eventlogs read for success, < 0 for failure
287 int telemetry_raw_read_eventlog(enum telemetry_unit telem_unit
,
288 struct telemetry_evtlog
*evtlog
, int len
)
290 return telm_core_conf
.telem_ops
->raw_read_eventlog(telem_unit
, evtlog
,
293 EXPORT_SYMBOL_GPL(telemetry_raw_read_eventlog
);
297 * telemetry_get_trace_verbosity() - Get the IOSS & PSS Trace verbosity
298 * @telem_unit: Specify whether IOSS or PSS Read
299 * @verbosity: Pointer to return Verbosity
301 * Return: 0 success, < 0 for failure
303 int telemetry_get_trace_verbosity(enum telemetry_unit telem_unit
,
306 return telm_core_conf
.telem_ops
->get_trace_verbosity(telem_unit
,
309 EXPORT_SYMBOL_GPL(telemetry_get_trace_verbosity
);
313 * telemetry_set_trace_verbosity() - Update the IOSS & PSS Trace verbosity
314 * @telem_unit: Specify whether IOSS or PSS Read
315 * @verbosity: Verbosity to set
317 * Return: 0 success, < 0 for failure
319 int telemetry_set_trace_verbosity(enum telemetry_unit telem_unit
, u32 verbosity
)
321 return telm_core_conf
.telem_ops
->set_trace_verbosity(telem_unit
,
324 EXPORT_SYMBOL_GPL(telemetry_set_trace_verbosity
);
327 * telemetry_set_pltdata() - Set the platform specific Data
328 * @ops: Pointer to ops structure
329 * @pltconfig: Platform config data
331 * Usage by other than telemetry pltdrv module is invalid
333 * Return: 0 success, < 0 for failure
335 int telemetry_set_pltdata(const struct telemetry_core_ops
*ops
,
336 struct telemetry_plt_config
*pltconfig
)
339 telm_core_conf
.telem_ops
= ops
;
342 telm_core_conf
.plt_config
= pltconfig
;
346 EXPORT_SYMBOL_GPL(telemetry_set_pltdata
);
349 * telemetry_clear_pltdata() - Clear the platform specific Data
351 * Usage by other than telemetry pltdrv module is invalid
353 * Return: 0 success, < 0 for failure
355 int telemetry_clear_pltdata(void)
357 telm_core_conf
.telem_ops
= &telm_defpltops
;
358 telm_core_conf
.plt_config
= NULL
;
362 EXPORT_SYMBOL_GPL(telemetry_clear_pltdata
);
365 * telemetry_pltconfig_valid() - Checkif platform config is valid
367 * Usage by other than telemetry module is invalid
369 * Return: 0 success, < 0 for failure
371 int telemetry_pltconfig_valid(void)
373 if (telm_core_conf
.plt_config
)
379 EXPORT_SYMBOL_GPL(telemetry_pltconfig_valid
);
381 static inline int telemetry_get_pssevtname(enum telemetry_unit telem_unit
,
382 const char **name
, int len
)
384 struct telemetry_unit_config psscfg
;
387 if (!telm_core_conf
.plt_config
)
390 psscfg
= telm_core_conf
.plt_config
->pss_config
;
392 if (len
> psscfg
.ssram_evts_used
)
393 len
= psscfg
.ssram_evts_used
;
395 for (i
= 0; i
< len
; i
++)
396 name
[i
] = psscfg
.telem_evts
[i
].name
;
401 static inline int telemetry_get_iossevtname(enum telemetry_unit telem_unit
,
402 const char **name
, int len
)
404 struct telemetry_unit_config iosscfg
;
407 if (!(telm_core_conf
.plt_config
))
410 iosscfg
= telm_core_conf
.plt_config
->ioss_config
;
412 if (len
> iosscfg
.ssram_evts_used
)
413 len
= iosscfg
.ssram_evts_used
;
415 for (i
= 0; i
< len
; i
++)
416 name
[i
] = iosscfg
.telem_evts
[i
].name
;
423 * telemetry_get_evtname() - Checkif platform config is valid
424 * @telem_unit: Telemetry Unit to check
425 * @name: Array of character pointers to contain name
426 * @len: length of array name provided by user
428 * Usage by other than telemetry debugfs module is invalid
430 * Return: 0 success, < 0 for failure
432 int telemetry_get_evtname(enum telemetry_unit telem_unit
,
433 const char **name
, int len
)
437 if (telem_unit
== TELEM_PSS
)
438 ret
= telemetry_get_pssevtname(telem_unit
, name
, len
);
440 else if (telem_unit
== TELEM_IOSS
)
441 ret
= telemetry_get_iossevtname(telem_unit
, name
, len
);
445 EXPORT_SYMBOL_GPL(telemetry_get_evtname
);
447 static int __init
telemetry_module_init(void)
449 pr_info(pr_fmt(DRIVER_NAME
) " Init\n");
451 telm_core_conf
.telem_ops
= &telm_defpltops
;
455 static void __exit
telemetry_module_exit(void)
459 module_init(telemetry_module_init
);
460 module_exit(telemetry_module_exit
);
462 MODULE_AUTHOR("Souvik Kumar Chakravarty <souvik.k.chakravarty@intel.com>");
463 MODULE_DESCRIPTION("Intel SoC Telemetry Interface");
464 MODULE_LICENSE("GPL");