1 // SPDX-License-Identifier: GPL-2.0 2 // 3 // System Control and Management Interface (SCMI) based regulator driver 4 // 5 // Copyright (C) 2020-2021 ARM Ltd. 6 // 7 // Implements a regulator driver on top of the SCMI Voltage Protocol. 8 // 9 // The ARM SCMI Protocol aims in general to hide as much as possible all the 10 // underlying operational details while providing an abstracted interface for 11 // its users to operate upon: as a consequence the resulting operational 12 // capabilities and configurability of this regulator device are much more 13 // limited than the ones usually available on a standard physical regulator. 14 // 15 // The supported SCMI regulator ops are restricted to the bare minimum: 16 // 17 // - 'status_ops': enable/disable/is_enabled 18 // - 'voltage_ops': get_voltage_sel/set_voltage_sel 19 // list_voltage/map_voltage 20 // 21 // Each SCMI regulator instance is associated, through the means of a proper DT 22 // entry description, to a specific SCMI Voltage Domain. 23 24 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 25 26 #include <linux/linear_range.h> 27 #include <linux/module.h> 28 #include <linux/of.h> 29 #include <linux/regulator/driver.h> 30 #include <linux/regulator/machine.h> 31 #include <linux/regulator/of_regulator.h> 32 #include <linux/scmi_protocol.h> 33 #include <linux/slab.h> 34 #include <linux/types.h> 35 36 static const struct scmi_voltage_proto_ops *voltage_ops; 37 38 struct scmi_regulator { 39 u32 id; 40 struct scmi_device *sdev; 41 struct scmi_protocol_handle *ph; 42 struct regulator_dev *rdev; 43 struct device_node *of_node; 44 struct regulator_desc desc; 45 struct regulator_config conf; 46 }; 47 48 struct scmi_regulator_info { 49 int num_doms; 50 struct scmi_regulator **sregv; 51 }; 52 53 static int scmi_reg_enable(struct regulator_dev *rdev) 54 { 55 struct scmi_regulator *sreg = rdev_get_drvdata(rdev); 56 57 return voltage_ops->config_set(sreg->ph, sreg->id, 58 SCMI_VOLTAGE_ARCH_STATE_ON); 59 } 60 61 static int scmi_reg_disable(struct regulator_dev *rdev) 62 { 63 struct scmi_regulator *sreg = rdev_get_drvdata(rdev); 64 65 return voltage_ops->config_set(sreg->ph, sreg->id, 66 SCMI_VOLTAGE_ARCH_STATE_OFF); 67 } 68 69 static int scmi_reg_is_enabled(struct regulator_dev *rdev) 70 { 71 int ret; 72 u32 config; 73 struct scmi_regulator *sreg = rdev_get_drvdata(rdev); 74 75 ret = voltage_ops->config_get(sreg->ph, sreg->id, &config); 76 if (ret) { 77 dev_err(&sreg->sdev->dev, 78 "Error %d reading regulator %s status.\n", 79 ret, sreg->desc.name); 80 return ret; 81 } 82 83 return config & SCMI_VOLTAGE_ARCH_STATE_ON; 84 } 85 86 static int scmi_reg_get_voltage_sel(struct regulator_dev *rdev) 87 { 88 int ret; 89 s32 volt_uV; 90 struct scmi_regulator *sreg = rdev_get_drvdata(rdev); 91 92 ret = voltage_ops->level_get(sreg->ph, sreg->id, &volt_uV); 93 if (ret) 94 return ret; 95 96 return sreg->desc.ops->map_voltage(rdev, volt_uV, volt_uV); 97 } 98 99 static int scmi_reg_set_voltage_sel(struct regulator_dev *rdev, 100 unsigned int selector) 101 { 102 s32 volt_uV; 103 struct scmi_regulator *sreg = rdev_get_drvdata(rdev); 104 105 volt_uV = sreg->desc.ops->list_voltage(rdev, selector); 106 if (volt_uV <= 0) 107 return -EINVAL; 108 109 return voltage_ops->level_set(sreg->ph, sreg->id, 0x0, volt_uV); 110 } 111 112 static const struct regulator_ops scmi_reg_fixed_ops = { 113 .enable = scmi_reg_enable, 114 .disable = scmi_reg_disable, 115 .is_enabled = scmi_reg_is_enabled, 116 }; 117 118 static const struct regulator_ops scmi_reg_linear_ops = { 119 .enable = scmi_reg_enable, 120 .disable = scmi_reg_disable, 121 .is_enabled = scmi_reg_is_enabled, 122 .get_voltage_sel = scmi_reg_get_voltage_sel, 123 .set_voltage_sel = scmi_reg_set_voltage_sel, 124 .list_voltage = regulator_list_voltage_linear, 125 .map_voltage = regulator_map_voltage_linear, 126 }; 127 128 static const struct regulator_ops scmi_reg_discrete_ops = { 129 .enable = scmi_reg_enable, 130 .disable = scmi_reg_disable, 131 .is_enabled = scmi_reg_is_enabled, 132 .get_voltage_sel = scmi_reg_get_voltage_sel, 133 .set_voltage_sel = scmi_reg_set_voltage_sel, 134 .list_voltage = regulator_list_voltage_table, 135 .map_voltage = regulator_map_voltage_iterate, 136 }; 137 138 static int 139 scmi_config_linear_regulator_mappings(struct scmi_regulator *sreg, 140 const struct scmi_voltage_info *vinfo) 141 { 142 s32 delta_uV; 143 144 /* 145 * Note that SCMI voltage domains describable by linear ranges 146 * (segments) {low, high, step} are guaranteed to come in one single 147 * triplet by the SCMI Voltage Domain protocol support itself. 148 */ 149 150 delta_uV = (vinfo->levels_uv[SCMI_VOLTAGE_SEGMENT_HIGH] - 151 vinfo->levels_uv[SCMI_VOLTAGE_SEGMENT_LOW]); 152 153 /* Rule out buggy negative-intervals answers from fw */ 154 if (delta_uV < 0) { 155 dev_err(&sreg->sdev->dev, 156 "Invalid volt-range %d-%duV for domain %d\n", 157 vinfo->levels_uv[SCMI_VOLTAGE_SEGMENT_LOW], 158 vinfo->levels_uv[SCMI_VOLTAGE_SEGMENT_HIGH], 159 sreg->id); 160 return -EINVAL; 161 } 162 163 if (!delta_uV) { 164 /* Just one fixed voltage exposed by SCMI */ 165 sreg->desc.fixed_uV = 166 vinfo->levels_uv[SCMI_VOLTAGE_SEGMENT_LOW]; 167 sreg->desc.n_voltages = 1; 168 sreg->desc.ops = &scmi_reg_fixed_ops; 169 } else { 170 /* One simple linear mapping. */ 171 sreg->desc.min_uV = 172 vinfo->levels_uv[SCMI_VOLTAGE_SEGMENT_LOW]; 173 sreg->desc.uV_step = 174 vinfo->levels_uv[SCMI_VOLTAGE_SEGMENT_STEP]; 175 sreg->desc.linear_min_sel = 0; 176 sreg->desc.n_voltages = (delta_uV / sreg->desc.uV_step) + 1; 177 sreg->desc.ops = &scmi_reg_linear_ops; 178 } 179 180 return 0; 181 } 182 183 static int 184 scmi_config_discrete_regulator_mappings(struct scmi_regulator *sreg, 185 const struct scmi_voltage_info *vinfo) 186 { 187 /* Discrete non linear levels are mapped to volt_table */ 188 sreg->desc.n_voltages = vinfo->num_levels; 189 190 if (sreg->desc.n_voltages > 1) { 191 sreg->desc.volt_table = (const unsigned int *)vinfo->levels_uv; 192 sreg->desc.ops = &scmi_reg_discrete_ops; 193 } else { 194 sreg->desc.fixed_uV = vinfo->levels_uv[0]; 195 sreg->desc.ops = &scmi_reg_fixed_ops; 196 } 197 198 return 0; 199 } 200 201 static int scmi_regulator_common_init(struct scmi_regulator *sreg) 202 { 203 int ret; 204 struct device *dev = &sreg->sdev->dev; 205 const struct scmi_voltage_info *vinfo; 206 207 vinfo = voltage_ops->info_get(sreg->ph, sreg->id); 208 if (!vinfo) { 209 dev_warn(dev, "Failure to get voltage domain %d\n", 210 sreg->id); 211 return -ENODEV; 212 } 213 214 /* 215 * Regulator framework does not fully support negative voltages 216 * so we discard any voltage domain reported as supporting negative 217 * voltages: as a consequence each levels_uv entry is guaranteed to 218 * be non-negative from here on. 219 */ 220 if (vinfo->negative_volts_allowed) { 221 dev_warn(dev, "Negative voltages NOT supported...skip %s\n", 222 sreg->of_node->full_name); 223 return -EOPNOTSUPP; 224 } 225 226 sreg->desc.name = devm_kasprintf(dev, GFP_KERNEL, "%s", vinfo->name); 227 if (!sreg->desc.name) 228 return -ENOMEM; 229 230 sreg->desc.id = sreg->id; 231 sreg->desc.type = REGULATOR_VOLTAGE; 232 sreg->desc.owner = THIS_MODULE; 233 sreg->desc.of_match_full_name = true; 234 sreg->desc.of_match = sreg->of_node->full_name; 235 sreg->desc.regulators_node = "regulators"; 236 if (vinfo->segmented) 237 ret = scmi_config_linear_regulator_mappings(sreg, vinfo); 238 else 239 ret = scmi_config_discrete_regulator_mappings(sreg, vinfo); 240 if (ret) 241 return ret; 242 243 /* 244 * Using the scmi device here to have DT searched from Voltage 245 * protocol node down. 246 */ 247 sreg->conf.dev = dev; 248 249 /* Store for later retrieval via rdev_get_drvdata() */ 250 sreg->conf.driver_data = sreg; 251 252 return 0; 253 } 254 255 static int process_scmi_regulator_of_node(struct scmi_device *sdev, 256 struct scmi_protocol_handle *ph, 257 struct device_node *np, 258 struct scmi_regulator_info *rinfo) 259 { 260 u32 dom; 261 int ret; 262 263 ret = of_property_read_u32(np, "reg", &dom); 264 if (ret) 265 return ret; 266 267 if (dom >= rinfo->num_doms) 268 return -ENODEV; 269 270 if (rinfo->sregv[dom]) { 271 dev_err(&sdev->dev, 272 "SCMI Voltage Domain %d already in use. Skipping: %s\n", 273 dom, np->full_name); 274 return -EINVAL; 275 } 276 277 rinfo->sregv[dom] = devm_kzalloc(&sdev->dev, 278 sizeof(struct scmi_regulator), 279 GFP_KERNEL); 280 if (!rinfo->sregv[dom]) 281 return -ENOMEM; 282 283 rinfo->sregv[dom]->id = dom; 284 rinfo->sregv[dom]->sdev = sdev; 285 rinfo->sregv[dom]->ph = ph; 286 287 /* get hold of good nodes */ 288 of_node_get(np); 289 rinfo->sregv[dom]->of_node = np; 290 291 dev_dbg(&sdev->dev, 292 "Found SCMI Regulator entry -- OF node [%d] -> %s\n", 293 dom, np->full_name); 294 295 return 0; 296 } 297 298 static int scmi_regulator_probe(struct scmi_device *sdev) 299 { 300 int d, ret, num_doms; 301 struct device_node *np; 302 const struct scmi_handle *handle = sdev->handle; 303 struct scmi_regulator_info *rinfo; 304 struct scmi_protocol_handle *ph; 305 306 if (!handle) 307 return -ENODEV; 308 309 voltage_ops = handle->devm_protocol_get(sdev, 310 SCMI_PROTOCOL_VOLTAGE, &ph); 311 if (IS_ERR(voltage_ops)) 312 return PTR_ERR(voltage_ops); 313 314 num_doms = voltage_ops->num_domains_get(ph); 315 if (!num_doms) 316 return 0; 317 318 if (num_doms < 0) { 319 dev_err(&sdev->dev, "failed to get voltage domains - err:%d\n", 320 num_doms); 321 322 return num_doms; 323 } 324 325 rinfo = devm_kzalloc(&sdev->dev, sizeof(*rinfo), GFP_KERNEL); 326 if (!rinfo) 327 return -ENOMEM; 328 329 /* Allocate pointers array for all possible domains */ 330 rinfo->sregv = devm_kcalloc(&sdev->dev, num_doms, 331 sizeof(void *), GFP_KERNEL); 332 if (!rinfo->sregv) 333 return -ENOMEM; 334 335 rinfo->num_doms = num_doms; 336 337 /* 338 * Start collecting into rinfo->sregv possibly good SCMI Regulators as 339 * described by a well-formed DT entry and associated with an existing 340 * plausible SCMI Voltage Domain number, all belonging to this SCMI 341 * platform instance node (handle->dev->of_node). 342 */ 343 of_node_get(handle->dev->of_node); 344 np = of_find_node_by_name(handle->dev->of_node, "regulators"); 345 for_each_child_of_node_scoped(np, child) { 346 ret = process_scmi_regulator_of_node(sdev, ph, child, rinfo); 347 /* abort on any mem issue */ 348 if (ret == -ENOMEM) 349 return ret; 350 } 351 of_node_put(np); 352 /* 353 * Register a regulator for each valid regulator-DT-entry that we 354 * can successfully reach via SCMI and has a valid associated voltage 355 * domain. 356 */ 357 for (d = 0; d < num_doms; d++) { 358 struct scmi_regulator *sreg = rinfo->sregv[d]; 359 360 /* Skip empty slots */ 361 if (!sreg) 362 continue; 363 364 ret = scmi_regulator_common_init(sreg); 365 /* Skip invalid voltage domains */ 366 if (ret) 367 continue; 368 369 sreg->rdev = devm_regulator_register(&sdev->dev, &sreg->desc, 370 &sreg->conf); 371 if (IS_ERR(sreg->rdev)) { 372 sreg->rdev = NULL; 373 continue; 374 } 375 376 dev_info(&sdev->dev, 377 "Regulator %s registered for domain [%d]\n", 378 sreg->desc.name, sreg->id); 379 } 380 381 dev_set_drvdata(&sdev->dev, rinfo); 382 383 return 0; 384 } 385 386 static void scmi_regulator_remove(struct scmi_device *sdev) 387 { 388 int d; 389 struct scmi_regulator_info *rinfo; 390 391 rinfo = dev_get_drvdata(&sdev->dev); 392 if (!rinfo) 393 return; 394 395 for (d = 0; d < rinfo->num_doms; d++) { 396 if (!rinfo->sregv[d]) 397 continue; 398 of_node_put(rinfo->sregv[d]->of_node); 399 } 400 } 401 402 static const struct scmi_device_id scmi_regulator_id_table[] = { 403 { SCMI_PROTOCOL_VOLTAGE, "regulator" }, 404 { }, 405 }; 406 MODULE_DEVICE_TABLE(scmi, scmi_regulator_id_table); 407 408 static struct scmi_driver scmi_drv = { 409 .name = "scmi-regulator", 410 .probe = scmi_regulator_probe, 411 .remove = scmi_regulator_remove, 412 .id_table = scmi_regulator_id_table, 413 }; 414 415 module_scmi_driver(scmi_drv); 416 417 MODULE_AUTHOR("Cristian Marussi <cristian.marussi@arm.com>"); 418 MODULE_DESCRIPTION("ARM SCMI regulator driver"); 419 MODULE_LICENSE("GPL v2"); 420