cam_cx_ipeak.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
  4. */
  5. #include <linux/of.h>
  6. #include <linux/slab.h>
  7. #include <linux/gpio.h>
  8. #include <linux/of_gpio.h>
  9. #include <soc/qcom/cx_ipeak.h>
  10. #include "cam_soc_util.h"
  11. #include "cam_debug_util.h"
  12. static struct cx_ipeak_client *cam_cx_ipeak;
  13. static int cx_ipeak_level = CAM_NOMINAL_VOTE;
  14. static int cx_default_ipeak_mask;
  15. static int cx_current_ipeak_mask;
  16. static int cam_cx_client_cnt;
  17. int cam_cx_ipeak_register_cx_ipeak(struct cam_hw_soc_info *soc_info)
  18. {
  19. int rc = 0;
  20. soc_info->cam_cx_ipeak_enable = true;
  21. soc_info->cam_cx_ipeak_bit = 1 << cam_cx_client_cnt++;
  22. cx_default_ipeak_mask |= soc_info->cam_cx_ipeak_bit;
  23. if (cam_cx_ipeak)
  24. goto exit;
  25. cam_cx_ipeak = cx_ipeak_register(soc_info->dev->of_node,
  26. "qcom,cam-cx-ipeak");
  27. if (cam_cx_ipeak) {
  28. goto exit;
  29. } else {
  30. rc = -EINVAL;
  31. goto exit;
  32. }
  33. exit:
  34. CAM_DBG(CAM_UTIL, "cam_cx_ipeak is enabled for %s\n"
  35. "mask = %x cx_default_ipeak_mask = %x",
  36. soc_info->dev_name, soc_info->cam_cx_ipeak_bit,
  37. cx_default_ipeak_mask);
  38. return rc;
  39. }
  40. int cam_cx_ipeak_update_vote_cx_ipeak(struct cam_hw_soc_info *soc_info,
  41. int32_t apply_level)
  42. {
  43. int32_t soc_cx_ipeak_bit = soc_info->cam_cx_ipeak_bit;
  44. int ret = 0;
  45. CAM_DBG(CAM_UTIL, "E: apply_level = %d cx_current_ipeak_mask = %x\n"
  46. "soc_cx_ipeak_bit = %x",
  47. apply_level, cx_current_ipeak_mask, soc_cx_ipeak_bit);
  48. if (apply_level < cx_ipeak_level &&
  49. (cx_current_ipeak_mask & soc_cx_ipeak_bit)) {
  50. if (cx_current_ipeak_mask == cx_default_ipeak_mask) {
  51. ret = cx_ipeak_update(cam_cx_ipeak, false);
  52. if (ret)
  53. goto exit;
  54. CAM_DBG(CAM_UTIL,
  55. "X: apply_level = %d cx_current_ipeak_mask = %x\n"
  56. "soc_cx_ipeak_bit = %x %s UNVOTE",
  57. apply_level, cx_current_ipeak_mask,
  58. soc_cx_ipeak_bit, soc_info->dev_name);
  59. }
  60. cx_current_ipeak_mask &= (~soc_cx_ipeak_bit);
  61. CAM_DBG(CAM_UTIL,
  62. "X: apply_level = %d cx_current_ipeak_mask = %x\n"
  63. "soc_cx_ipeak_bit = %x %s DISABLE_BIT",
  64. apply_level, cx_current_ipeak_mask,
  65. soc_cx_ipeak_bit, soc_info->dev_name);
  66. goto exit;
  67. } else if (apply_level < cx_ipeak_level) {
  68. CAM_DBG(CAM_UTIL,
  69. "X: apply_level = %d cx_current_ipeak_mask = %x\n"
  70. "soc_cx_ipeak_bit = %x NO AI",
  71. apply_level, cx_current_ipeak_mask, soc_cx_ipeak_bit);
  72. goto exit;
  73. }
  74. cx_current_ipeak_mask |= soc_cx_ipeak_bit;
  75. CAM_DBG(CAM_UTIL,
  76. "X: apply_level = %d cx_current_ipeak_mask = %x\n"
  77. "soc_cx_ipeak_bit = %x %s ENABLE_BIT",
  78. apply_level, cx_current_ipeak_mask,
  79. soc_cx_ipeak_bit, soc_info->dev_name);
  80. if (cx_current_ipeak_mask == cx_default_ipeak_mask) {
  81. ret = cx_ipeak_update(cam_cx_ipeak, true);
  82. if (ret)
  83. goto exit;
  84. CAM_DBG(CAM_UTIL,
  85. "X: apply_level = %d cx_current_ipeak_mask = %x\n"
  86. "soc_cx_ipeak_bit = %x %s VOTE",
  87. apply_level, cx_current_ipeak_mask,
  88. soc_cx_ipeak_bit, soc_info->dev_name);
  89. }
  90. exit:
  91. return ret;
  92. }
  93. int cam_cx_ipeak_unvote_cx_ipeak(struct cam_hw_soc_info *soc_info)
  94. {
  95. int32_t soc_cx_ipeak_bit = soc_info->cam_cx_ipeak_bit;
  96. CAM_DBG(CAM_UTIL, "E:cx_current_ipeak_mask = %x\n"
  97. "soc_cx_ipeak_bit = %x",
  98. cx_current_ipeak_mask, soc_cx_ipeak_bit);
  99. if (cx_current_ipeak_mask == cx_default_ipeak_mask) {
  100. if (cam_cx_ipeak)
  101. cx_ipeak_update(cam_cx_ipeak, false);
  102. CAM_DBG(CAM_UTIL, "X:cx_current_ipeak_mask = %x\n"
  103. "soc_cx_ipeak_bit = %x UNVOTE",
  104. cx_current_ipeak_mask, soc_cx_ipeak_bit);
  105. }
  106. cx_current_ipeak_mask &= (~soc_cx_ipeak_bit);
  107. CAM_DBG(CAM_UTIL, "X:cx_current_ipeak_mask = %x\n"
  108. "soc_cx_ipeak_bit = %x",
  109. cx_current_ipeak_mask, soc_cx_ipeak_bit);
  110. return 0;
  111. }