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