451 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Intel SoC Core Telemetry Driver4 * Copyright (C) 2015, Intel Corporation.5 * All Rights Reserved.6 *7 * Telemetry Framework provides platform related PM and performance statistics.8 * This file provides the core telemetry API implementation.9 */10#include <linux/device.h>11#include <linux/module.h>12 13#include <asm/intel_telemetry.h>14 15#define DRIVER_NAME "intel_telemetry_core"16 17struct telemetry_core_config {18 struct telemetry_plt_config *plt_config;19 const struct telemetry_core_ops *telem_ops;20};21 22static struct telemetry_core_config telm_core_conf;23 24static int telemetry_def_update_events(struct telemetry_evtconfig pss_evtconfig,25 struct telemetry_evtconfig ioss_evtconfig)26{27 return 0;28}29 30static int telemetry_def_set_sampling_period(u8 pss_period, u8 ioss_period)31{32 return 0;33}34 35static int telemetry_def_get_sampling_period(u8 *pss_min_period,36 u8 *pss_max_period,37 u8 *ioss_min_period,38 u8 *ioss_max_period)39{40 return 0;41}42 43static int telemetry_def_get_eventconfig(44 struct telemetry_evtconfig *pss_evtconfig,45 struct telemetry_evtconfig *ioss_evtconfig,46 int pss_len, int ioss_len)47{48 return 0;49}50 51static int telemetry_def_get_trace_verbosity(enum telemetry_unit telem_unit,52 u32 *verbosity)53{54 return 0;55}56 57 58static int telemetry_def_set_trace_verbosity(enum telemetry_unit telem_unit,59 u32 verbosity)60{61 return 0;62}63 64static int telemetry_def_raw_read_eventlog(enum telemetry_unit telem_unit,65 struct telemetry_evtlog *evtlog,66 int len, int log_all_evts)67{68 return 0;69}70 71static int telemetry_def_read_eventlog(enum telemetry_unit telem_unit,72 struct telemetry_evtlog *evtlog,73 int len, int log_all_evts)74{75 return 0;76}77 78static int telemetry_def_add_events(u8 num_pss_evts, u8 num_ioss_evts,79 u32 *pss_evtmap, u32 *ioss_evtmap)80{81 return 0;82}83 84static int telemetry_def_reset_events(void)85{86 return 0;87}88 89static 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,100};101 102/**103 * telemetry_update_events() - Update telemetry Configuration104 * @pss_evtconfig: PSS related config. No change if num_evts = 0.105 * @ioss_evtconfig: IOSS related config. No change if num_evts = 0.106 *107 * This API updates the IOSS & PSS Telemetry configuration. Old config108 * is overwritten. Call telemetry_reset_events when logging is over109 * All sample period values should be in the form of:110 * bits[6:3] -> value; bits [0:2]-> Exponent; Period = (Value *16^Exponent)111 *112 * Return: 0 success, < 0 for failure113 */114int telemetry_update_events(struct telemetry_evtconfig pss_evtconfig,115 struct telemetry_evtconfig ioss_evtconfig)116{117 return telm_core_conf.telem_ops->update_events(pss_evtconfig,118 ioss_evtconfig);119}120EXPORT_SYMBOL_GPL(telemetry_update_events);121 122 123/**124 * telemetry_set_sampling_period() - Sets the IOSS & PSS sampling period125 * @pss_period: placeholder for PSS Period to be set.126 * Set to 0 if not required to be updated127 * @ioss_period: placeholder for IOSS Period to be set128 * Set to 0 if not required to be updated129 *130 * All values should be in the form of:131 * bits[6:3] -> value; bits [0:2]-> Exponent; Period = (Value *16^Exponent)132 *133 * Return: 0 success, < 0 for failure134 */135int telemetry_set_sampling_period(u8 pss_period, u8 ioss_period)136{137 return telm_core_conf.telem_ops->set_sampling_period(pss_period,138 ioss_period);139}140EXPORT_SYMBOL_GPL(telemetry_set_sampling_period);141 142/**143 * telemetry_get_sampling_period() - Get IOSS & PSS min & max sampling period144 * @pss_min_period: placeholder for PSS Min Period supported145 * @pss_max_period: placeholder for PSS Max Period supported146 * @ioss_min_period: placeholder for IOSS Min Period supported147 * @ioss_max_period: placeholder for IOSS Max Period supported148 *149 * All values should be in the form of:150 * bits[6:3] -> value; bits [0:2]-> Exponent; Period = (Value *16^Exponent)151 *152 * Return: 0 success, < 0 for failure153 */154int telemetry_get_sampling_period(u8 *pss_min_period, u8 *pss_max_period,155 u8 *ioss_min_period, u8 *ioss_max_period)156{157 return telm_core_conf.telem_ops->get_sampling_period(pss_min_period,158 pss_max_period,159 ioss_min_period,160 ioss_max_period);161}162EXPORT_SYMBOL_GPL(telemetry_get_sampling_period);163 164 165/**166 * telemetry_reset_events() - Restore the IOSS & PSS configuration to default167 *168 * Return: 0 success, < 0 for failure169 */170int telemetry_reset_events(void)171{172 return telm_core_conf.telem_ops->reset_events();173}174EXPORT_SYMBOL_GPL(telemetry_reset_events);175 176/**177 * telemetry_get_eventconfig() - Returns the pss and ioss events enabled178 * @pss_evtconfig: Pointer to PSS related configuration.179 * @ioss_evtconfig: Pointer to IOSS related configuration.180 * @pss_len: Number of u32 elements allocated for pss_evtconfig array181 * @ioss_len: Number of u32 elements allocated for ioss_evtconfig array182 *183 * Return: 0 success, < 0 for failure184 */185int telemetry_get_eventconfig(struct telemetry_evtconfig *pss_evtconfig,186 struct telemetry_evtconfig *ioss_evtconfig,187 int pss_len, int ioss_len)188{189 return telm_core_conf.telem_ops->get_eventconfig(pss_evtconfig,190 ioss_evtconfig,191 pss_len, ioss_len);192}193EXPORT_SYMBOL_GPL(telemetry_get_eventconfig);194 195/**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 Enable200 * @ioss_evtmap: Array of PSS Event-IDs to Enable201 *202 * Events are appended to Old Configuration. In case of total events > 28, it203 * returns error. Call telemetry_reset_events to reset after eventlog done204 *205 * Return: 0 success, < 0 for failure206 */207int telemetry_add_events(u8 num_pss_evts, u8 num_ioss_evts,208 u32 *pss_evtmap, u32 *ioss_evtmap)209{210 return telm_core_conf.telem_ops->add_events(num_pss_evts,211 num_ioss_evts, pss_evtmap,212 ioss_evtmap);213}214EXPORT_SYMBOL_GPL(telemetry_add_events);215 216/**217 * telemetry_read_events() - Fetches samples as specified by evtlog.telem_evt_id218 * @telem_unit: Specify whether IOSS or PSS Read219 * @evtlog: Array of telemetry_evtlog structs to fill data220 * evtlog.telem_evt_id specifies the ids to read221 * @len: Length of array of evtlog222 *223 * Return: number of eventlogs read for success, < 0 for failure224 */225int telemetry_read_events(enum telemetry_unit telem_unit,226 struct telemetry_evtlog *evtlog, int len)227{228 return telm_core_conf.telem_ops->read_eventlog(telem_unit, evtlog,229 len, 0);230}231EXPORT_SYMBOL_GPL(telemetry_read_events);232 233/**234 * telemetry_raw_read_events() - Fetch samples specified by evtlog.telem_evt_id235 * @telem_unit: Specify whether IOSS or PSS Read236 * @evtlog: Array of telemetry_evtlog structs to fill data237 * evtlog.telem_evt_id specifies the ids to read238 * @len: Length of array of evtlog239 *240 * The caller must take care of locking in this case.241 *242 * Return: number of eventlogs read for success, < 0 for failure243 */244int telemetry_raw_read_events(enum telemetry_unit telem_unit,245 struct telemetry_evtlog *evtlog, int len)246{247 return telm_core_conf.telem_ops->raw_read_eventlog(telem_unit, evtlog,248 len, 0);249}250EXPORT_SYMBOL_GPL(telemetry_raw_read_events);251 252/**253 * telemetry_read_eventlog() - Fetch the Telemetry log from PSS or IOSS254 * @telem_unit: Specify whether IOSS or PSS Read255 * @evtlog: Array of telemetry_evtlog structs to fill data256 * @len: Length of array of evtlog257 *258 * Return: number of eventlogs read for success, < 0 for failure259 */260int telemetry_read_eventlog(enum telemetry_unit telem_unit,261 struct telemetry_evtlog *evtlog, int len)262{263 return telm_core_conf.telem_ops->read_eventlog(telem_unit, evtlog,264 len, 1);265}266EXPORT_SYMBOL_GPL(telemetry_read_eventlog);267 268/**269 * telemetry_raw_read_eventlog() - Fetch the Telemetry log from PSS or IOSS270 * @telem_unit: Specify whether IOSS or PSS Read271 * @evtlog: Array of telemetry_evtlog structs to fill data272 * @len: Length of array of evtlog273 *274 * The caller must take care of locking in this case.275 *276 * Return: number of eventlogs read for success, < 0 for failure277 */278int telemetry_raw_read_eventlog(enum telemetry_unit telem_unit,279 struct telemetry_evtlog *evtlog, int len)280{281 return telm_core_conf.telem_ops->raw_read_eventlog(telem_unit, evtlog,282 len, 1);283}284EXPORT_SYMBOL_GPL(telemetry_raw_read_eventlog);285 286 287/**288 * telemetry_get_trace_verbosity() - Get the IOSS & PSS Trace verbosity289 * @telem_unit: Specify whether IOSS or PSS Read290 * @verbosity: Pointer to return Verbosity291 *292 * Return: 0 success, < 0 for failure293 */294int telemetry_get_trace_verbosity(enum telemetry_unit telem_unit,295 u32 *verbosity)296{297 return telm_core_conf.telem_ops->get_trace_verbosity(telem_unit,298 verbosity);299}300EXPORT_SYMBOL_GPL(telemetry_get_trace_verbosity);301 302 303/**304 * telemetry_set_trace_verbosity() - Update the IOSS & PSS Trace verbosity305 * @telem_unit: Specify whether IOSS or PSS Read306 * @verbosity: Verbosity to set307 *308 * Return: 0 success, < 0 for failure309 */310int telemetry_set_trace_verbosity(enum telemetry_unit telem_unit, u32 verbosity)311{312 return telm_core_conf.telem_ops->set_trace_verbosity(telem_unit,313 verbosity);314}315EXPORT_SYMBOL_GPL(telemetry_set_trace_verbosity);316 317/**318 * telemetry_set_pltdata() - Set the platform specific Data319 * @ops: Pointer to ops structure320 * @pltconfig: Platform config data321 *322 * Usage by other than telemetry pltdrv module is invalid323 *324 * Return: 0 success, < 0 for failure325 */326int telemetry_set_pltdata(const struct telemetry_core_ops *ops,327 struct telemetry_plt_config *pltconfig)328{329 if (ops)330 telm_core_conf.telem_ops = ops;331 332 if (pltconfig)333 telm_core_conf.plt_config = pltconfig;334 335 return 0;336}337EXPORT_SYMBOL_GPL(telemetry_set_pltdata);338 339/**340 * telemetry_clear_pltdata() - Clear the platform specific Data341 *342 * Usage by other than telemetry pltdrv module is invalid343 *344 * Return: 0 success, < 0 for failure345 */346int telemetry_clear_pltdata(void)347{348 telm_core_conf.telem_ops = &telm_defpltops;349 telm_core_conf.plt_config = NULL;350 351 return 0;352}353EXPORT_SYMBOL_GPL(telemetry_clear_pltdata);354 355/**356 * telemetry_get_pltdata() - Return telemetry platform config357 *358 * May be used by other telemetry modules to get platform specific359 * configuration.360 */361struct telemetry_plt_config *telemetry_get_pltdata(void)362{363 return telm_core_conf.plt_config;364}365EXPORT_SYMBOL_GPL(telemetry_get_pltdata);366 367static inline int telemetry_get_pssevtname(enum telemetry_unit telem_unit,368 const char **name, int len)369{370 struct telemetry_unit_config psscfg;371 int i;372 373 if (!telm_core_conf.plt_config)374 return -EINVAL;375 376 psscfg = telm_core_conf.plt_config->pss_config;377 378 if (len > psscfg.ssram_evts_used)379 len = psscfg.ssram_evts_used;380 381 for (i = 0; i < len; i++)382 name[i] = psscfg.telem_evts[i].name;383 384 return 0;385}386 387static inline int telemetry_get_iossevtname(enum telemetry_unit telem_unit,388 const char **name, int len)389{390 struct telemetry_unit_config iosscfg;391 int i;392 393 if (!(telm_core_conf.plt_config))394 return -EINVAL;395 396 iosscfg = telm_core_conf.plt_config->ioss_config;397 398 if (len > iosscfg.ssram_evts_used)399 len = iosscfg.ssram_evts_used;400 401 for (i = 0; i < len; i++)402 name[i] = iosscfg.telem_evts[i].name;403 404 return 0;405 406}407 408/**409 * telemetry_get_evtname() - Checkif platform config is valid410 * @telem_unit: Telemetry Unit to check411 * @name: Array of character pointers to contain name412 * @len: length of array name provided by user413 *414 * Usage by other than telemetry debugfs module is invalid415 *416 * Return: 0 success, < 0 for failure417 */418int telemetry_get_evtname(enum telemetry_unit telem_unit,419 const char **name, int len)420{421 int ret = -EINVAL;422 423 if (telem_unit == TELEM_PSS)424 ret = telemetry_get_pssevtname(telem_unit, name, len);425 426 else if (telem_unit == TELEM_IOSS)427 ret = telemetry_get_iossevtname(telem_unit, name, len);428 429 return ret;430}431EXPORT_SYMBOL_GPL(telemetry_get_evtname);432 433static int __init telemetry_module_init(void)434{435 pr_info(pr_fmt(DRIVER_NAME) " Init\n");436 437 telm_core_conf.telem_ops = &telm_defpltops;438 return 0;439}440 441static void __exit telemetry_module_exit(void)442{443}444 445module_init(telemetry_module_init);446module_exit(telemetry_module_exit);447 448MODULE_AUTHOR("Souvik Kumar Chakravarty <souvik.k.chakravarty@intel.com>");449MODULE_DESCRIPTION("Intel SoC Telemetry Interface");450MODULE_LICENSE("GPL v2");451