cam_soc_bus.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
  4. * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  5. */
  6. #include <linux/msm-bus.h>
  7. #include "cam_soc_bus.h"
  8. /**
  9. * struct cam_soc_bus_client_data : Bus client data
  10. *
  11. * @pdata: Bus pdata information
  12. * @client_id: Bus client id
  13. * @num_paths: Number of paths for this client
  14. * @curr_vote_level: current voted index
  15. * @dyn_vote: whether dynamic voting enabled
  16. */
  17. struct cam_soc_bus_client_data {
  18. struct msm_bus_scale_pdata *pdata;
  19. uint32_t client_id;
  20. int num_paths;
  21. unsigned int curr_vote_level;
  22. bool dyn_vote;
  23. };
  24. int cam_soc_bus_client_update_request(void *client, unsigned int idx)
  25. {
  26. int rc = 0;
  27. struct cam_soc_bus_client *bus_client =
  28. (struct cam_soc_bus_client *) client;
  29. struct cam_soc_bus_client_data *bus_client_data =
  30. (struct cam_soc_bus_client_data *) bus_client->client_data;
  31. if (bus_client_data->dyn_vote) {
  32. CAM_ERR(CAM_UTIL,
  33. "Dyn update not allowed client[%d][%s], dyn_vote: %d",
  34. bus_client_data->client_id,
  35. bus_client->common_data->name,
  36. bus_client_data->dyn_vote);
  37. rc = -EINVAL;
  38. goto end;
  39. }
  40. if (idx >= bus_client->common_data->num_usecases) {
  41. CAM_ERR(CAM_UTIL, "Invalid vote level=%d, usecases=%d", idx,
  42. bus_client->common_data->num_usecases);
  43. rc = -EINVAL;
  44. goto end;
  45. }
  46. CAM_DBG(CAM_PERF, "Bus client=[%d][%s] index[%d]",
  47. bus_client_data->client_id, bus_client->common_data->name, idx);
  48. rc = msm_bus_scale_client_update_request(bus_client_data->client_id,
  49. idx);
  50. if (rc) {
  51. CAM_ERR(CAM_UTIL,
  52. "Update request failed, client[%d][%s], idx: %d",
  53. bus_client_data->client_id,
  54. bus_client->common_data->name, idx);
  55. goto end;
  56. }
  57. end:
  58. return rc;
  59. }
  60. int cam_soc_bus_client_update_bw(void *client, uint64_t ab, uint64_t ib,
  61. enum cam_soc_bus_path_data bus_path_data)
  62. {
  63. int idx = 0;
  64. struct msm_bus_paths *path;
  65. struct msm_bus_scale_pdata *pdata;
  66. struct cam_soc_bus_client *bus_client =
  67. (struct cam_soc_bus_client *) client;
  68. struct cam_soc_bus_client_data *bus_client_data =
  69. (struct cam_soc_bus_client_data *) bus_client->client_data;
  70. int rc = 0;
  71. if ((bus_client->common_data->num_usecases != 2) ||
  72. (bus_client_data->num_paths != 1) ||
  73. (!bus_client_data->dyn_vote)) {
  74. CAM_ERR(CAM_UTIL,
  75. "dynamic update not allowed Bus client=[%d][%s], %d %d %d",
  76. bus_client_data->client_id,
  77. bus_client->common_data->name,
  78. bus_client->common_data->num_usecases,
  79. bus_client_data->num_paths,
  80. bus_client_data->dyn_vote);
  81. rc = -EINVAL;
  82. goto end;
  83. }
  84. idx = bus_client_data->curr_vote_level;
  85. idx = 1 - idx;
  86. bus_client_data->curr_vote_level = idx;
  87. pdata = bus_client_data->pdata;
  88. path = &(pdata->usecase[idx]);
  89. path->vectors[0].ab = ab;
  90. path->vectors[0].ib = ib;
  91. CAM_DBG(CAM_PERF, "Bus client=[%d][%s] :ab[%llu] ib[%llu], index[%d]",
  92. bus_client_data->client_id, bus_client->common_data->name, ab,
  93. ib, idx);
  94. rc = msm_bus_scale_client_update_request(bus_client_data->client_id,
  95. idx);
  96. if (rc) {
  97. CAM_ERR(CAM_UTIL,
  98. "Update request failed, client[%d][%s], idx: %d",
  99. bus_client_data->client_id,
  100. bus_client->common_data->name, idx);
  101. return rc;
  102. }
  103. end:
  104. return rc;
  105. }
  106. int cam_soc_bus_client_register(struct platform_device *pdev,
  107. struct device_node *dev_node, void **client,
  108. struct cam_soc_bus_client_common_data *common_data)
  109. {
  110. struct msm_bus_scale_pdata *pdata = NULL;
  111. struct cam_soc_bus_client *bus_client = NULL;
  112. struct cam_soc_bus_client_data *bus_client_data = NULL;
  113. uint32_t client_id;
  114. int rc;
  115. bus_client = kzalloc(sizeof(struct cam_soc_bus_client), GFP_KERNEL);
  116. if (!bus_client) {
  117. CAM_ERR(CAM_UTIL, "Non Enought Memroy");
  118. rc = -ENOMEM;
  119. goto end;
  120. }
  121. *client = bus_client;
  122. bus_client_data = kzalloc(sizeof(struct cam_soc_bus_client_data),
  123. GFP_KERNEL);
  124. if (!bus_client_data) {
  125. kfree(bus_client);
  126. *client = NULL;
  127. rc = -ENOMEM;
  128. goto end;
  129. }
  130. bus_client->client_data = bus_client_data;
  131. pdata = msm_bus_pdata_from_node(pdev,
  132. dev_node);
  133. if (!pdata) {
  134. CAM_ERR(CAM_UTIL, "failed get_pdata");
  135. rc = -EINVAL;
  136. goto error;
  137. }
  138. if ((pdata->num_usecases == 0) ||
  139. (pdata->usecase[0].num_paths == 0)) {
  140. CAM_ERR(CAM_UTIL, "usecase=%d", pdata->num_usecases);
  141. rc = -EINVAL;
  142. goto error;
  143. }
  144. client_id = msm_bus_scale_register_client(pdata);
  145. if (!client_id) {
  146. CAM_ERR(CAM_UTIL, "failed in register bus client_data");
  147. rc = -EINVAL;
  148. goto error;
  149. }
  150. bus_client->common_data = common_data;
  151. bus_client_data->dyn_vote = of_property_read_bool(dev_node,
  152. "qcom,msm-bus-vector-dyn-vote");
  153. if (bus_client_data->dyn_vote && (pdata->num_usecases != 2)) {
  154. CAM_ERR(CAM_UTIL, "Excess or less vectors %d",
  155. pdata->num_usecases);
  156. rc = -EINVAL;
  157. goto fail_unregister_client;
  158. }
  159. rc = msm_bus_scale_client_update_request(client_id, 0);
  160. if (rc) {
  161. CAM_ERR(CAM_UTIL, "Bus client update request failed, rc = %d",
  162. rc);
  163. goto fail_unregister_client;
  164. }
  165. bus_client->common_data->src_id = pdata->usecase[0].vectors[0].src;
  166. bus_client->common_data->dst_id = pdata->usecase[0].vectors[0].dst;
  167. bus_client_data->pdata = pdata;
  168. bus_client_data->client_id = client_id;
  169. bus_client->common_data->num_usecases = pdata->num_usecases;
  170. bus_client_data->num_paths = pdata->usecase[0].num_paths;
  171. bus_client->common_data->name = pdata->name;
  172. CAM_DBG(CAM_PERF, "Register Bus Client=[%d][%s] : src=%d, dst=%d",
  173. bus_client_data->client_id, bus_client->common_data->name,
  174. bus_client->common_data->src_id,
  175. bus_client->common_data->dst_id);
  176. return 0;
  177. fail_unregister_client:
  178. msm_bus_scale_unregister_client(bus_client_data->client_id);
  179. error:
  180. kfree(bus_client_data);
  181. bus_client->client_data = NULL;
  182. kfree(bus_client);
  183. *client = NULL;
  184. end:
  185. return rc;
  186. }
  187. void cam_soc_bus_client_unregister(void **client)
  188. {
  189. struct cam_soc_bus_client *bus_client =
  190. (struct cam_soc_bus_client *) (*client);
  191. struct cam_soc_bus_client_data *bus_client_data =
  192. (struct cam_soc_bus_client_data *) bus_client->client_data;
  193. if (bus_client_data->dyn_vote)
  194. cam_soc_bus_client_update_bw(bus_client, 0, 0);
  195. else
  196. cam_soc_bus_client_update_request(bus_client, 0);
  197. msm_bus_scale_unregister_client(bus_client_data->client_id);
  198. kfree(bus_client_data);
  199. bus_client->client_data = NULL;
  200. kfree(bus_client);
  201. *client = NULL;
  202. }