1 // SPDX-License-Identifier: GPL-2.0
3 * Intel SoC Core Telemetry Driver
4 * Copyright (C) 2015, Intel Corporation.
7 * Telemetry Framework provides platform related PM and performance statistics.
8 * This file provides the core telemetry API implementation.
10 #include <linux/device.h>
11 #include <linux/module.h>
13 #include <asm/intel_telemetry.h>
15 #define DRIVER_NAME "intel_telemetry_core"
17 struct telemetry_core_config
{
18 struct telemetry_plt_config
*plt_config
;
19 const struct telemetry_core_ops
*telem_ops
;
22 static struct telemetry_core_config telm_core_conf
;
24 static int telemetry_def_update_events(struct telemetry_evtconfig pss_evtconfig
,
25 struct telemetry_evtconfig ioss_evtconfig
)
30 static int telemetry_def_set_sampling_period(u8 pss_period
, u8 ioss_period
)
35 static int telemetry_def_get_sampling_period(u8
*pss_min_period
,
43 static int telemetry_def_get_eventconfig(
44 struct telemetry_evtconfig
*pss_evtconfig
,
45 struct telemetry_evtconfig
*ioss_evtconfig
,
46 int pss_len
, int ioss_len
)
51 static int telemetry_def_get_trace_verbosity(enum telemetry_unit telem_unit
,
58 static int telemetry_def_set_trace_verbosity(enum telemetry_unit telem_unit
,
64 static int telemetry_def_raw_read_eventlog(enum telemetry_unit telem_unit
,
65 struct telemetry_evtlog
*evtlog
,
66 int len
, int log_all_evts
)
71 static int telemetry_def_read_eventlog(enum telemetry_unit telem_unit
,
72 struct telemetry_evtlog
*evtlog
,
73 int len
, int log_all_evts
)
78 static int telemetry_def_add_events(u8 num_pss_evts
, u8 num_ioss_evts
,
79 u32
*pss_evtmap
, u32
*ioss_evtmap
)
84 static int telemetry_def_reset_events(void)
89 static const struct telemetry_core_ops telm_defpltops
= {
90 .set_sampling_period
= telemetry_def_set_sampling_period
,
91 .get_sampling_period
= telemetry_def_get_sampling_period
,
92 .get_trace_verbosity
= telemetry_def_get_trace_verbosity
,
93 .set_trace_verbosity
= telemetry_def_set_trace_verbosity
,
94 .raw_read_eventlog
= telemetry_def_raw_read_eventlog
,
95 .get_eventconfig
= telemetry_def_get_eventconfig
,
96 .read_eventlog
= telemetry_def_read_eventlog
,
97 .update_events
= telemetry_def_update_events
,
98 .reset_events
= telemetry_def_reset_events
,
99 .add_events
= telemetry_def_add_events
,
103 * telemetry_update_events() - Update telemetry Configuration
104 * @pss_evtconfig: PSS related config. No change if num_evts = 0.
105 * @pss_evtconfig: IOSS related config. No change if num_evts = 0.
107 * This API updates the IOSS & PSS Telemetry configuration. Old config
108 * is overwritten. Call telemetry_reset_events when logging is over
109 * All sample period values should be in the form of:
110 * bits[6:3] -> value; bits [0:2]-> Exponent; Period = (Value *16^Exponent)
112 * Return: 0 success, < 0 for failure
114 int telemetry_update_events(struct telemetry_evtconfig pss_evtconfig
,
115 struct telemetry_evtconfig ioss_evtconfig
)
117 return telm_core_conf
.telem_ops
->update_events(pss_evtconfig
,
120 EXPORT_SYMBOL_GPL(telemetry_update_events
);
124 * telemetry_set_sampling_period() - Sets the IOSS & PSS sampling period
125 * @pss_period: placeholder for PSS Period to be set.
126 * Set to 0 if not required to be updated
127 * @ioss_period: placeholder for IOSS Period to be set
128 * Set to 0 if not required to be updated
130 * All values should be in the form of:
131 * bits[6:3] -> value; bits [0:2]-> Exponent; Period = (Value *16^Exponent)
133 * Return: 0 success, < 0 for failure
135 int telemetry_set_sampling_period(u8 pss_period
, u8 ioss_period
)
137 return telm_core_conf
.telem_ops
->set_sampling_period(pss_period
,
140 EXPORT_SYMBOL_GPL(telemetry_set_sampling_period
);
143 * telemetry_get_sampling_period() - Get IOSS & PSS min & max sampling period
144 * @pss_min_period: placeholder for PSS Min Period supported
145 * @pss_max_period: placeholder for PSS Max Period supported
146 * @ioss_min_period: placeholder for IOSS Min Period supported
147 * @ioss_max_period: placeholder for IOSS Max Period supported
149 * All values should be in the form of:
150 * bits[6:3] -> value; bits [0:2]-> Exponent; Period = (Value *16^Exponent)
152 * Return: 0 success, < 0 for failure
154 int telemetry_get_sampling_period(u8
*pss_min_period
, u8
*pss_max_period
,
155 u8
*ioss_min_period
, u8
*ioss_max_period
)
157 return telm_core_conf
.telem_ops
->get_sampling_period(pss_min_period
,
162 EXPORT_SYMBOL_GPL(telemetry_get_sampling_period
);
166 * telemetry_reset_events() - Restore the IOSS & PSS configuration to default
168 * Return: 0 success, < 0 for failure
170 int telemetry_reset_events(void)
172 return telm_core_conf
.telem_ops
->reset_events();
174 EXPORT_SYMBOL_GPL(telemetry_reset_events
);
177 * telemetry_get_eventconfig() - Returns the pss and ioss events enabled
178 * @pss_evtconfig: Pointer to PSS related configuration.
179 * @pss_evtconfig: Pointer to IOSS related configuration.
180 * @pss_len: Number of u32 elements allocated for pss_evtconfig array
181 * @ioss_len: Number of u32 elements allocated for ioss_evtconfig array
183 * Return: 0 success, < 0 for failure
185 int telemetry_get_eventconfig(struct telemetry_evtconfig
*pss_evtconfig
,
186 struct telemetry_evtconfig
*ioss_evtconfig
,
187 int pss_len
, int ioss_len
)
189 return telm_core_conf
.telem_ops
->get_eventconfig(pss_evtconfig
,
193 EXPORT_SYMBOL_GPL(telemetry_get_eventconfig
);
196 * telemetry_add_events() - Add IOSS & PSS configuration to existing settings.
197 * @num_pss_evts: Number of PSS Events (<29) in pss_evtmap. Can be 0.
198 * @num_ioss_evts: Number of IOSS Events (<29) in ioss_evtmap. Can be 0.
199 * @pss_evtmap: Array of PSS Event-IDs to Enable
200 * @ioss_evtmap: Array of PSS Event-IDs to Enable
202 * Events are appended to Old Configuration. In case of total events > 28, it
203 * returns error. Call telemetry_reset_events to reset after eventlog done
205 * Return: 0 success, < 0 for failure
207 int telemetry_add_events(u8 num_pss_evts
, u8 num_ioss_evts
,
208 u32
*pss_evtmap
, u32
*ioss_evtmap
)
210 return telm_core_conf
.telem_ops
->add_events(num_pss_evts
,
211 num_ioss_evts
, pss_evtmap
,
214 EXPORT_SYMBOL_GPL(telemetry_add_events
);
217 * telemetry_read_events() - Fetches samples as specified by evtlog.telem_evt_id
218 * @telem_unit: Specify whether IOSS or PSS Read
219 * @evtlog: Array of telemetry_evtlog structs to fill data
220 * evtlog.telem_evt_id specifies the ids to read
221 * @len: Length of array of evtlog
223 * Return: number of eventlogs read for success, < 0 for failure
225 int telemetry_read_events(enum telemetry_unit telem_unit
,
226 struct telemetry_evtlog
*evtlog
, int len
)
228 return telm_core_conf
.telem_ops
->read_eventlog(telem_unit
, evtlog
,
231 EXPORT_SYMBOL_GPL(telemetry_read_events
);
234 * telemetry_raw_read_events() - Fetch samples specified by evtlog.telem_evt_id
235 * @telem_unit: Specify whether IOSS or PSS Read
236 * @evtlog: Array of telemetry_evtlog structs to fill data
237 * evtlog.telem_evt_id specifies the ids to read
238 * @len: Length of array of evtlog
240 * The caller must take care of locking in this case.
242 * Return: number of eventlogs read for success, < 0 for failure
244 int telemetry_raw_read_events(enum telemetry_unit telem_unit
,
245 struct telemetry_evtlog
*evtlog
, int len
)
247 return telm_core_conf
.telem_ops
->raw_read_eventlog(telem_unit
, evtlog
,
250 EXPORT_SYMBOL_GPL(telemetry_raw_read_events
);
253 * telemetry_read_eventlog() - Fetch the Telemetry log from PSS or IOSS
254 * @telem_unit: Specify whether IOSS or PSS Read
255 * @evtlog: Array of telemetry_evtlog structs to fill data
256 * @len: Length of array of evtlog
258 * Return: number of eventlogs read for success, < 0 for failure
260 int telemetry_read_eventlog(enum telemetry_unit telem_unit
,
261 struct telemetry_evtlog
*evtlog
, int len
)
263 return telm_core_conf
.telem_ops
->read_eventlog(telem_unit
, evtlog
,
266 EXPORT_SYMBOL_GPL(telemetry_read_eventlog
);
269 * telemetry_raw_read_eventlog() - Fetch the Telemetry log from PSS or IOSS
270 * @telem_unit: Specify whether IOSS or PSS Read
271 * @evtlog: Array of telemetry_evtlog structs to fill data
272 * @len: Length of array of evtlog
274 * The caller must take care of locking in this case.
276 * Return: number of eventlogs read for success, < 0 for failure
278 int telemetry_raw_read_eventlog(enum telemetry_unit telem_unit
,
279 struct telemetry_evtlog
*evtlog
, int len
)
281 return telm_core_conf
.telem_ops
->raw_read_eventlog(telem_unit
, evtlog
,
284 EXPORT_SYMBOL_GPL(telemetry_raw_read_eventlog
);
288 * telemetry_get_trace_verbosity() - Get the IOSS & PSS Trace verbosity
289 * @telem_unit: Specify whether IOSS or PSS Read
290 * @verbosity: Pointer to return Verbosity
292 * Return: 0 success, < 0 for failure
294 int telemetry_get_trace_verbosity(enum telemetry_unit telem_unit
,
297 return telm_core_conf
.telem_ops
->get_trace_verbosity(telem_unit
,
300 EXPORT_SYMBOL_GPL(telemetry_get_trace_verbosity
);
304 * telemetry_set_trace_verbosity() - Update the IOSS & PSS Trace verbosity
305 * @telem_unit: Specify whether IOSS or PSS Read
306 * @verbosity: Verbosity to set
308 * Return: 0 success, < 0 for failure
310 int telemetry_set_trace_verbosity(enum telemetry_unit telem_unit
, u32 verbosity
)
312 return telm_core_conf
.telem_ops
->set_trace_verbosity(telem_unit
,
315 EXPORT_SYMBOL_GPL(telemetry_set_trace_verbosity
);
318 * telemetry_set_pltdata() - Set the platform specific Data
319 * @ops: Pointer to ops structure
320 * @pltconfig: Platform config data
322 * Usage by other than telemetry pltdrv module is invalid
324 * Return: 0 success, < 0 for failure
326 int telemetry_set_pltdata(const struct telemetry_core_ops
*ops
,
327 struct telemetry_plt_config
*pltconfig
)
330 telm_core_conf
.telem_ops
= ops
;
333 telm_core_conf
.plt_config
= pltconfig
;
337 EXPORT_SYMBOL_GPL(telemetry_set_pltdata
);
340 * telemetry_clear_pltdata() - Clear the platform specific Data
342 * Usage by other than telemetry pltdrv module is invalid
344 * Return: 0 success, < 0 for failure
346 int telemetry_clear_pltdata(void)
348 telm_core_conf
.telem_ops
= &telm_defpltops
;
349 telm_core_conf
.plt_config
= NULL
;
353 EXPORT_SYMBOL_GPL(telemetry_clear_pltdata
);
356 * telemetry_pltconfig_valid() - Checkif platform config is valid
358 * Usage by other than telemetry module is invalid
360 * Return: 0 success, < 0 for failure
362 int telemetry_pltconfig_valid(void)
364 if (telm_core_conf
.plt_config
)
370 EXPORT_SYMBOL_GPL(telemetry_pltconfig_valid
);
372 static inline int telemetry_get_pssevtname(enum telemetry_unit telem_unit
,
373 const char **name
, int len
)
375 struct telemetry_unit_config psscfg
;
378 if (!telm_core_conf
.plt_config
)
381 psscfg
= telm_core_conf
.plt_config
->pss_config
;
383 if (len
> psscfg
.ssram_evts_used
)
384 len
= psscfg
.ssram_evts_used
;
386 for (i
= 0; i
< len
; i
++)
387 name
[i
] = psscfg
.telem_evts
[i
].name
;
392 static inline int telemetry_get_iossevtname(enum telemetry_unit telem_unit
,
393 const char **name
, int len
)
395 struct telemetry_unit_config iosscfg
;
398 if (!(telm_core_conf
.plt_config
))
401 iosscfg
= telm_core_conf
.plt_config
->ioss_config
;
403 if (len
> iosscfg
.ssram_evts_used
)
404 len
= iosscfg
.ssram_evts_used
;
406 for (i
= 0; i
< len
; i
++)
407 name
[i
] = iosscfg
.telem_evts
[i
].name
;
414 * telemetry_get_evtname() - Checkif platform config is valid
415 * @telem_unit: Telemetry Unit to check
416 * @name: Array of character pointers to contain name
417 * @len: length of array name provided by user
419 * Usage by other than telemetry debugfs module is invalid
421 * Return: 0 success, < 0 for failure
423 int telemetry_get_evtname(enum telemetry_unit telem_unit
,
424 const char **name
, int len
)
428 if (telem_unit
== TELEM_PSS
)
429 ret
= telemetry_get_pssevtname(telem_unit
, name
, len
);
431 else if (telem_unit
== TELEM_IOSS
)
432 ret
= telemetry_get_iossevtname(telem_unit
, name
, len
);
436 EXPORT_SYMBOL_GPL(telemetry_get_evtname
);
438 static int __init
telemetry_module_init(void)
440 pr_info(pr_fmt(DRIVER_NAME
) " Init\n");
442 telm_core_conf
.telem_ops
= &telm_defpltops
;
446 static void __exit
telemetry_module_exit(void)
450 module_init(telemetry_module_init
);
451 module_exit(telemetry_module_exit
);
453 MODULE_AUTHOR("Souvik Kumar Chakravarty <souvik.k.chakravarty@intel.com>");
454 MODULE_DESCRIPTION("Intel SoC Telemetry Interface");
455 MODULE_LICENSE("GPL v2");