cam_soc_bus.c 6.0 KB

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