mt_lp_rm.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. /*
  2. * Copyright (c) 2020-2023, MediaTek Inc. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <stddef.h>
  7. #include <lpm/mt_lp_rm.h>
  8. struct platform_mt_resource_manager {
  9. unsigned int count;
  10. struct mt_resource_manager *plat_rm;
  11. };
  12. static struct platform_mt_resource_manager plat_mt_rm;
  13. int mt_lp_rm_register(struct mt_resource_manager *rm)
  14. {
  15. unsigned int i;
  16. struct mt_resource_constraint *const *rc;
  17. if ((rm == NULL) || (rm->consts == NULL) ||
  18. (plat_mt_rm.plat_rm != NULL)) {
  19. return MT_RM_STATUS_BAD;
  20. }
  21. for (i = 0U, rc = rm->consts; *rc != NULL; i++, rc++) {
  22. if ((*rc)->init != NULL) {
  23. (*rc)->init();
  24. }
  25. }
  26. plat_mt_rm.plat_rm = rm;
  27. plat_mt_rm.count = i;
  28. return MT_RM_STATUS_OK;
  29. }
  30. int mt_lp_rm_reset_constraint(unsigned int idx, unsigned int cpuid, int stateid)
  31. {
  32. struct mt_resource_constraint const *rc = NULL;
  33. if ((plat_mt_rm.plat_rm == NULL) || (idx >= plat_mt_rm.count)) {
  34. return MT_RM_STATUS_BAD;
  35. }
  36. rc = plat_mt_rm.plat_rm->consts[idx];
  37. if ((rc == NULL) || (rc->reset == NULL)) {
  38. return MT_RM_STATUS_BAD;
  39. }
  40. return rc->reset(cpuid, stateid);
  41. }
  42. int mt_lp_rm_get_status(unsigned int type, void *priv)
  43. {
  44. int res = 0;
  45. struct mt_resource_constraint *const *con;
  46. struct mt_resource_manager *rm = plat_mt_rm.plat_rm;
  47. if ((rm == NULL) || (type >= PLAT_RC_MAX)) {
  48. return -1;
  49. }
  50. for (con = rm->consts; *con != NULL; con++) {
  51. if ((*con)->get_status == NULL) {
  52. continue;
  53. }
  54. res = (*con)->get_status(type, priv);
  55. if (res == MT_RM_STATUS_STOP) {
  56. break;
  57. }
  58. }
  59. return res;
  60. }
  61. int mt_lp_rm_do_constraint(unsigned int constraint_id, unsigned int cpuid, int stateid)
  62. {
  63. int res = MT_RM_STATUS_BAD;
  64. struct mt_resource_constraint const *rc;
  65. struct mt_resource_manager *rm = plat_mt_rm.plat_rm;
  66. if ((rm == NULL) || (constraint_id >= plat_mt_rm.count)) {
  67. return res;
  68. }
  69. rc = rm->consts[constraint_id];
  70. if ((rc != NULL) && (rc->run != NULL)) {
  71. res = rc->run(cpuid, stateid);
  72. }
  73. return res;
  74. }
  75. int mt_lp_rm_find_constraint(unsigned int idx, unsigned int cpuid,
  76. int stateid, void *priv)
  77. {
  78. unsigned int i;
  79. int res = MT_RM_STATUS_BAD;
  80. struct mt_resource_constraint *const *rc;
  81. struct mt_resource_manager *rm = plat_mt_rm.plat_rm;
  82. if ((rm == NULL) || (idx >= plat_mt_rm.count)) {
  83. return res;
  84. }
  85. /* If subsys clk/mtcmos is on, add block-resource-off flag */
  86. if (rm->update != NULL) {
  87. res = rm->update(rm->consts, plat_mt_rm.count, stateid, priv);
  88. if (res != 0) {
  89. return MT_RM_STATUS_BAD;
  90. }
  91. }
  92. res = MT_RM_STATUS_BAD;
  93. for (i = idx, rc = (rm->consts + idx); *rc != NULL; i++, rc++) {
  94. if (((*rc)->is_valid != NULL) &&
  95. ((*rc)->is_valid(cpuid, stateid))) {
  96. res = i;
  97. break;
  98. }
  99. }
  100. return res;
  101. }
  102. int mt_lp_rm_find_and_run_constraint(unsigned int idx, unsigned int cpuid,
  103. int stateid, void *priv)
  104. {
  105. int res = MT_RM_STATUS_BAD;
  106. res = mt_lp_rm_find_constraint(idx, cpuid, stateid, priv);
  107. if (res != MT_RM_STATUS_BAD) {
  108. mt_lp_rm_do_constraint(res, cpuid, stateid);
  109. }
  110. return res;
  111. }
  112. int mt_lp_rm_do_update(int stateid, int type, void const *p)
  113. {
  114. int res = MT_RM_STATUS_BAD;
  115. struct mt_resource_constraint *const *rc;
  116. struct mt_resource_manager *rm = plat_mt_rm.plat_rm;
  117. if (rm == NULL) {
  118. return res;
  119. }
  120. for (rc = rm->consts; *rc != NULL; rc++) {
  121. if ((*rc)->update != NULL) {
  122. res = (*rc)->update(stateid, type, p);
  123. if (res != MT_RM_STATUS_OK) {
  124. break;
  125. }
  126. }
  127. }
  128. return res;
  129. }