1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2016-2017 Texas Instruments Incorporated - http://www.ti.com/ 4 * Nishanth Menon <nm@ti.com> 5 * Dave Gerlach <d-gerlach@ti.com> 6 * 7 * TI OPP supply driver that provides override into the regulator control 8 * for generic opp core to handle devices with ABB regulator and/or 9 * SmartReflex Class0. 10 */ 11 #include <linux/clk.h> 12 #include <linux/cpufreq.h> 13 #include <linux/device.h> 14 #include <linux/io.h> 15 #include <linux/module.h> 16 #include <linux/notifier.h> 17 #include <linux/of_device.h> 18 #include <linux/of.h> 19 #include <linux/platform_device.h> 20 #include <linux/pm_opp.h> 21 #include <linux/regulator/consumer.h> 22 #include <linux/slab.h> 23 24 /** 25 * struct ti_opp_supply_optimum_voltage_table - optimized voltage table 26 * @reference_uv: reference voltage (usually Nominal voltage) 27 * @optimized_uv: Optimized voltage from efuse 28 */ 29 struct ti_opp_supply_optimum_voltage_table { 30 unsigned int reference_uv; 31 unsigned int optimized_uv; 32 }; 33 34 /** 35 * struct ti_opp_supply_data - OMAP specific opp supply data 36 * @vdd_table: Optimized voltage mapping table 37 * @num_vdd_table: number of entries in vdd_table 38 * @vdd_absolute_max_voltage_uv: absolute maximum voltage in UV for the supply 39 */ 40 struct ti_opp_supply_data { 41 struct ti_opp_supply_optimum_voltage_table *vdd_table; 42 u32 num_vdd_table; 43 u32 vdd_absolute_max_voltage_uv; 44 }; 45 46 static struct ti_opp_supply_data opp_data; 47 48 /** 49 * struct ti_opp_supply_of_data - device tree match data 50 * @flags: specific type of opp supply 51 * @efuse_voltage_mask: mask required for efuse register representing voltage 52 * @efuse_voltage_uv: Are the efuse entries in micro-volts? if not, assume 53 * milli-volts. 54 */ 55 struct ti_opp_supply_of_data { 56 #define OPPDM_EFUSE_CLASS0_OPTIMIZED_VOLTAGE BIT(1) 57 #define OPPDM_HAS_NO_ABB BIT(2) 58 const u8 flags; 59 const u32 efuse_voltage_mask; 60 const bool efuse_voltage_uv; 61 }; 62 63 /** 64 * _store_optimized_voltages() - store optimized voltages 65 * @dev: ti opp supply device for which we need to store info 66 * @data: data specific to the device 67 * 68 * Picks up efuse based optimized voltages for VDD unique per device and 69 * stores it in internal data structure for use during transition requests. 70 * 71 * Return: If successful, 0, else appropriate error value. 72 */ 73 static int _store_optimized_voltages(struct device *dev, 74 struct ti_opp_supply_data *data) 75 { 76 void __iomem *base; 77 struct property *prop; 78 struct resource *res; 79 const __be32 *val; 80 int proplen, i; 81 int ret = 0; 82 struct ti_opp_supply_optimum_voltage_table *table; 83 const struct ti_opp_supply_of_data *of_data = dev_get_drvdata(dev); 84 85 /* pick up Efuse based voltages */ 86 res = platform_get_resource(to_platform_device(dev), IORESOURCE_MEM, 0); 87 if (!res) { 88 dev_err(dev, "Unable to get IO resource\n"); 89 ret = -ENODEV; 90 goto out_map; 91 } 92 93 base = ioremap_nocache(res->start, resource_size(res)); 94 if (!base) { 95 dev_err(dev, "Unable to map Efuse registers\n"); 96 ret = -ENOMEM; 97 goto out_map; 98 } 99 100 /* Fetch efuse-settings. */ 101 prop = of_find_property(dev->of_node, "ti,efuse-settings", NULL); 102 if (!prop) { 103 dev_err(dev, "No 'ti,efuse-settings' property found\n"); 104 ret = -EINVAL; 105 goto out; 106 } 107 108 proplen = prop->length / sizeof(int); 109 data->num_vdd_table = proplen / 2; 110 /* Verify for corrupted OPP entries in dt */ 111 if (data->num_vdd_table * 2 * sizeof(int) != prop->length) { 112 dev_err(dev, "Invalid 'ti,efuse-settings'\n"); 113 ret = -EINVAL; 114 goto out; 115 } 116 117 ret = of_property_read_u32(dev->of_node, "ti,absolute-max-voltage-uv", 118 &data->vdd_absolute_max_voltage_uv); 119 if (ret) { 120 dev_err(dev, "ti,absolute-max-voltage-uv is missing\n"); 121 ret = -EINVAL; 122 goto out; 123 } 124 125 table = kcalloc(data->num_vdd_table, sizeof(*data->vdd_table), 126 GFP_KERNEL); 127 if (!table) { 128 ret = -ENOMEM; 129 goto out; 130 } 131 data->vdd_table = table; 132 133 val = prop->value; 134 for (i = 0; i < data->num_vdd_table; i++, table++) { 135 u32 efuse_offset; 136 u32 tmp; 137 138 table->reference_uv = be32_to_cpup(val++); 139 efuse_offset = be32_to_cpup(val++); 140 141 tmp = readl(base + efuse_offset); 142 tmp &= of_data->efuse_voltage_mask; 143 tmp >>= __ffs(of_data->efuse_voltage_mask); 144 145 table->optimized_uv = of_data->efuse_voltage_uv ? tmp : 146 tmp * 1000; 147 148 dev_dbg(dev, "[%d] efuse=0x%08x volt_table=%d vset=%d\n", 149 i, efuse_offset, table->reference_uv, 150 table->optimized_uv); 151 152 /* 153 * Some older samples might not have optimized efuse 154 * Use reference voltage for those - just add debug message 155 * for them. 156 */ 157 if (!table->optimized_uv) { 158 dev_dbg(dev, "[%d] efuse=0x%08x volt_table=%d:vset0\n", 159 i, efuse_offset, table->reference_uv); 160 table->optimized_uv = table->reference_uv; 161 } 162 } 163 out: 164 iounmap(base); 165 out_map: 166 return ret; 167 } 168 169 /** 170 * _free_optimized_voltages() - free resources for optvoltages 171 * @dev: device for which we need to free info 172 * @data: data specific to the device 173 */ 174 static void _free_optimized_voltages(struct device *dev, 175 struct ti_opp_supply_data *data) 176 { 177 kfree(data->vdd_table); 178 data->vdd_table = NULL; 179 data->num_vdd_table = 0; 180 } 181 182 /** 183 * _get_optimal_vdd_voltage() - Finds optimal voltage for the supply 184 * @dev: device for which we need to find info 185 * @data: data specific to the device 186 * @reference_uv: reference voltage (OPP voltage) for which we need value 187 * 188 * Return: if a match is found, return optimized voltage, else return 189 * reference_uv, also return reference_uv if no optimization is needed. 190 */ 191 static int _get_optimal_vdd_voltage(struct device *dev, 192 struct ti_opp_supply_data *data, 193 int reference_uv) 194 { 195 int i; 196 struct ti_opp_supply_optimum_voltage_table *table; 197 198 if (!data->num_vdd_table) 199 return reference_uv; 200 201 table = data->vdd_table; 202 if (!table) 203 return -EINVAL; 204 205 /* Find a exact match - this list is usually very small */ 206 for (i = 0; i < data->num_vdd_table; i++, table++) 207 if (table->reference_uv == reference_uv) 208 return table->optimized_uv; 209 210 /* IF things are screwed up, we'd make a mess on console.. ratelimit */ 211 dev_err_ratelimited(dev, "%s: Failed optimized voltage match for %d\n", 212 __func__, reference_uv); 213 return reference_uv; 214 } 215 216 static int _opp_set_voltage(struct device *dev, 217 struct dev_pm_opp_supply *supply, 218 int new_target_uv, struct regulator *reg, 219 char *reg_name) 220 { 221 int ret; 222 unsigned long vdd_uv, uv_max; 223 224 if (new_target_uv) 225 vdd_uv = new_target_uv; 226 else 227 vdd_uv = supply->u_volt; 228 229 /* 230 * If we do have an absolute max voltage specified, then we should 231 * use that voltage instead to allow for cases where the voltage rails 232 * are ganged (example if we set the max for an opp as 1.12v, and 233 * the absolute max is 1.5v, for another rail to get 1.25v, it cannot 234 * be achieved if the regulator is constrainted to max of 1.12v, even 235 * if it can function at 1.25v 236 */ 237 if (opp_data.vdd_absolute_max_voltage_uv) 238 uv_max = opp_data.vdd_absolute_max_voltage_uv; 239 else 240 uv_max = supply->u_volt_max; 241 242 if (vdd_uv > uv_max || 243 vdd_uv < supply->u_volt_min || 244 supply->u_volt_min > uv_max) { 245 dev_warn(dev, 246 "Invalid range voltages [Min:%lu target:%lu Max:%lu]\n", 247 supply->u_volt_min, vdd_uv, uv_max); 248 return -EINVAL; 249 } 250 251 dev_dbg(dev, "%s scaling to %luuV[min %luuV max %luuV]\n", reg_name, 252 vdd_uv, supply->u_volt_min, 253 uv_max); 254 255 ret = regulator_set_voltage_triplet(reg, 256 supply->u_volt_min, 257 vdd_uv, 258 uv_max); 259 if (ret) { 260 dev_err(dev, "%s failed for %luuV[min %luuV max %luuV]\n", 261 reg_name, vdd_uv, supply->u_volt_min, 262 uv_max); 263 return ret; 264 } 265 266 return 0; 267 } 268 269 /** 270 * ti_opp_supply_set_opp() - do the opp supply transition 271 * @data: information on regulators and new and old opps provided by 272 * opp core to use in transition 273 * 274 * Return: If successful, 0, else appropriate error value. 275 */ 276 static int ti_opp_supply_set_opp(struct dev_pm_set_opp_data *data) 277 { 278 struct dev_pm_opp_supply *old_supply_vdd = &data->old_opp.supplies[0]; 279 struct dev_pm_opp_supply *old_supply_vbb = &data->old_opp.supplies[1]; 280 struct dev_pm_opp_supply *new_supply_vdd = &data->new_opp.supplies[0]; 281 struct dev_pm_opp_supply *new_supply_vbb = &data->new_opp.supplies[1]; 282 struct device *dev = data->dev; 283 unsigned long old_freq = data->old_opp.rate, freq = data->new_opp.rate; 284 struct clk *clk = data->clk; 285 struct regulator *vdd_reg = data->regulators[0]; 286 struct regulator *vbb_reg = data->regulators[1]; 287 int vdd_uv; 288 int ret; 289 290 vdd_uv = _get_optimal_vdd_voltage(dev, &opp_data, 291 new_supply_vbb->u_volt); 292 293 /* Scaling up? Scale voltage before frequency */ 294 if (freq > old_freq) { 295 ret = _opp_set_voltage(dev, new_supply_vdd, vdd_uv, vdd_reg, 296 "vdd"); 297 if (ret) 298 goto restore_voltage; 299 300 ret = _opp_set_voltage(dev, new_supply_vbb, 0, vbb_reg, "vbb"); 301 if (ret) 302 goto restore_voltage; 303 } 304 305 /* Change frequency */ 306 dev_dbg(dev, "%s: switching OPP: %lu Hz --> %lu Hz\n", 307 __func__, old_freq, freq); 308 309 ret = clk_set_rate(clk, freq); 310 if (ret) { 311 dev_err(dev, "%s: failed to set clock rate: %d\n", __func__, 312 ret); 313 goto restore_voltage; 314 } 315 316 /* Scaling down? Scale voltage after frequency */ 317 if (freq < old_freq) { 318 ret = _opp_set_voltage(dev, new_supply_vbb, 0, vbb_reg, "vbb"); 319 if (ret) 320 goto restore_freq; 321 322 ret = _opp_set_voltage(dev, new_supply_vdd, vdd_uv, vdd_reg, 323 "vdd"); 324 if (ret) 325 goto restore_freq; 326 } 327 328 return 0; 329 330 restore_freq: 331 ret = clk_set_rate(clk, old_freq); 332 if (ret) 333 dev_err(dev, "%s: failed to restore old-freq (%lu Hz)\n", 334 __func__, old_freq); 335 restore_voltage: 336 /* This shouldn't harm even if the voltages weren't updated earlier */ 337 if (old_supply_vdd->u_volt) { 338 ret = _opp_set_voltage(dev, old_supply_vbb, 0, vbb_reg, "vbb"); 339 if (ret) 340 return ret; 341 342 ret = _opp_set_voltage(dev, old_supply_vdd, 0, vdd_reg, 343 "vdd"); 344 if (ret) 345 return ret; 346 } 347 348 return ret; 349 } 350 351 static const struct ti_opp_supply_of_data omap_generic_of_data = { 352 }; 353 354 static const struct ti_opp_supply_of_data omap_omap5_of_data = { 355 .flags = OPPDM_EFUSE_CLASS0_OPTIMIZED_VOLTAGE, 356 .efuse_voltage_mask = 0xFFF, 357 .efuse_voltage_uv = false, 358 }; 359 360 static const struct ti_opp_supply_of_data omap_omap5core_of_data = { 361 .flags = OPPDM_EFUSE_CLASS0_OPTIMIZED_VOLTAGE | OPPDM_HAS_NO_ABB, 362 .efuse_voltage_mask = 0xFFF, 363 .efuse_voltage_uv = false, 364 }; 365 366 static const struct of_device_id ti_opp_supply_of_match[] = { 367 {.compatible = "ti,omap-opp-supply", .data = &omap_generic_of_data}, 368 {.compatible = "ti,omap5-opp-supply", .data = &omap_omap5_of_data}, 369 {.compatible = "ti,omap5-core-opp-supply", 370 .data = &omap_omap5core_of_data}, 371 {}, 372 }; 373 MODULE_DEVICE_TABLE(of, ti_opp_supply_of_match); 374 375 static int ti_opp_supply_probe(struct platform_device *pdev) 376 { 377 struct device *dev = &pdev->dev; 378 struct device *cpu_dev = get_cpu_device(0); 379 const struct of_device_id *match; 380 const struct ti_opp_supply_of_data *of_data; 381 int ret = 0; 382 383 match = of_match_device(ti_opp_supply_of_match, dev); 384 if (!match) { 385 /* We do not expect this to happen */ 386 dev_err(dev, "%s: Unable to match device\n", __func__); 387 return -ENODEV; 388 } 389 if (!match->data) { 390 /* Again, unlikely.. but mistakes do happen */ 391 dev_err(dev, "%s: Bad data in match\n", __func__); 392 return -EINVAL; 393 } 394 of_data = match->data; 395 396 dev_set_drvdata(dev, (void *)of_data); 397 398 /* If we need optimized voltage */ 399 if (of_data->flags & OPPDM_EFUSE_CLASS0_OPTIMIZED_VOLTAGE) { 400 ret = _store_optimized_voltages(dev, &opp_data); 401 if (ret) 402 return ret; 403 } 404 405 ret = PTR_ERR_OR_ZERO(dev_pm_opp_register_set_opp_helper(cpu_dev, 406 ti_opp_supply_set_opp)); 407 if (ret) 408 _free_optimized_voltages(dev, &opp_data); 409 410 return ret; 411 } 412 413 static struct platform_driver ti_opp_supply_driver = { 414 .probe = ti_opp_supply_probe, 415 .driver = { 416 .name = "ti_opp_supply", 417 .owner = THIS_MODULE, 418 .of_match_table = of_match_ptr(ti_opp_supply_of_match), 419 }, 420 }; 421 module_platform_driver(ti_opp_supply_driver); 422 423 MODULE_DESCRIPTION("Texas Instruments OMAP OPP Supply driver"); 424 MODULE_AUTHOR("Texas Instruments Inc."); 425 MODULE_LICENSE("GPL v2"); 426