0001
0002
0003
0004
0005
0006 #include <linux/clk.h>
0007 #include <linux/devfreq.h>
0008 #include <linux/minmax.h>
0009 #include <linux/module.h>
0010 #include <linux/of.h>
0011 #include <linux/of_device.h>
0012 #include <linux/platform_device.h>
0013 #include <linux/pm_opp.h>
0014 #include <linux/regulator/consumer.h>
0015
0016 struct mtk_ccifreq_platform_data {
0017 int min_volt_shift;
0018 int max_volt_shift;
0019 int proc_max_volt;
0020 int sram_min_volt;
0021 int sram_max_volt;
0022 };
0023
0024 struct mtk_ccifreq_drv {
0025 struct device *dev;
0026 struct devfreq *devfreq;
0027 struct regulator *proc_reg;
0028 struct regulator *sram_reg;
0029 struct clk *cci_clk;
0030 struct clk *inter_clk;
0031 int inter_voltage;
0032 unsigned long pre_freq;
0033
0034 struct mutex reg_lock;
0035 struct notifier_block opp_nb;
0036 const struct mtk_ccifreq_platform_data *soc_data;
0037 int vtrack_max;
0038 };
0039
0040 static int mtk_ccifreq_set_voltage(struct mtk_ccifreq_drv *drv, int new_voltage)
0041 {
0042 const struct mtk_ccifreq_platform_data *soc_data = drv->soc_data;
0043 struct device *dev = drv->dev;
0044 int pre_voltage, pre_vsram, new_vsram, vsram, voltage, ret;
0045 int retry_max = drv->vtrack_max;
0046
0047 if (!drv->sram_reg) {
0048 ret = regulator_set_voltage(drv->proc_reg, new_voltage,
0049 drv->soc_data->proc_max_volt);
0050 return ret;
0051 }
0052
0053 pre_voltage = regulator_get_voltage(drv->proc_reg);
0054 if (pre_voltage < 0) {
0055 dev_err(dev, "invalid vproc value: %d\n", pre_voltage);
0056 return pre_voltage;
0057 }
0058
0059 pre_vsram = regulator_get_voltage(drv->sram_reg);
0060 if (pre_vsram < 0) {
0061 dev_err(dev, "invalid vsram value: %d\n", pre_vsram);
0062 return pre_vsram;
0063 }
0064
0065 new_vsram = clamp(new_voltage + soc_data->min_volt_shift,
0066 soc_data->sram_min_volt, soc_data->sram_max_volt);
0067
0068 do {
0069 if (pre_voltage <= new_voltage) {
0070 vsram = clamp(pre_voltage + soc_data->max_volt_shift,
0071 soc_data->sram_min_volt, new_vsram);
0072 ret = regulator_set_voltage(drv->sram_reg, vsram,
0073 soc_data->sram_max_volt);
0074 if (ret)
0075 return ret;
0076
0077 if (vsram == soc_data->sram_max_volt ||
0078 new_vsram == soc_data->sram_min_volt)
0079 voltage = new_voltage;
0080 else
0081 voltage = vsram - soc_data->min_volt_shift;
0082
0083 ret = regulator_set_voltage(drv->proc_reg, voltage,
0084 soc_data->proc_max_volt);
0085 if (ret) {
0086 regulator_set_voltage(drv->sram_reg, pre_vsram,
0087 soc_data->sram_max_volt);
0088 return ret;
0089 }
0090 } else if (pre_voltage > new_voltage) {
0091 voltage = max(new_voltage,
0092 pre_vsram - soc_data->max_volt_shift);
0093 ret = regulator_set_voltage(drv->proc_reg, voltage,
0094 soc_data->proc_max_volt);
0095 if (ret)
0096 return ret;
0097
0098 if (voltage == new_voltage)
0099 vsram = new_vsram;
0100 else
0101 vsram = max(new_vsram,
0102 voltage + soc_data->min_volt_shift);
0103
0104 ret = regulator_set_voltage(drv->sram_reg, vsram,
0105 soc_data->sram_max_volt);
0106 if (ret) {
0107 regulator_set_voltage(drv->proc_reg, pre_voltage,
0108 soc_data->proc_max_volt);
0109 return ret;
0110 }
0111 }
0112
0113 pre_voltage = voltage;
0114 pre_vsram = vsram;
0115
0116 if (--retry_max < 0) {
0117 dev_err(dev,
0118 "over loop count, failed to set voltage\n");
0119 return -EINVAL;
0120 }
0121 } while (voltage != new_voltage || vsram != new_vsram);
0122
0123 return 0;
0124 }
0125
0126 static int mtk_ccifreq_target(struct device *dev, unsigned long *freq,
0127 u32 flags)
0128 {
0129 struct mtk_ccifreq_drv *drv = dev_get_drvdata(dev);
0130 struct clk *cci_pll = clk_get_parent(drv->cci_clk);
0131 struct dev_pm_opp *opp;
0132 unsigned long opp_rate;
0133 int voltage, pre_voltage, inter_voltage, target_voltage, ret;
0134
0135 if (!drv)
0136 return -EINVAL;
0137
0138 if (drv->pre_freq == *freq)
0139 return 0;
0140
0141 inter_voltage = drv->inter_voltage;
0142
0143 opp_rate = *freq;
0144 opp = devfreq_recommended_opp(dev, &opp_rate, 1);
0145 if (IS_ERR(opp)) {
0146 dev_err(dev, "failed to find opp for freq: %ld\n", opp_rate);
0147 return PTR_ERR(opp);
0148 }
0149
0150 mutex_lock(&drv->reg_lock);
0151
0152 voltage = dev_pm_opp_get_voltage(opp);
0153 dev_pm_opp_put(opp);
0154
0155 pre_voltage = regulator_get_voltage(drv->proc_reg);
0156 if (pre_voltage < 0) {
0157 dev_err(dev, "invalid vproc value: %d\n", pre_voltage);
0158 ret = pre_voltage;
0159 goto out_unlock;
0160 }
0161
0162
0163 target_voltage = max(inter_voltage, voltage);
0164 if (pre_voltage <= target_voltage) {
0165 ret = mtk_ccifreq_set_voltage(drv, target_voltage);
0166 if (ret) {
0167 dev_err(dev, "failed to scale up voltage\n");
0168 goto out_restore_voltage;
0169 }
0170 }
0171
0172
0173 ret = clk_set_parent(drv->cci_clk, drv->inter_clk);
0174 if (ret) {
0175 dev_err(dev, "failed to re-parent cci clock\n");
0176 goto out_restore_voltage;
0177 }
0178
0179
0180 ret = clk_set_rate(cci_pll, *freq);
0181 if (ret) {
0182 dev_err(dev, "failed to set cci pll rate: %d\n", ret);
0183 clk_set_parent(drv->cci_clk, cci_pll);
0184 goto out_restore_voltage;
0185 }
0186
0187
0188 ret = clk_set_parent(drv->cci_clk, cci_pll);
0189 if (ret) {
0190 dev_err(dev, "failed to re-parent cci clock\n");
0191 mtk_ccifreq_set_voltage(drv, inter_voltage);
0192 goto out_unlock;
0193 }
0194
0195
0196
0197
0198
0199 if (voltage < inter_voltage || voltage < pre_voltage) {
0200 ret = mtk_ccifreq_set_voltage(drv, voltage);
0201 if (ret) {
0202 dev_err(dev, "failed to scale down voltage\n");
0203 goto out_unlock;
0204 }
0205 }
0206
0207 drv->pre_freq = *freq;
0208 mutex_unlock(&drv->reg_lock);
0209
0210 return 0;
0211
0212 out_restore_voltage:
0213 mtk_ccifreq_set_voltage(drv, pre_voltage);
0214
0215 out_unlock:
0216 mutex_unlock(&drv->reg_lock);
0217 return ret;
0218 }
0219
0220 static int mtk_ccifreq_opp_notifier(struct notifier_block *nb,
0221 unsigned long event, void *data)
0222 {
0223 struct dev_pm_opp *opp = data;
0224 struct mtk_ccifreq_drv *drv;
0225 unsigned long freq, volt;
0226
0227 drv = container_of(nb, struct mtk_ccifreq_drv, opp_nb);
0228
0229 if (event == OPP_EVENT_ADJUST_VOLTAGE) {
0230 freq = dev_pm_opp_get_freq(opp);
0231
0232 mutex_lock(&drv->reg_lock);
0233
0234 if (freq == drv->pre_freq) {
0235 volt = dev_pm_opp_get_voltage(opp);
0236 mtk_ccifreq_set_voltage(drv, volt);
0237 }
0238 mutex_unlock(&drv->reg_lock);
0239 }
0240
0241 return 0;
0242 }
0243
0244 static struct devfreq_dev_profile mtk_ccifreq_profile = {
0245 .target = mtk_ccifreq_target,
0246 };
0247
0248 static int mtk_ccifreq_probe(struct platform_device *pdev)
0249 {
0250 struct device *dev = &pdev->dev;
0251 struct mtk_ccifreq_drv *drv;
0252 struct devfreq_passive_data *passive_data;
0253 struct dev_pm_opp *opp;
0254 unsigned long rate, opp_volt;
0255 int ret;
0256
0257 drv = devm_kzalloc(dev, sizeof(*drv), GFP_KERNEL);
0258 if (!drv)
0259 return -ENOMEM;
0260
0261 drv->dev = dev;
0262 drv->soc_data = (const struct mtk_ccifreq_platform_data *)
0263 of_device_get_match_data(&pdev->dev);
0264 mutex_init(&drv->reg_lock);
0265 platform_set_drvdata(pdev, drv);
0266
0267 drv->cci_clk = devm_clk_get(dev, "cci");
0268 if (IS_ERR(drv->cci_clk)) {
0269 ret = PTR_ERR(drv->cci_clk);
0270 return dev_err_probe(dev, ret, "failed to get cci clk\n");
0271 }
0272
0273 drv->inter_clk = devm_clk_get(dev, "intermediate");
0274 if (IS_ERR(drv->inter_clk)) {
0275 ret = PTR_ERR(drv->inter_clk);
0276 return dev_err_probe(dev, ret,
0277 "failed to get intermediate clk\n");
0278 }
0279
0280 drv->proc_reg = devm_regulator_get_optional(dev, "proc");
0281 if (IS_ERR(drv->proc_reg)) {
0282 ret = PTR_ERR(drv->proc_reg);
0283 return dev_err_probe(dev, ret,
0284 "failed to get proc regulator\n");
0285 }
0286
0287 ret = regulator_enable(drv->proc_reg);
0288 if (ret) {
0289 dev_err(dev, "failed to enable proc regulator\n");
0290 return ret;
0291 }
0292
0293 drv->sram_reg = devm_regulator_get_optional(dev, "sram");
0294 if (IS_ERR(drv->sram_reg))
0295 drv->sram_reg = NULL;
0296 else {
0297 ret = regulator_enable(drv->sram_reg);
0298 if (ret) {
0299 dev_err(dev, "failed to enable sram regulator\n");
0300 goto out_free_resources;
0301 }
0302 }
0303
0304
0305
0306
0307
0308
0309 drv->vtrack_max = 3 * DIV_ROUND_UP(max(drv->soc_data->sram_max_volt,
0310 drv->soc_data->proc_max_volt),
0311 drv->soc_data->min_volt_shift);
0312
0313 ret = clk_prepare_enable(drv->cci_clk);
0314 if (ret)
0315 goto out_free_resources;
0316
0317 ret = dev_pm_opp_of_add_table(dev);
0318 if (ret) {
0319 dev_err(dev, "failed to add opp table: %d\n", ret);
0320 goto out_disable_cci_clk;
0321 }
0322
0323 rate = clk_get_rate(drv->inter_clk);
0324 opp = dev_pm_opp_find_freq_ceil(dev, &rate);
0325 if (IS_ERR(opp)) {
0326 ret = PTR_ERR(opp);
0327 dev_err(dev, "failed to get intermediate opp: %d\n", ret);
0328 goto out_remove_opp_table;
0329 }
0330 drv->inter_voltage = dev_pm_opp_get_voltage(opp);
0331 dev_pm_opp_put(opp);
0332
0333 rate = U32_MAX;
0334 opp = dev_pm_opp_find_freq_floor(drv->dev, &rate);
0335 if (IS_ERR(opp)) {
0336 dev_err(dev, "failed to get opp\n");
0337 ret = PTR_ERR(opp);
0338 goto out_remove_opp_table;
0339 }
0340
0341 opp_volt = dev_pm_opp_get_voltage(opp);
0342 dev_pm_opp_put(opp);
0343 ret = mtk_ccifreq_set_voltage(drv, opp_volt);
0344 if (ret) {
0345 dev_err(dev, "failed to scale to highest voltage %lu in proc_reg\n",
0346 opp_volt);
0347 goto out_remove_opp_table;
0348 }
0349
0350 passive_data = devm_kzalloc(dev, sizeof(*passive_data), GFP_KERNEL);
0351 if (!passive_data) {
0352 ret = -ENOMEM;
0353 goto out_remove_opp_table;
0354 }
0355
0356 passive_data->parent_type = CPUFREQ_PARENT_DEV;
0357 drv->devfreq = devm_devfreq_add_device(dev, &mtk_ccifreq_profile,
0358 DEVFREQ_GOV_PASSIVE,
0359 passive_data);
0360 if (IS_ERR(drv->devfreq)) {
0361 ret = -EPROBE_DEFER;
0362 dev_err(dev, "failed to add devfreq device: %ld\n",
0363 PTR_ERR(drv->devfreq));
0364 goto out_remove_opp_table;
0365 }
0366
0367 drv->opp_nb.notifier_call = mtk_ccifreq_opp_notifier;
0368 ret = dev_pm_opp_register_notifier(dev, &drv->opp_nb);
0369 if (ret) {
0370 dev_err(dev, "failed to register opp notifier: %d\n", ret);
0371 goto out_remove_opp_table;
0372 }
0373 return 0;
0374
0375 out_remove_opp_table:
0376 dev_pm_opp_of_remove_table(dev);
0377
0378 out_disable_cci_clk:
0379 clk_disable_unprepare(drv->cci_clk);
0380
0381 out_free_resources:
0382 if (regulator_is_enabled(drv->proc_reg))
0383 regulator_disable(drv->proc_reg);
0384 if (drv->sram_reg && regulator_is_enabled(drv->sram_reg))
0385 regulator_disable(drv->sram_reg);
0386
0387 return ret;
0388 }
0389
0390 static int mtk_ccifreq_remove(struct platform_device *pdev)
0391 {
0392 struct device *dev = &pdev->dev;
0393 struct mtk_ccifreq_drv *drv;
0394
0395 drv = platform_get_drvdata(pdev);
0396
0397 dev_pm_opp_unregister_notifier(dev, &drv->opp_nb);
0398 dev_pm_opp_of_remove_table(dev);
0399 clk_disable_unprepare(drv->cci_clk);
0400 regulator_disable(drv->proc_reg);
0401 if (drv->sram_reg)
0402 regulator_disable(drv->sram_reg);
0403
0404 return 0;
0405 }
0406
0407 static const struct mtk_ccifreq_platform_data mt8183_platform_data = {
0408 .min_volt_shift = 100000,
0409 .max_volt_shift = 200000,
0410 .proc_max_volt = 1150000,
0411 };
0412
0413 static const struct mtk_ccifreq_platform_data mt8186_platform_data = {
0414 .min_volt_shift = 100000,
0415 .max_volt_shift = 250000,
0416 .proc_max_volt = 1118750,
0417 .sram_min_volt = 850000,
0418 .sram_max_volt = 1118750,
0419 };
0420
0421 static const struct of_device_id mtk_ccifreq_machines[] = {
0422 { .compatible = "mediatek,mt8183-cci", .data = &mt8183_platform_data },
0423 { .compatible = "mediatek,mt8186-cci", .data = &mt8186_platform_data },
0424 { },
0425 };
0426 MODULE_DEVICE_TABLE(of, mtk_ccifreq_machines);
0427
0428 static struct platform_driver mtk_ccifreq_platdrv = {
0429 .probe = mtk_ccifreq_probe,
0430 .remove = mtk_ccifreq_remove,
0431 .driver = {
0432 .name = "mtk-ccifreq",
0433 .of_match_table = mtk_ccifreq_machines,
0434 },
0435 };
0436 module_platform_driver(mtk_ccifreq_platdrv);
0437
0438 MODULE_DESCRIPTION("MediaTek CCI devfreq driver");
0439 MODULE_AUTHOR("Jia-Wei Chang <jia-wei.chang@mediatek.com>");
0440 MODULE_LICENSE("GPL v2");