sensor.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. // SPDX-License-Identifier: BSD-3-Clause
  2. /*
  3. * Copyright 2021-2024 NXP
  4. */
  5. #include <cdefs.h>
  6. #include <string.h>
  7. #include "common.h"
  8. #include <drivers/scmi-msg.h>
  9. #include <drivers/scmi.h>
  10. #include <lib/utils_def.h>
  11. static bool message_id_is_supported(size_t message_id);
  12. uint16_t plat_scmi_sensor_count(unsigned int agent_id __unused)
  13. {
  14. if (sensor_ops.sensor_count != NULL) {
  15. return sensor_ops.sensor_count(agent_id);
  16. }
  17. return 0U;
  18. }
  19. uint8_t plat_scmi_sensor_max_requests(unsigned int agent_id __unused)
  20. {
  21. if (sensor_ops.sensor_max_request != NULL) {
  22. return sensor_ops.sensor_max_request(agent_id);
  23. }
  24. return 0U;
  25. }
  26. uint32_t plat_scmi_sensor_reg(unsigned int agent_id __unused,
  27. unsigned int *addr)
  28. {
  29. if (sensor_ops.get_sensor_req != NULL) {
  30. return sensor_ops.get_sensor_req(agent_id, addr);
  31. }
  32. return 0U;
  33. }
  34. int32_t plat_scmi_sensor_reading_get(uint32_t agent_id __unused,
  35. uint16_t sensor_id __unused,
  36. uint32_t *val __unused)
  37. {
  38. if (sensor_ops.sensor_reading_get != NULL) {
  39. return sensor_ops.sensor_reading_get(agent_id, sensor_id, val);
  40. }
  41. return 0;
  42. }
  43. uint32_t plat_scmi_sensor_description_get(uint32_t agent_id __unused,
  44. uint16_t desc_index __unused,
  45. struct scmi_sensor_desc *desc __unused)
  46. {
  47. if (sensor_ops.sensor_description_get != NULL) {
  48. return sensor_ops.sensor_description_get(agent_id, desc_index, desc);
  49. }
  50. return 0U;
  51. }
  52. uint32_t plat_scmi_sensor_update_interval(uint32_t agent_id __unused,
  53. uint16_t sensor_id __unused)
  54. {
  55. if (sensor_ops.sensor_update_interval != NULL) {
  56. return sensor_ops.sensor_update_interval(agent_id, sensor_id);
  57. }
  58. return 0U;
  59. }
  60. uint32_t plat_scmi_sensor_state(uint32_t agent_id __unused,
  61. uint16_t sensor_id __unused)
  62. {
  63. if (sensor_ops.sensor_state != NULL) {
  64. return sensor_ops.sensor_state(agent_id, sensor_id);
  65. }
  66. return 0U;
  67. }
  68. uint32_t plat_scmi_sensor_timestamped(uint32_t agent_id __unused,
  69. uint16_t sensor_id __unused)
  70. {
  71. if (sensor_ops.sensor_timestamped != NULL) {
  72. return sensor_ops.sensor_timestamped(agent_id, sensor_id);
  73. }
  74. return 0U;
  75. }
  76. static void report_version(struct scmi_msg *msg)
  77. {
  78. struct scmi_protocol_version_p2a return_values = {
  79. .status = SCMI_SUCCESS,
  80. .version = SCMI_PROTOCOL_VERSION_SENSOR,
  81. };
  82. if (msg->in_size != 0U) {
  83. scmi_status_response(msg, SCMI_PROTOCOL_ERROR);
  84. return;
  85. }
  86. scmi_write_response(msg, &return_values, sizeof(return_values));
  87. }
  88. static void report_attributes(struct scmi_msg *msg)
  89. {
  90. unsigned int addr[2];
  91. unsigned int len;
  92. struct scmi_protocol_attributes_p2a_sensor return_values = {
  93. .status = SCMI_SUCCESS,
  94. };
  95. if (msg->in_size != 0U) {
  96. scmi_status_response(msg, SCMI_PROTOCOL_ERROR);
  97. return;
  98. }
  99. return_values.num_sensors = plat_scmi_sensor_count(msg->agent_id);
  100. return_values.max_reqs = plat_scmi_sensor_max_requests(msg->agent_id);
  101. len = plat_scmi_sensor_reg(msg->agent_id, addr);
  102. if (len != 0U) {
  103. return_values.sensor_reg_low = addr[0];
  104. return_values.sensor_reg_high = addr[1];
  105. return_values.sensor_reg_len = len;
  106. }
  107. scmi_write_response(msg, &return_values, sizeof(return_values));
  108. }
  109. static void report_message_attributes(struct scmi_msg *msg)
  110. {
  111. struct scmi_protocol_message_attributes_a2p *in_args = (void *)msg->in;
  112. struct scmi_protocol_message_attributes_p2a return_values = {
  113. .status = SCMI_SUCCESS,
  114. /* For this protocol, attributes shall be zero */
  115. .attributes = 0U,
  116. };
  117. if (msg->in_size != sizeof(*in_args)) {
  118. scmi_status_response(msg, SCMI_PROTOCOL_ERROR);
  119. return;
  120. }
  121. if (!message_id_is_supported(in_args->message_id)) {
  122. scmi_status_response(msg, SCMI_NOT_FOUND);
  123. return;
  124. }
  125. scmi_write_response(msg, &return_values, sizeof(return_values));
  126. }
  127. static void scmi_sensor_description_get(struct scmi_msg *msg)
  128. {
  129. const struct scmi_sensor_description_get_a2p *in_args = (void *)msg->in;
  130. struct scmi_sensor_description_get_p2a return_values = {
  131. .status = SCMI_SUCCESS,
  132. };
  133. struct scmi_sensor_desc desc;
  134. unsigned int desc_index = 0U;
  135. unsigned int num_sensor_flags;
  136. if (msg->in_size != sizeof(*in_args)) {
  137. scmi_status_response(msg, SCMI_PROTOCOL_ERROR);
  138. return;
  139. }
  140. desc_index = SPECULATION_SAFE_VALUE(in_args->desc_index);
  141. num_sensor_flags = plat_scmi_sensor_description_get(msg->agent_id, desc_index,
  142. &desc);
  143. return_values.num_sensor_flags = num_sensor_flags;
  144. memcpy(msg->out, &return_values, sizeof(return_values));
  145. memcpy(msg->out + sizeof(return_values), &desc, sizeof(desc));
  146. msg->out_size_out = sizeof(return_values) + sizeof(struct scmi_sensor_desc);
  147. }
  148. static void scmi_sensor_config_get(struct scmi_msg *msg)
  149. {
  150. const struct scmi_sensor_config_get_a2p *in_args = (void *)msg->in;
  151. struct scmi_sensor_config_get_p2a return_values = {
  152. .status = SCMI_SUCCESS,
  153. };
  154. unsigned int sensor_id = 0U;
  155. uint32_t update_interval, state, timestamped;
  156. if (msg->in_size != sizeof(*in_args)) {
  157. scmi_status_response(msg, SCMI_PROTOCOL_ERROR);
  158. return;
  159. }
  160. sensor_id = SPECULATION_SAFE_VALUE(in_args->sensor_id);
  161. if (sensor_id >= plat_scmi_sensor_count(msg->agent_id)) {
  162. scmi_status_response(msg, SCMI_INVALID_PARAMETERS);
  163. return;
  164. }
  165. update_interval = plat_scmi_sensor_update_interval(msg->agent_id, sensor_id);
  166. state = plat_scmi_sensor_state(msg->agent_id, sensor_id);
  167. timestamped = plat_scmi_sensor_timestamped(msg->agent_id, sensor_id);
  168. return_values.sensor_config = (update_interval << 11) | (timestamped << 1) | state;
  169. scmi_write_response(msg, &return_values, sizeof(return_values));
  170. }
  171. static void scmi_sensor_reading_get(struct scmi_msg *msg)
  172. {
  173. const struct scmi_sensor_reading_get_a2p *in_args = (void *)msg->in;
  174. struct scmi_sensor_reading_get_p2a return_values = {
  175. .status = SCMI_SUCCESS,
  176. };
  177. unsigned int sensor_id = 0U;
  178. int32_t ret;
  179. if (msg->in_size != sizeof(*in_args)) {
  180. scmi_status_response(msg, SCMI_PROTOCOL_ERROR);
  181. return;
  182. }
  183. sensor_id = SPECULATION_SAFE_VALUE(in_args->sensor_id);
  184. if (sensor_id >= plat_scmi_sensor_count(msg->agent_id)) {
  185. scmi_status_response(msg, SCMI_INVALID_PARAMETERS);
  186. return;
  187. }
  188. ret = plat_scmi_sensor_reading_get(msg->agent_id, sensor_id,
  189. (uint32_t *)&return_values.val);
  190. if (ret) {
  191. scmi_status_response(msg, SCMI_HARDWARE_ERROR);
  192. return;
  193. }
  194. scmi_write_response(msg, &return_values, sizeof(return_values));
  195. }
  196. static void scmi_sensor_list_update_intervals(struct scmi_msg *msg)
  197. {
  198. /* TODO */
  199. scmi_status_response(msg, SCMI_NOT_SUPPORTED);
  200. }
  201. static const scmi_msg_handler_t scmi_sensor_handler_table[SCMI_SENSOR_MAX] = {
  202. [SCMI_PROTOCOL_VERSION] = report_version,
  203. [SCMI_PROTOCOL_ATTRIBUTES] = report_attributes,
  204. [SCMI_PROTOCOL_MESSAGE_ATTRIBUTES] = report_message_attributes,
  205. [SCMI_SENSOR_DESCRIPTION_GET] = scmi_sensor_description_get,
  206. [SCMI_SENSOR_CONFIG_GET] = scmi_sensor_config_get,
  207. [SCMI_SENSOR_LIST_UPDATE_INTERVALS] = scmi_sensor_list_update_intervals,
  208. [SCMI_SENSOR_READING_GET] = scmi_sensor_reading_get,
  209. };
  210. static bool message_id_is_supported(size_t message_id)
  211. {
  212. return scmi_sensor_handler_table[message_id] != NULL;
  213. }
  214. scmi_msg_handler_t scmi_msg_get_sensor_handler(struct scmi_msg *msg)
  215. {
  216. unsigned int message_id = SPECULATION_SAFE_VALUE(msg->message_id);
  217. if (!message_id_is_supported(message_id)) {
  218. VERBOSE("pd handle not found %u\n", msg->message_id);
  219. return NULL;
  220. }
  221. return scmi_sensor_handler_table[message_id];
  222. }