0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/clk.h>
0012 #include <linux/cpufreq.h>
0013 #include <linux/device.h>
0014 #include <linux/io.h>
0015 #include <linux/module.h>
0016 #include <linux/notifier.h>
0017 #include <linux/of_device.h>
0018 #include <linux/of.h>
0019 #include <linux/platform_device.h>
0020 #include <linux/pm_opp.h>
0021 #include <linux/regulator/consumer.h>
0022 #include <linux/slab.h>
0023
0024
0025
0026
0027
0028
0029 struct ti_opp_supply_optimum_voltage_table {
0030 unsigned int reference_uv;
0031 unsigned int optimized_uv;
0032 };
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042 struct ti_opp_supply_data {
0043 struct ti_opp_supply_optimum_voltage_table *vdd_table;
0044 u32 num_vdd_table;
0045 u32 vdd_absolute_max_voltage_uv;
0046 struct dev_pm_opp_supply old_supplies[2];
0047 struct dev_pm_opp_supply new_supplies[2];
0048 };
0049
0050 static struct ti_opp_supply_data opp_data;
0051
0052
0053
0054
0055
0056
0057
0058
0059 struct ti_opp_supply_of_data {
0060 #define OPPDM_EFUSE_CLASS0_OPTIMIZED_VOLTAGE BIT(1)
0061 #define OPPDM_HAS_NO_ABB BIT(2)
0062 const u8 flags;
0063 const u32 efuse_voltage_mask;
0064 const bool efuse_voltage_uv;
0065 };
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077 static int _store_optimized_voltages(struct device *dev,
0078 struct ti_opp_supply_data *data)
0079 {
0080 void __iomem *base;
0081 struct property *prop;
0082 struct resource *res;
0083 const __be32 *val;
0084 int proplen, i;
0085 int ret = 0;
0086 struct ti_opp_supply_optimum_voltage_table *table;
0087 const struct ti_opp_supply_of_data *of_data = dev_get_drvdata(dev);
0088
0089
0090 res = platform_get_resource(to_platform_device(dev), IORESOURCE_MEM, 0);
0091 if (!res) {
0092 dev_err(dev, "Unable to get IO resource\n");
0093 ret = -ENODEV;
0094 goto out_map;
0095 }
0096
0097 base = ioremap(res->start, resource_size(res));
0098 if (!base) {
0099 dev_err(dev, "Unable to map Efuse registers\n");
0100 ret = -ENOMEM;
0101 goto out_map;
0102 }
0103
0104
0105 prop = of_find_property(dev->of_node, "ti,efuse-settings", NULL);
0106 if (!prop) {
0107 dev_err(dev, "No 'ti,efuse-settings' property found\n");
0108 ret = -EINVAL;
0109 goto out;
0110 }
0111
0112 proplen = prop->length / sizeof(int);
0113 data->num_vdd_table = proplen / 2;
0114
0115 if (data->num_vdd_table * 2 * sizeof(int) != prop->length) {
0116 dev_err(dev, "Invalid 'ti,efuse-settings'\n");
0117 ret = -EINVAL;
0118 goto out;
0119 }
0120
0121 ret = of_property_read_u32(dev->of_node, "ti,absolute-max-voltage-uv",
0122 &data->vdd_absolute_max_voltage_uv);
0123 if (ret) {
0124 dev_err(dev, "ti,absolute-max-voltage-uv is missing\n");
0125 ret = -EINVAL;
0126 goto out;
0127 }
0128
0129 table = kcalloc(data->num_vdd_table, sizeof(*data->vdd_table),
0130 GFP_KERNEL);
0131 if (!table) {
0132 ret = -ENOMEM;
0133 goto out;
0134 }
0135 data->vdd_table = table;
0136
0137 val = prop->value;
0138 for (i = 0; i < data->num_vdd_table; i++, table++) {
0139 u32 efuse_offset;
0140 u32 tmp;
0141
0142 table->reference_uv = be32_to_cpup(val++);
0143 efuse_offset = be32_to_cpup(val++);
0144
0145 tmp = readl(base + efuse_offset);
0146 tmp &= of_data->efuse_voltage_mask;
0147 tmp >>= __ffs(of_data->efuse_voltage_mask);
0148
0149 table->optimized_uv = of_data->efuse_voltage_uv ? tmp :
0150 tmp * 1000;
0151
0152 dev_dbg(dev, "[%d] efuse=0x%08x volt_table=%d vset=%d\n",
0153 i, efuse_offset, table->reference_uv,
0154 table->optimized_uv);
0155
0156
0157
0158
0159
0160
0161 if (!table->optimized_uv) {
0162 dev_dbg(dev, "[%d] efuse=0x%08x volt_table=%d:vset0\n",
0163 i, efuse_offset, table->reference_uv);
0164 table->optimized_uv = table->reference_uv;
0165 }
0166 }
0167 out:
0168 iounmap(base);
0169 out_map:
0170 return ret;
0171 }
0172
0173
0174
0175
0176
0177
0178 static void _free_optimized_voltages(struct device *dev,
0179 struct ti_opp_supply_data *data)
0180 {
0181 kfree(data->vdd_table);
0182 data->vdd_table = NULL;
0183 data->num_vdd_table = 0;
0184 }
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195 static int _get_optimal_vdd_voltage(struct device *dev,
0196 struct ti_opp_supply_data *data,
0197 int reference_uv)
0198 {
0199 int i;
0200 struct ti_opp_supply_optimum_voltage_table *table;
0201
0202 if (!data->num_vdd_table)
0203 return reference_uv;
0204
0205 table = data->vdd_table;
0206 if (!table)
0207 return -EINVAL;
0208
0209
0210 for (i = 0; i < data->num_vdd_table; i++, table++)
0211 if (table->reference_uv == reference_uv)
0212 return table->optimized_uv;
0213
0214
0215 dev_err_ratelimited(dev, "%s: Failed optimized voltage match for %d\n",
0216 __func__, reference_uv);
0217 return reference_uv;
0218 }
0219
0220 static int _opp_set_voltage(struct device *dev,
0221 struct dev_pm_opp_supply *supply,
0222 int new_target_uv, struct regulator *reg,
0223 char *reg_name)
0224 {
0225 int ret;
0226 unsigned long vdd_uv, uv_max;
0227
0228 if (new_target_uv)
0229 vdd_uv = new_target_uv;
0230 else
0231 vdd_uv = supply->u_volt;
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241 if (opp_data.vdd_absolute_max_voltage_uv)
0242 uv_max = opp_data.vdd_absolute_max_voltage_uv;
0243 else
0244 uv_max = supply->u_volt_max;
0245
0246 if (vdd_uv > uv_max ||
0247 vdd_uv < supply->u_volt_min ||
0248 supply->u_volt_min > uv_max) {
0249 dev_warn(dev,
0250 "Invalid range voltages [Min:%lu target:%lu Max:%lu]\n",
0251 supply->u_volt_min, vdd_uv, uv_max);
0252 return -EINVAL;
0253 }
0254
0255 dev_dbg(dev, "%s scaling to %luuV[min %luuV max %luuV]\n", reg_name,
0256 vdd_uv, supply->u_volt_min,
0257 uv_max);
0258
0259 ret = regulator_set_voltage_triplet(reg,
0260 supply->u_volt_min,
0261 vdd_uv,
0262 uv_max);
0263 if (ret) {
0264 dev_err(dev, "%s failed for %luuV[min %luuV max %luuV]\n",
0265 reg_name, vdd_uv, supply->u_volt_min,
0266 uv_max);
0267 return ret;
0268 }
0269
0270 return 0;
0271 }
0272
0273
0274 static int ti_opp_config_regulators(struct device *dev,
0275 struct dev_pm_opp *old_opp, struct dev_pm_opp *new_opp,
0276 struct regulator **regulators, unsigned int count)
0277 {
0278 struct dev_pm_opp_supply *old_supply_vdd = &opp_data.old_supplies[0];
0279 struct dev_pm_opp_supply *old_supply_vbb = &opp_data.old_supplies[1];
0280 struct dev_pm_opp_supply *new_supply_vdd = &opp_data.new_supplies[0];
0281 struct dev_pm_opp_supply *new_supply_vbb = &opp_data.new_supplies[1];
0282 struct regulator *vdd_reg = regulators[0];
0283 struct regulator *vbb_reg = regulators[1];
0284 unsigned long old_freq, freq;
0285 int vdd_uv;
0286 int ret;
0287
0288
0289 WARN_ON(count != 2);
0290
0291
0292 ret = dev_pm_opp_get_supplies(new_opp, opp_data.new_supplies);
0293 WARN_ON(ret);
0294
0295 old_freq = dev_pm_opp_get_freq(old_opp);
0296 freq = dev_pm_opp_get_freq(new_opp);
0297 WARN_ON(!old_freq || !freq);
0298
0299 vdd_uv = _get_optimal_vdd_voltage(dev, &opp_data,
0300 new_supply_vdd->u_volt);
0301
0302 if (new_supply_vdd->u_volt_min < vdd_uv)
0303 new_supply_vdd->u_volt_min = vdd_uv;
0304
0305
0306 if (freq > old_freq) {
0307 ret = _opp_set_voltage(dev, new_supply_vdd, vdd_uv, vdd_reg,
0308 "vdd");
0309 if (ret)
0310 goto restore_voltage;
0311
0312 ret = _opp_set_voltage(dev, new_supply_vbb, 0, vbb_reg, "vbb");
0313 if (ret)
0314 goto restore_voltage;
0315 } else {
0316 ret = _opp_set_voltage(dev, new_supply_vbb, 0, vbb_reg, "vbb");
0317 if (ret)
0318 goto restore_voltage;
0319
0320 ret = _opp_set_voltage(dev, new_supply_vdd, vdd_uv, vdd_reg,
0321 "vdd");
0322 if (ret)
0323 goto restore_voltage;
0324 }
0325
0326 return 0;
0327
0328 restore_voltage:
0329
0330 ret = dev_pm_opp_get_supplies(old_opp, opp_data.old_supplies);
0331 WARN_ON(ret);
0332
0333
0334 if (old_supply_vdd->u_volt) {
0335 ret = _opp_set_voltage(dev, old_supply_vbb, 0, vbb_reg, "vbb");
0336 if (ret)
0337 return ret;
0338
0339 ret = _opp_set_voltage(dev, old_supply_vdd, 0, vdd_reg,
0340 "vdd");
0341 if (ret)
0342 return ret;
0343 }
0344
0345 return ret;
0346 }
0347
0348 static const struct ti_opp_supply_of_data omap_generic_of_data = {
0349 };
0350
0351 static const struct ti_opp_supply_of_data omap_omap5_of_data = {
0352 .flags = OPPDM_EFUSE_CLASS0_OPTIMIZED_VOLTAGE,
0353 .efuse_voltage_mask = 0xFFF,
0354 .efuse_voltage_uv = false,
0355 };
0356
0357 static const struct ti_opp_supply_of_data omap_omap5core_of_data = {
0358 .flags = OPPDM_EFUSE_CLASS0_OPTIMIZED_VOLTAGE | OPPDM_HAS_NO_ABB,
0359 .efuse_voltage_mask = 0xFFF,
0360 .efuse_voltage_uv = false,
0361 };
0362
0363 static const struct of_device_id ti_opp_supply_of_match[] = {
0364 {.compatible = "ti,omap-opp-supply", .data = &omap_generic_of_data},
0365 {.compatible = "ti,omap5-opp-supply", .data = &omap_omap5_of_data},
0366 {.compatible = "ti,omap5-core-opp-supply",
0367 .data = &omap_omap5core_of_data},
0368 {},
0369 };
0370 MODULE_DEVICE_TABLE(of, ti_opp_supply_of_match);
0371
0372 static int ti_opp_supply_probe(struct platform_device *pdev)
0373 {
0374 struct device *dev = &pdev->dev;
0375 struct device *cpu_dev = get_cpu_device(0);
0376 const struct of_device_id *match;
0377 const struct ti_opp_supply_of_data *of_data;
0378 int ret = 0;
0379
0380 match = of_match_device(ti_opp_supply_of_match, dev);
0381 if (!match) {
0382
0383 dev_err(dev, "%s: Unable to match device\n", __func__);
0384 return -ENODEV;
0385 }
0386 if (!match->data) {
0387
0388 dev_err(dev, "%s: Bad data in match\n", __func__);
0389 return -EINVAL;
0390 }
0391 of_data = match->data;
0392
0393 dev_set_drvdata(dev, (void *)of_data);
0394
0395
0396 if (of_data->flags & OPPDM_EFUSE_CLASS0_OPTIMIZED_VOLTAGE) {
0397 ret = _store_optimized_voltages(dev, &opp_data);
0398 if (ret)
0399 return ret;
0400 }
0401
0402 ret = dev_pm_opp_set_config_regulators(cpu_dev, ti_opp_config_regulators);
0403 if (ret < 0)
0404 _free_optimized_voltages(dev, &opp_data);
0405
0406 return ret;
0407 }
0408
0409 static struct platform_driver ti_opp_supply_driver = {
0410 .probe = ti_opp_supply_probe,
0411 .driver = {
0412 .name = "ti_opp_supply",
0413 .of_match_table = of_match_ptr(ti_opp_supply_of_match),
0414 },
0415 };
0416 module_platform_driver(ti_opp_supply_driver);
0417
0418 MODULE_DESCRIPTION("Texas Instruments OMAP OPP Supply driver");
0419 MODULE_AUTHOR("Texas Instruments Inc.");
0420 MODULE_LICENSE("GPL v2");