qti_epm.h 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. /*
  3. * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
  4. */
  5. #ifndef __QCOM_EPM_H__
  6. #define __QCOM_EPM_H__
  7. #include <linux/interrupt.h>
  8. #include <linux/ipc_logging.h>
  9. #include <linux/powercap.h>
  10. #include <linux/thermal.h>
  11. struct epm_priv;
  12. struct epm_device;
  13. #define IPC_LOGPAGES 10
  14. #define EPM_DBG(epm, msg, args...) do { \
  15. dev_dbg(epm->dev, "%s:" msg, __func__, args); \
  16. if ((epm) && (epm)->ipc_log) { \
  17. ipc_log_string((epm)->ipc_log, \
  18. "[%s] "msg"\n", \
  19. current->comm, args); \
  20. } \
  21. } while (0)
  22. #define EPM_REG_NAME_LENGTH 32
  23. #define EPM_POWER_CH_MAX 48
  24. #define EPM_TZ_CH_MAX 8
  25. #define EPM_MAX_DATA_MAX 10
  26. /*
  27. * Different epm modes of operation
  28. */
  29. enum epm_mode {
  30. EPM_ACAT_MODE,
  31. EPM_RCM_MODE,
  32. /* Keep last */
  33. EPM_MODE_MAX
  34. };
  35. /*
  36. * Different epm sdam IDs to use as an index into an array
  37. */
  38. enum epm_sdam_id {
  39. CONFIG_SDAM,
  40. DATA_AVG_SDAM,
  41. DATA_1_SDAM,
  42. DATA_2_SDAM,
  43. DATA_3_SDAM,
  44. DATA_4_SDAM,
  45. DATA_5_SDAM,
  46. DATA_6_SDAM,
  47. DATA_7_SDAM,
  48. DATA_8_SDAM,
  49. DATA_9_SDAM,
  50. DATA_10_SDAM,
  51. DATA_11_SDAM,
  52. /* Keep last */
  53. MAX_EPM_SDAM
  54. };
  55. /*
  56. * Data sdam field IDs to use as an index into an array
  57. */
  58. enum data_sdam_field_ids {
  59. DATA_SDAM_SEQ_START,
  60. DATA_SDAM_SEQ_END,
  61. DATA_SDAM_NUM_RECORDS,
  62. DATA_SDAM_RTC0,
  63. DATA_SDAM_RTC1,
  64. DATA_SDAM_RTC2,
  65. DATA_SDAM_RTC3,
  66. DATA_SDAM_VPH_LSB,
  67. DATA_SDAM_VPH_MSB,
  68. DATA_SDAM_DIE_TEMP_SID1,
  69. DATA_SDAM_DIE_TEMP_SID8 = DATA_SDAM_DIE_TEMP_SID1 + EPM_TZ_CH_MAX - 1,
  70. DATA_SDAM_POWER_LSB_CH1,
  71. DATA_SDAM_POWER_MSB_CH1,
  72. DATA_SDAM_POWER_LSB_CH48 = DATA_SDAM_POWER_LSB_CH1 + 2 * (EPM_POWER_CH_MAX - 1),
  73. DATA_SDAM_POWER_MSB_CH48,
  74. /* Keep last */
  75. MAX_SDAM_DATA
  76. };
  77. /*
  78. * config sdam field IDs to use as an index into an array
  79. */
  80. enum config_sdam_field_ids {
  81. CONFIG_SDAM_EPM_MODE,
  82. CONFIG_SDAM_EPM_STATUS,
  83. CONFIG_SDAM_MAX_DATA,
  84. CONFIG_SDAM_MEAS_CFG,
  85. CONFIG_SDAM_LAST_FULL_SDAM,
  86. CONFIG_SDAM_CONFIG_1,
  87. CONFIG_SDAM_PID_1,
  88. CONFIG_SDAM_CONFIG_48 = CONFIG_SDAM_CONFIG_1 + 2 * (EPM_POWER_CH_MAX - 1),
  89. /* Keep last */
  90. MAX_CONFIG_SDAM_DATA
  91. };
  92. /*
  93. * ACAT mode different epm data types
  94. */
  95. enum epm_data_type {
  96. EPM_1S_DATA,
  97. EPM_10S_AVG_DATA,
  98. /* Keep last */
  99. EPM_TYPE_MAX
  100. };
  101. /**
  102. * struct epm_sdam - EPM sdam data structure
  103. * @id: EPM sdam id type
  104. * @nvmem: Pointer to nvmem device
  105. * @lock: lock to protect multiple read concurrently
  106. * @last_data: last full read data copy for current sdam
  107. */
  108. struct epm_sdam {
  109. enum epm_sdam_id id;
  110. struct nvmem_device *nvmem;
  111. struct mutex lock;
  112. uint8_t last_data[MAX_CONFIG_SDAM_DATA];
  113. };
  114. /**
  115. * struct epm_device_pz_data - EPM device powercap zone data for each data type
  116. * @pz: Pointer to powercap zone device
  117. * @type: Type of epm acat data types, 1S data to 10S average data
  118. * @epm_dev: Pointer to regulator epm channel device
  119. */
  120. struct epm_device_pz_data {
  121. struct powercap_zone pz;
  122. enum epm_data_type type;
  123. struct epm_device *epm_dev;
  124. };
  125. /**
  126. * struct epm_device - Each regulator channel device data
  127. * @epm_node: epm device list head member to traverse all devices
  128. * @priv: epm hardware instance that this channel is connected to
  129. * @epm_pz: array of powercap zone data types for different data retrieval
  130. * @name: name of the regulator which is used to identify channel
  131. * @enabled: epm channel is enabled or not
  132. * @sid: epm channel SID
  133. * @pid: epm channel PID
  134. * @gang_num: epm channel gang_num
  135. * @data_offset: epm channel power data offset from DATA sdam base
  136. * @last_data: epm channel last 1S data
  137. * @last_avg_data: epm channel last 10S average data
  138. * @time_stamp: timestamp of last 1S data collected from epm channel
  139. * @avg_time_stamp: timestamp of last 10S average data collected from epm channel
  140. * @lock: lock to protect multiple client read concurrently
  141. */
  142. struct epm_device {
  143. struct list_head epm_node;
  144. struct epm_priv *priv;
  145. struct epm_device_pz_data epm_pz[EPM_TYPE_MAX];
  146. char name[EPM_REG_NAME_LENGTH];
  147. bool enabled;
  148. uint8_t sid;
  149. uint8_t pid;
  150. uint8_t gang_num;
  151. uint8_t data_offset;
  152. uint16_t last_data[EPM_MAX_DATA_MAX];
  153. uint16_t last_avg_data;
  154. u64 last_data_uw[EPM_MAX_DATA_MAX];
  155. u64 last_avg_data_uw;
  156. u64 time_stamp;
  157. u64 avg_time_stamp;
  158. struct mutex lock;
  159. };
  160. /**
  161. * struct epm_tz_device - EPM each temeprature device data
  162. * @offset: epm tz channel offset from first temperature data
  163. * @last_temp: epm thermal zone last read data
  164. * @time_stamp: timestamp of last temperature data collected for given tz
  165. * @priv: epm hardware instance that this channel is connected to
  166. * @tz: array of powercap zone data types for different data retrieval
  167. * @lock: lock to protect multiple client read concurrently
  168. */
  169. struct epm_tz_device {
  170. uint8_t offset;
  171. int last_temp;
  172. u64 time_stamp;
  173. struct epm_priv *priv;
  174. struct thermal_zone_device *tz;
  175. struct mutex lock;
  176. };
  177. /**
  178. * struct epm_priv - Structure for EPM hardware private data
  179. * @dev: Pointer for EPM device
  180. * @mode: enum to give current mode of operation
  181. * @sdam: Pointer for array of EPM sdams
  182. * @pct: pointer to powercap control type
  183. * @irq: epm sdam pbs irq number
  184. * @num_sdams: Number of SDAMs used for EPM from DT
  185. * @num_reg: Number of regulator based on config sdam
  186. * @max_data: EPM hardware max_data configuration
  187. * @data_1s_base_pid: PID info of 1st 1S sdam of EPM
  188. * @last_sdam_pid: PID info of latest 1S data sdam
  189. * @reg_ppid_map: array of regulator/rail PPID from devicetree
  190. * @dt_reg_cnt: Number of regulator count in devicetree
  191. * @last_ch_offset: Last enabled data channel offset
  192. * @initialized: EPM hardware initialization is done if it is true
  193. * @g_enabled: The epm global enable bit status
  194. * @ops: EPM hardware supported ops
  195. * @config_sdam_data: Config sdam data dump collected at init
  196. * @ipc_log: Handle to ipc_logging
  197. * @all_1s_read_ts: Timestamp collected just after epm irq 1S data update
  198. * @all_avg_read_ts: Timestamp collected just after epm irq 10S avg data update
  199. * @epm_dev_head: List head for all epm channel devices
  200. * @epm_tz: Array of list of pmic die temperature devices
  201. * @sec_read_lock: lock to protect 1s data update and client request
  202. * @avg_read_lock: lock to protect avg data update and client request
  203. * @avg_data_work: Workqueue to check avg data if counters are not matching state
  204. */
  205. struct epm_priv {
  206. struct device *dev;
  207. enum epm_mode mode;
  208. struct epm_sdam *sdam;
  209. struct powercap_control_type *pct;
  210. int irq;
  211. u32 num_sdams;
  212. u32 num_reg;
  213. u8 max_data;
  214. u16 data_1s_base_pid;
  215. u16 last_sdam_pid;
  216. u16 reg_ppid_map[EPM_POWER_CH_MAX];
  217. u8 dt_reg_cnt;
  218. u8 dt_tz_cnt;
  219. u8 last_ch_offset;
  220. bool initialized;
  221. bool g_enabled;
  222. struct epm_ops *ops;
  223. uint8_t *config_sdam_data;
  224. void *ipc_log;
  225. u64 all_1s_read_ts;
  226. u64 all_avg_read_ts;
  227. u64 all_tz_read_ts;
  228. struct list_head epm_dev_head;
  229. struct epm_tz_device *epm_tz;
  230. struct mutex sec_read_lock;
  231. struct mutex avg_read_lock;
  232. struct delayed_work avg_data_work;
  233. };
  234. /**
  235. * struct epm_ops - Structure for EPM hardware supported ops
  236. * @init: EPM hardware init function
  237. * @get_mode: Function to get current EPM operation mode
  238. * @get_power: Function to get power for EPM channel in us for a given type
  239. * @get_max_power: Function to get max power which EPM channel can deliver
  240. * @get_temp: Function to get current temperature of a pmic die
  241. * @get_hw_mon_data: Function to hardware monitor data for RCM mode
  242. * @release: Function to clear all EPM data on exit
  243. * @suspend: Function to execute EPM during suspend callback if any
  244. * @resume: Function to restore EPM durng resume callback if any
  245. */
  246. struct epm_ops {
  247. int (*init)(struct epm_priv *priv);
  248. enum epm_mode (*get_mode)(struct epm_priv *epm);
  249. int (*get_power)(struct epm_device *epm_dev, enum epm_data_type type, u64 *power);
  250. int (*get_max_power)(const struct epm_device *epm_dev, u64 *max_power);
  251. int (*get_temp)(struct epm_tz_device *epm_tz, int *temp);
  252. int (*get_hw_mon_data)(struct epm_device *epm, int *data);
  253. void (*release)(struct epm_priv *epm);
  254. int (*suspend)(struct epm_priv *epm);
  255. int (*resume)(struct epm_priv *epm);
  256. };
  257. extern struct epm_ops epm_hw_ops;
  258. #endif /* __QCOM_EPM_H__ */