1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2020 Samsung Electronics Co., Ltd. 4 * http://www.samsung.com/ 5 * Author: Marek Szyprowski <m.szyprowski@samsung.com> 6 * 7 * Simplified generic voltage coupler from regulator core.c 8 * The main difference is that it keeps current regulator voltage 9 * if consumers didn't apply their constraints yet. 10 */ 11 12 #include <linux/init.h> 13 #include <linux/kernel.h> 14 #include <linux/of.h> 15 #include <linux/regulator/coupler.h> 16 #include <linux/regulator/driver.h> 17 #include <linux/regulator/machine.h> 18 19 static int regulator_get_optimal_voltage(struct regulator_dev *rdev, 20 int *current_uV, 21 int *min_uV, int *max_uV, 22 suspend_state_t state) 23 { 24 struct coupling_desc *c_desc = &rdev->coupling_desc; 25 struct regulator_dev **c_rdevs = c_desc->coupled_rdevs; 26 struct regulation_constraints *constraints = rdev->constraints; 27 int desired_min_uV = 0, desired_max_uV = INT_MAX; 28 int max_current_uV = 0, min_current_uV = INT_MAX; 29 int highest_min_uV = 0, target_uV, possible_uV; 30 int i, ret, max_spread, n_coupled = c_desc->n_coupled; 31 bool done; 32 33 *current_uV = -1; 34 35 /* Find highest min desired voltage */ 36 for (i = 0; i < n_coupled; i++) { 37 int tmp_min = 0; 38 int tmp_max = INT_MAX; 39 40 lockdep_assert_held_once(&c_rdevs[i]->mutex.base); 41 42 ret = regulator_check_consumers(c_rdevs[i], 43 &tmp_min, 44 &tmp_max, state); 45 if (ret < 0) 46 return ret; 47 48 if (tmp_min == 0) { 49 ret = regulator_get_voltage_rdev(c_rdevs[i]); 50 if (ret < 0) 51 return ret; 52 tmp_min = ret; 53 } 54 55 /* apply constraints */ 56 ret = regulator_check_voltage(c_rdevs[i], &tmp_min, &tmp_max); 57 if (ret < 0) 58 return ret; 59 60 highest_min_uV = max(highest_min_uV, tmp_min); 61 62 if (i == 0) { 63 desired_min_uV = tmp_min; 64 desired_max_uV = tmp_max; 65 } 66 } 67 68 max_spread = constraints->max_spread[0]; 69 70 /* 71 * Let target_uV be equal to the desired one if possible. 72 * If not, set it to minimum voltage, allowed by other coupled 73 * regulators. 74 */ 75 target_uV = max(desired_min_uV, highest_min_uV - max_spread); 76 77 /* 78 * Find min and max voltages, which currently aren't violating 79 * max_spread. 80 */ 81 for (i = 1; i < n_coupled; i++) { 82 int tmp_act; 83 84 tmp_act = regulator_get_voltage_rdev(c_rdevs[i]); 85 if (tmp_act < 0) 86 return tmp_act; 87 88 min_current_uV = min(tmp_act, min_current_uV); 89 max_current_uV = max(tmp_act, max_current_uV); 90 } 91 92 /* 93 * Correct target voltage, so as it currently isn't 94 * violating max_spread 95 */ 96 possible_uV = max(target_uV, max_current_uV - max_spread); 97 possible_uV = min(possible_uV, min_current_uV + max_spread); 98 99 if (possible_uV > desired_max_uV) 100 return -EINVAL; 101 102 done = (possible_uV == target_uV); 103 desired_min_uV = possible_uV; 104 105 /* Set current_uV if wasn't done earlier in the code and if necessary */ 106 if (*current_uV == -1) { 107 ret = regulator_get_voltage_rdev(rdev); 108 if (ret < 0) 109 return ret; 110 *current_uV = ret; 111 } 112 113 *min_uV = desired_min_uV; 114 *max_uV = desired_max_uV; 115 116 return done; 117 } 118 119 static int exynos_coupler_balance_voltage(struct regulator_coupler *coupler, 120 struct regulator_dev *rdev, 121 suspend_state_t state) 122 { 123 struct regulator_dev **c_rdevs; 124 struct regulator_dev *best_rdev; 125 struct coupling_desc *c_desc = &rdev->coupling_desc; 126 int i, ret, n_coupled, best_min_uV, best_max_uV, best_c_rdev; 127 unsigned int delta, best_delta; 128 unsigned long c_rdev_done = 0; 129 bool best_c_rdev_done; 130 131 c_rdevs = c_desc->coupled_rdevs; 132 n_coupled = c_desc->n_coupled; 133 134 /* 135 * Find the best possible voltage change on each loop. Leave the loop 136 * if there isn't any possible change. 137 */ 138 do { 139 best_c_rdev_done = false; 140 best_delta = 0; 141 best_min_uV = 0; 142 best_max_uV = 0; 143 best_c_rdev = 0; 144 best_rdev = NULL; 145 146 /* 147 * Find highest difference between optimal voltage 148 * and current voltage. 149 */ 150 for (i = 0; i < n_coupled; i++) { 151 /* 152 * optimal_uV is the best voltage that can be set for 153 * i-th regulator at the moment without violating 154 * max_spread constraint in order to balance 155 * the coupled voltages. 156 */ 157 int optimal_uV = 0, optimal_max_uV = 0, current_uV = 0; 158 159 if (test_bit(i, &c_rdev_done)) 160 continue; 161 162 ret = regulator_get_optimal_voltage(c_rdevs[i], 163 ¤t_uV, 164 &optimal_uV, 165 &optimal_max_uV, 166 state); 167 if (ret < 0) 168 goto out; 169 170 delta = abs(optimal_uV - current_uV); 171 172 if (delta && best_delta <= delta) { 173 best_c_rdev_done = ret; 174 best_delta = delta; 175 best_rdev = c_rdevs[i]; 176 best_min_uV = optimal_uV; 177 best_max_uV = optimal_max_uV; 178 best_c_rdev = i; 179 } 180 } 181 182 /* Nothing to change, return successfully */ 183 if (!best_rdev) { 184 ret = 0; 185 goto out; 186 } 187 188 ret = regulator_set_voltage_rdev(best_rdev, best_min_uV, 189 best_max_uV, state); 190 191 if (ret < 0) 192 goto out; 193 194 if (best_c_rdev_done) 195 set_bit(best_c_rdev, &c_rdev_done); 196 197 } while (n_coupled > 1); 198 199 out: 200 return ret; 201 } 202 203 static int exynos_coupler_attach(struct regulator_coupler *coupler, 204 struct regulator_dev *rdev) 205 { 206 return 0; 207 } 208 209 static struct regulator_coupler exynos_coupler = { 210 .attach_regulator = exynos_coupler_attach, 211 .balance_voltage = exynos_coupler_balance_voltage, 212 }; 213 214 static int __init exynos_coupler_init(void) 215 { 216 if (!of_machine_is_compatible("samsung,exynos5800")) 217 return 0; 218 219 return regulator_coupler_register(&exynos_coupler); 220 } 221 arch_initcall(exynos_coupler_init); 222