intel_telemetry_core.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465
  1. /*
  2. * Intel SoC Core Telemetry Driver
  3. * Copyright (C) 2015, Intel Corporation.
  4. * All Rights Reserved.
  5. *
  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.
  9. *
  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
  13. * more details.
  14. *
  15. * Telemetry Framework provides platform related PM and performance statistics.
  16. * This file provides the core telemetry API implementation.
  17. */
  18. #include <linux/module.h>
  19. #include <linux/init.h>
  20. #include <linux/device.h>
  21. #include <asm/intel_telemetry.h>
  22. #define DRIVER_NAME "intel_telemetry_core"
  23. struct telemetry_core_config {
  24. struct telemetry_plt_config *plt_config;
  25. const struct telemetry_core_ops *telem_ops;
  26. };
  27. static struct telemetry_core_config telm_core_conf;
  28. static int telemetry_def_update_events(struct telemetry_evtconfig pss_evtconfig,
  29. struct telemetry_evtconfig ioss_evtconfig)
  30. {
  31. return 0;
  32. }
  33. static int telemetry_def_set_sampling_period(u8 pss_period, u8 ioss_period)
  34. {
  35. return 0;
  36. }
  37. static int telemetry_def_get_sampling_period(u8 *pss_min_period,
  38. u8 *pss_max_period,
  39. u8 *ioss_min_period,
  40. u8 *ioss_max_period)
  41. {
  42. return 0;
  43. }
  44. static int telemetry_def_get_eventconfig(
  45. struct telemetry_evtconfig *pss_evtconfig,
  46. struct telemetry_evtconfig *ioss_evtconfig,
  47. int pss_len, int ioss_len)
  48. {
  49. return 0;
  50. }
  51. static int telemetry_def_get_trace_verbosity(enum telemetry_unit telem_unit,
  52. u32 *verbosity)
  53. {
  54. return 0;
  55. }
  56. static int telemetry_def_set_trace_verbosity(enum telemetry_unit telem_unit,
  57. u32 verbosity)
  58. {
  59. return 0;
  60. }
  61. static int telemetry_def_raw_read_eventlog(enum telemetry_unit telem_unit,
  62. struct telemetry_evtlog *evtlog,
  63. int len, int log_all_evts)
  64. {
  65. return 0;
  66. }
  67. static int telemetry_def_read_eventlog(enum telemetry_unit telem_unit,
  68. struct telemetry_evtlog *evtlog,
  69. int len, int log_all_evts)
  70. {
  71. return 0;
  72. }
  73. static int telemetry_def_add_events(u8 num_pss_evts, u8 num_ioss_evts,
  74. u32 *pss_evtmap, u32 *ioss_evtmap)
  75. {
  76. return 0;
  77. }
  78. static int telemetry_def_reset_events(void)
  79. {
  80. return 0;
  81. }
  82. static const struct telemetry_core_ops telm_defpltops = {
  83. .set_sampling_period = telemetry_def_set_sampling_period,
  84. .get_sampling_period = telemetry_def_get_sampling_period,
  85. .get_trace_verbosity = telemetry_def_get_trace_verbosity,
  86. .set_trace_verbosity = telemetry_def_set_trace_verbosity,
  87. .raw_read_eventlog = telemetry_def_raw_read_eventlog,
  88. .get_eventconfig = telemetry_def_get_eventconfig,
  89. .read_eventlog = telemetry_def_read_eventlog,
  90. .update_events = telemetry_def_update_events,
  91. .reset_events = telemetry_def_reset_events,
  92. .add_events = telemetry_def_add_events,
  93. };
  94. /**
  95. * telemetry_update_events() - Update telemetry Configuration
  96. * @pss_evtconfig: PSS related config. No change if num_evts = 0.
  97. * @pss_evtconfig: IOSS related config. No change if num_evts = 0.
  98. *
  99. * This API updates the IOSS & PSS Telemetry configuration. Old config
  100. * is overwritten. Call telemetry_reset_events when logging is over
  101. * All sample period values should be in the form of:
  102. * bits[6:3] -> value; bits [0:2]-> Exponent; Period = (Value *16^Exponent)
  103. *
  104. * Return: 0 success, < 0 for failure
  105. */
  106. int telemetry_update_events(struct telemetry_evtconfig pss_evtconfig,
  107. struct telemetry_evtconfig ioss_evtconfig)
  108. {
  109. return telm_core_conf.telem_ops->update_events(pss_evtconfig,
  110. ioss_evtconfig);
  111. }
  112. EXPORT_SYMBOL_GPL(telemetry_update_events);
  113. /**
  114. * telemetry_set_sampling_period() - Sets the IOSS & PSS sampling period
  115. * @pss_period: placeholder for PSS Period to be set.
  116. * Set to 0 if not required to be updated
  117. * @ioss_period: placeholder for IOSS Period to be set
  118. * Set to 0 if not required to be updated
  119. *
  120. * All values should be in the form of:
  121. * bits[6:3] -> value; bits [0:2]-> Exponent; Period = (Value *16^Exponent)
  122. *
  123. * Return: 0 success, < 0 for failure
  124. */
  125. int telemetry_set_sampling_period(u8 pss_period, u8 ioss_period)
  126. {
  127. return telm_core_conf.telem_ops->set_sampling_period(pss_period,
  128. ioss_period);
  129. }
  130. EXPORT_SYMBOL_GPL(telemetry_set_sampling_period);
  131. /**
  132. * telemetry_get_sampling_period() - Get IOSS & PSS min & max sampling period
  133. * @pss_min_period: placeholder for PSS Min Period supported
  134. * @pss_max_period: placeholder for PSS Max Period supported
  135. * @ioss_min_period: placeholder for IOSS Min Period supported
  136. * @ioss_max_period: placeholder for IOSS Max Period supported
  137. *
  138. * All values should be in the form of:
  139. * bits[6:3] -> value; bits [0:2]-> Exponent; Period = (Value *16^Exponent)
  140. *
  141. * Return: 0 success, < 0 for failure
  142. */
  143. int telemetry_get_sampling_period(u8 *pss_min_period, u8 *pss_max_period,
  144. u8 *ioss_min_period, u8 *ioss_max_period)
  145. {
  146. return telm_core_conf.telem_ops->get_sampling_period(pss_min_period,
  147. pss_max_period,
  148. ioss_min_period,
  149. ioss_max_period);
  150. }
  151. EXPORT_SYMBOL_GPL(telemetry_get_sampling_period);
  152. /**
  153. * telemetry_reset_events() - Restore the IOSS & PSS configuration to default
  154. *
  155. * Return: 0 success, < 0 for failure
  156. */
  157. int telemetry_reset_events(void)
  158. {
  159. return telm_core_conf.telem_ops->reset_events();
  160. }
  161. EXPORT_SYMBOL_GPL(telemetry_reset_events);
  162. /**
  163. * telemetry_get_eventconfig() - Returns the pss and ioss events enabled
  164. * @pss_evtconfig: Pointer to PSS related configuration.
  165. * @pss_evtconfig: Pointer to IOSS related configuration.
  166. * @pss_len: Number of u32 elements allocated for pss_evtconfig array
  167. * @ioss_len: Number of u32 elements allocated for ioss_evtconfig array
  168. *
  169. * Return: 0 success, < 0 for failure
  170. */
  171. int telemetry_get_eventconfig(struct telemetry_evtconfig *pss_evtconfig,
  172. struct telemetry_evtconfig *ioss_evtconfig,
  173. int pss_len, int ioss_len)
  174. {
  175. return telm_core_conf.telem_ops->get_eventconfig(pss_evtconfig,
  176. ioss_evtconfig,
  177. pss_len, ioss_len);
  178. }
  179. EXPORT_SYMBOL_GPL(telemetry_get_eventconfig);
  180. /**
  181. * telemetry_add_events() - Add IOSS & PSS configuration to existing settings.
  182. * @num_pss_evts: Number of PSS Events (<29) in pss_evtmap. Can be 0.
  183. * @num_ioss_evts: Number of IOSS Events (<29) in ioss_evtmap. Can be 0.
  184. * @pss_evtmap: Array of PSS Event-IDs to Enable
  185. * @ioss_evtmap: Array of PSS Event-IDs to Enable
  186. *
  187. * Events are appended to Old Configuration. In case of total events > 28, it
  188. * returns error. Call telemetry_reset_events to reset after eventlog done
  189. *
  190. * Return: 0 success, < 0 for failure
  191. */
  192. int telemetry_add_events(u8 num_pss_evts, u8 num_ioss_evts,
  193. u32 *pss_evtmap, u32 *ioss_evtmap)
  194. {
  195. return telm_core_conf.telem_ops->add_events(num_pss_evts,
  196. num_ioss_evts, pss_evtmap,
  197. ioss_evtmap);
  198. }
  199. EXPORT_SYMBOL_GPL(telemetry_add_events);
  200. /**
  201. * telemetry_read_events() - Fetches samples as specified by evtlog.telem_evt_id
  202. * @telem_unit: Specify whether IOSS or PSS Read
  203. * @evtlog: Array of telemetry_evtlog structs to fill data
  204. * evtlog.telem_evt_id specifies the ids to read
  205. * @len: Length of array of evtlog
  206. *
  207. * Return: number of eventlogs read for success, < 0 for failure
  208. */
  209. int telemetry_read_events(enum telemetry_unit telem_unit,
  210. struct telemetry_evtlog *evtlog, int len)
  211. {
  212. return telm_core_conf.telem_ops->read_eventlog(telem_unit, evtlog,
  213. len, 0);
  214. }
  215. EXPORT_SYMBOL_GPL(telemetry_read_events);
  216. /**
  217. * telemetry_raw_read_events() - Fetch samples 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
  222. *
  223. * The caller must take care of locking in this case.
  224. *
  225. * Return: number of eventlogs read for success, < 0 for failure
  226. */
  227. int telemetry_raw_read_events(enum telemetry_unit telem_unit,
  228. struct telemetry_evtlog *evtlog, int len)
  229. {
  230. return telm_core_conf.telem_ops->raw_read_eventlog(telem_unit, evtlog,
  231. len, 0);
  232. }
  233. EXPORT_SYMBOL_GPL(telemetry_raw_read_events);
  234. /**
  235. * telemetry_read_eventlog() - Fetch the Telemetry log from PSS or IOSS
  236. * @telem_unit: Specify whether IOSS or PSS Read
  237. * @evtlog: Array of telemetry_evtlog structs to fill data
  238. * @len: Length of array of evtlog
  239. *
  240. * Return: number of eventlogs read for success, < 0 for failure
  241. */
  242. int telemetry_read_eventlog(enum telemetry_unit telem_unit,
  243. struct telemetry_evtlog *evtlog, int len)
  244. {
  245. return telm_core_conf.telem_ops->read_eventlog(telem_unit, evtlog,
  246. len, 1);
  247. }
  248. EXPORT_SYMBOL_GPL(telemetry_read_eventlog);
  249. /**
  250. * telemetry_raw_read_eventlog() - Fetch the Telemetry log from PSS or IOSS
  251. * @telem_unit: Specify whether IOSS or PSS Read
  252. * @evtlog: Array of telemetry_evtlog structs to fill data
  253. * @len: Length of array of evtlog
  254. *
  255. * The caller must take care of locking in this case.
  256. *
  257. * Return: number of eventlogs read for success, < 0 for failure
  258. */
  259. int telemetry_raw_read_eventlog(enum telemetry_unit telem_unit,
  260. struct telemetry_evtlog *evtlog, int len)
  261. {
  262. return telm_core_conf.telem_ops->raw_read_eventlog(telem_unit, evtlog,
  263. len, 1);
  264. }
  265. EXPORT_SYMBOL_GPL(telemetry_raw_read_eventlog);
  266. /**
  267. * telemetry_get_trace_verbosity() - Get the IOSS & PSS Trace verbosity
  268. * @telem_unit: Specify whether IOSS or PSS Read
  269. * @verbosity: Pointer to return Verbosity
  270. *
  271. * Return: 0 success, < 0 for failure
  272. */
  273. int telemetry_get_trace_verbosity(enum telemetry_unit telem_unit,
  274. u32 *verbosity)
  275. {
  276. return telm_core_conf.telem_ops->get_trace_verbosity(telem_unit,
  277. verbosity);
  278. }
  279. EXPORT_SYMBOL_GPL(telemetry_get_trace_verbosity);
  280. /**
  281. * telemetry_set_trace_verbosity() - Update the IOSS & PSS Trace verbosity
  282. * @telem_unit: Specify whether IOSS or PSS Read
  283. * @verbosity: Verbosity to set
  284. *
  285. * Return: 0 success, < 0 for failure
  286. */
  287. int telemetry_set_trace_verbosity(enum telemetry_unit telem_unit, u32 verbosity)
  288. {
  289. return telm_core_conf.telem_ops->set_trace_verbosity(telem_unit,
  290. verbosity);
  291. }
  292. EXPORT_SYMBOL_GPL(telemetry_set_trace_verbosity);
  293. /**
  294. * telemetry_set_pltdata() - Set the platform specific Data
  295. * @ops: Pointer to ops structure
  296. * @pltconfig: Platform config data
  297. *
  298. * Usage by other than telemetry pltdrv module is invalid
  299. *
  300. * Return: 0 success, < 0 for failure
  301. */
  302. int telemetry_set_pltdata(const struct telemetry_core_ops *ops,
  303. struct telemetry_plt_config *pltconfig)
  304. {
  305. if (ops)
  306. telm_core_conf.telem_ops = ops;
  307. if (pltconfig)
  308. telm_core_conf.plt_config = pltconfig;
  309. return 0;
  310. }
  311. EXPORT_SYMBOL_GPL(telemetry_set_pltdata);
  312. /**
  313. * telemetry_clear_pltdata() - Clear the platform specific Data
  314. *
  315. * Usage by other than telemetry pltdrv module is invalid
  316. *
  317. * Return: 0 success, < 0 for failure
  318. */
  319. int telemetry_clear_pltdata(void)
  320. {
  321. telm_core_conf.telem_ops = &telm_defpltops;
  322. telm_core_conf.plt_config = NULL;
  323. return 0;
  324. }
  325. EXPORT_SYMBOL_GPL(telemetry_clear_pltdata);
  326. /**
  327. * telemetry_pltconfig_valid() - Checkif platform config is valid
  328. *
  329. * Usage by other than telemetry module is invalid
  330. *
  331. * Return: 0 success, < 0 for failure
  332. */
  333. int telemetry_pltconfig_valid(void)
  334. {
  335. if (telm_core_conf.plt_config)
  336. return 0;
  337. else
  338. return -EINVAL;
  339. }
  340. EXPORT_SYMBOL_GPL(telemetry_pltconfig_valid);
  341. static inline int telemetry_get_pssevtname(enum telemetry_unit telem_unit,
  342. const char **name, int len)
  343. {
  344. struct telemetry_unit_config psscfg;
  345. int i;
  346. if (!telm_core_conf.plt_config)
  347. return -EINVAL;
  348. psscfg = telm_core_conf.plt_config->pss_config;
  349. if (len > psscfg.ssram_evts_used)
  350. len = psscfg.ssram_evts_used;
  351. for (i = 0; i < len; i++)
  352. name[i] = psscfg.telem_evts[i].name;
  353. return 0;
  354. }
  355. static inline int telemetry_get_iossevtname(enum telemetry_unit telem_unit,
  356. const char **name, int len)
  357. {
  358. struct telemetry_unit_config iosscfg;
  359. int i;
  360. if (!(telm_core_conf.plt_config))
  361. return -EINVAL;
  362. iosscfg = telm_core_conf.plt_config->ioss_config;
  363. if (len > iosscfg.ssram_evts_used)
  364. len = iosscfg.ssram_evts_used;
  365. for (i = 0; i < len; i++)
  366. name[i] = iosscfg.telem_evts[i].name;
  367. return 0;
  368. }
  369. /**
  370. * telemetry_get_evtname() - Checkif platform config is valid
  371. * @telem_unit: Telemetry Unit to check
  372. * @name: Array of character pointers to contain name
  373. * @len: length of array name provided by user
  374. *
  375. * Usage by other than telemetry debugfs module is invalid
  376. *
  377. * Return: 0 success, < 0 for failure
  378. */
  379. int telemetry_get_evtname(enum telemetry_unit telem_unit,
  380. const char **name, int len)
  381. {
  382. int ret = -EINVAL;
  383. if (telem_unit == TELEM_PSS)
  384. ret = telemetry_get_pssevtname(telem_unit, name, len);
  385. else if (telem_unit == TELEM_IOSS)
  386. ret = telemetry_get_iossevtname(telem_unit, name, len);
  387. return ret;
  388. }
  389. EXPORT_SYMBOL_GPL(telemetry_get_evtname);
  390. static int __init telemetry_module_init(void)
  391. {
  392. pr_info(pr_fmt(DRIVER_NAME) " Init\n");
  393. telm_core_conf.telem_ops = &telm_defpltops;
  394. return 0;
  395. }
  396. static void __exit telemetry_module_exit(void)
  397. {
  398. }
  399. module_init(telemetry_module_init);
  400. module_exit(telemetry_module_exit);
  401. MODULE_AUTHOR("Souvik Kumar Chakravarty <souvik.k.chakravarty@intel.com>");
  402. MODULE_DESCRIPTION("Intel SoC Telemetry Interface");
  403. MODULE_LICENSE("GPL");