Merge tag 'for-6.6-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave...
[platform/kernel/linux-rpi.git] / drivers / devfreq / mtk-cci-devfreq.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (C) 2022 MediaTek Inc.
4  */
5
6 #include <linux/clk.h>
7 #include <linux/devfreq.h>
8 #include <linux/minmax.h>
9 #include <linux/module.h>
10 #include <linux/of.h>
11 #include <linux/platform_device.h>
12 #include <linux/pm_opp.h>
13 #include <linux/regulator/consumer.h>
14
15 struct mtk_ccifreq_platform_data {
16         int min_volt_shift;
17         int max_volt_shift;
18         int proc_max_volt;
19         int sram_min_volt;
20         int sram_max_volt;
21 };
22
23 struct mtk_ccifreq_drv {
24         struct device *dev;
25         struct devfreq *devfreq;
26         struct regulator *proc_reg;
27         struct regulator *sram_reg;
28         struct clk *cci_clk;
29         struct clk *inter_clk;
30         int inter_voltage;
31         unsigned long pre_freq;
32         /* Avoid race condition for regulators between notify and policy */
33         struct mutex reg_lock;
34         struct notifier_block opp_nb;
35         const struct mtk_ccifreq_platform_data *soc_data;
36         int vtrack_max;
37 };
38
39 static int mtk_ccifreq_set_voltage(struct mtk_ccifreq_drv *drv, int new_voltage)
40 {
41         const struct mtk_ccifreq_platform_data *soc_data = drv->soc_data;
42         struct device *dev = drv->dev;
43         int pre_voltage, pre_vsram, new_vsram, vsram, voltage, ret;
44         int retry_max = drv->vtrack_max;
45
46         if (!drv->sram_reg) {
47                 ret = regulator_set_voltage(drv->proc_reg, new_voltage,
48                                             drv->soc_data->proc_max_volt);
49                 return ret;
50         }
51
52         pre_voltage = regulator_get_voltage(drv->proc_reg);
53         if (pre_voltage < 0) {
54                 dev_err(dev, "invalid vproc value: %d\n", pre_voltage);
55                 return pre_voltage;
56         }
57
58         pre_vsram = regulator_get_voltage(drv->sram_reg);
59         if (pre_vsram < 0) {
60                 dev_err(dev, "invalid vsram value: %d\n", pre_vsram);
61                 return pre_vsram;
62         }
63
64         new_vsram = clamp(new_voltage + soc_data->min_volt_shift,
65                           soc_data->sram_min_volt, soc_data->sram_max_volt);
66
67         do {
68                 if (pre_voltage <= new_voltage) {
69                         vsram = clamp(pre_voltage + soc_data->max_volt_shift,
70                                       soc_data->sram_min_volt, new_vsram);
71                         ret = regulator_set_voltage(drv->sram_reg, vsram,
72                                                     soc_data->sram_max_volt);
73                         if (ret)
74                                 return ret;
75
76                         if (vsram == soc_data->sram_max_volt ||
77                             new_vsram == soc_data->sram_min_volt)
78                                 voltage = new_voltage;
79                         else
80                                 voltage = vsram - soc_data->min_volt_shift;
81
82                         ret = regulator_set_voltage(drv->proc_reg, voltage,
83                                                     soc_data->proc_max_volt);
84                         if (ret) {
85                                 regulator_set_voltage(drv->sram_reg, pre_vsram,
86                                                       soc_data->sram_max_volt);
87                                 return ret;
88                         }
89                 } else if (pre_voltage > new_voltage) {
90                         voltage = max(new_voltage,
91                                       pre_vsram - soc_data->max_volt_shift);
92                         ret = regulator_set_voltage(drv->proc_reg, voltage,
93                                                     soc_data->proc_max_volt);
94                         if (ret)
95                                 return ret;
96
97                         if (voltage == new_voltage)
98                                 vsram = new_vsram;
99                         else
100                                 vsram = max(new_vsram,
101                                             voltage + soc_data->min_volt_shift);
102
103                         ret = regulator_set_voltage(drv->sram_reg, vsram,
104                                                     soc_data->sram_max_volt);
105                         if (ret) {
106                                 regulator_set_voltage(drv->proc_reg, pre_voltage,
107                                                       soc_data->proc_max_volt);
108                                 return ret;
109                         }
110                 }
111
112                 pre_voltage = voltage;
113                 pre_vsram = vsram;
114
115                 if (--retry_max < 0) {
116                         dev_err(dev,
117                                 "over loop count, failed to set voltage\n");
118                         return -EINVAL;
119                 }
120         } while (voltage != new_voltage || vsram != new_vsram);
121
122         return 0;
123 }
124
125 static int mtk_ccifreq_target(struct device *dev, unsigned long *freq,
126                               u32 flags)
127 {
128         struct mtk_ccifreq_drv *drv = dev_get_drvdata(dev);
129         struct clk *cci_pll;
130         struct dev_pm_opp *opp;
131         unsigned long opp_rate;
132         int voltage, pre_voltage, inter_voltage, target_voltage, ret;
133
134         if (!drv)
135                 return -EINVAL;
136
137         if (drv->pre_freq == *freq)
138                 return 0;
139
140         inter_voltage = drv->inter_voltage;
141         cci_pll = clk_get_parent(drv->cci_clk);
142
143         opp_rate = *freq;
144         opp = devfreq_recommended_opp(dev, &opp_rate, 1);
145         if (IS_ERR(opp)) {
146                 dev_err(dev, "failed to find opp for freq: %ld\n", opp_rate);
147                 return PTR_ERR(opp);
148         }
149
150         mutex_lock(&drv->reg_lock);
151
152         voltage = dev_pm_opp_get_voltage(opp);
153         dev_pm_opp_put(opp);
154
155         pre_voltage = regulator_get_voltage(drv->proc_reg);
156         if (pre_voltage < 0) {
157                 dev_err(dev, "invalid vproc value: %d\n", pre_voltage);
158                 ret = pre_voltage;
159                 goto out_unlock;
160         }
161
162         /* scale up: set voltage first then freq. */
163         target_voltage = max(inter_voltage, voltage);
164         if (pre_voltage <= target_voltage) {
165                 ret = mtk_ccifreq_set_voltage(drv, target_voltage);
166                 if (ret) {
167                         dev_err(dev, "failed to scale up voltage\n");
168                         goto out_restore_voltage;
169                 }
170         }
171
172         /* switch the cci clock to intermediate clock source. */
173         ret = clk_set_parent(drv->cci_clk, drv->inter_clk);
174         if (ret) {
175                 dev_err(dev, "failed to re-parent cci clock\n");
176                 goto out_restore_voltage;
177         }
178
179         /* set the original clock to target rate. */
180         ret = clk_set_rate(cci_pll, *freq);
181         if (ret) {
182                 dev_err(dev, "failed to set cci pll rate: %d\n", ret);
183                 clk_set_parent(drv->cci_clk, cci_pll);
184                 goto out_restore_voltage;
185         }
186
187         /* switch the cci clock back to the original clock source. */
188         ret = clk_set_parent(drv->cci_clk, cci_pll);
189         if (ret) {
190                 dev_err(dev, "failed to re-parent cci clock\n");
191                 mtk_ccifreq_set_voltage(drv, inter_voltage);
192                 goto out_unlock;
193         }
194
195         /*
196          * If the new voltage is lower than the intermediate voltage or the
197          * original voltage, scale down to the new voltage.
198          */
199         if (voltage < inter_voltage || voltage < pre_voltage) {
200                 ret = mtk_ccifreq_set_voltage(drv, voltage);
201                 if (ret) {
202                         dev_err(dev, "failed to scale down voltage\n");
203                         goto out_unlock;
204                 }
205         }
206
207         drv->pre_freq = *freq;
208         mutex_unlock(&drv->reg_lock);
209
210         return 0;
211
212 out_restore_voltage:
213         mtk_ccifreq_set_voltage(drv, pre_voltage);
214
215 out_unlock:
216         mutex_unlock(&drv->reg_lock);
217         return ret;
218 }
219
220 static int mtk_ccifreq_opp_notifier(struct notifier_block *nb,
221                                     unsigned long event, void *data)
222 {
223         struct dev_pm_opp *opp = data;
224         struct mtk_ccifreq_drv *drv;
225         unsigned long freq, volt;
226
227         drv = container_of(nb, struct mtk_ccifreq_drv, opp_nb);
228
229         if (event == OPP_EVENT_ADJUST_VOLTAGE) {
230                 freq = dev_pm_opp_get_freq(opp);
231
232                 mutex_lock(&drv->reg_lock);
233                 /* current opp item is changed */
234                 if (freq == drv->pre_freq) {
235                         volt = dev_pm_opp_get_voltage(opp);
236                         mtk_ccifreq_set_voltage(drv, volt);
237                 }
238                 mutex_unlock(&drv->reg_lock);
239         }
240
241         return 0;
242 }
243
244 static struct devfreq_dev_profile mtk_ccifreq_profile = {
245         .target = mtk_ccifreq_target,
246 };
247
248 static int mtk_ccifreq_probe(struct platform_device *pdev)
249 {
250         struct device *dev = &pdev->dev;
251         struct mtk_ccifreq_drv *drv;
252         struct devfreq_passive_data *passive_data;
253         struct dev_pm_opp *opp;
254         unsigned long rate, opp_volt;
255         int ret;
256
257         drv = devm_kzalloc(dev, sizeof(*drv), GFP_KERNEL);
258         if (!drv)
259                 return -ENOMEM;
260
261         drv->dev = dev;
262         drv->soc_data = (const struct mtk_ccifreq_platform_data *)
263                                 of_device_get_match_data(&pdev->dev);
264         mutex_init(&drv->reg_lock);
265         platform_set_drvdata(pdev, drv);
266
267         drv->cci_clk = devm_clk_get(dev, "cci");
268         if (IS_ERR(drv->cci_clk)) {
269                 ret = PTR_ERR(drv->cci_clk);
270                 return dev_err_probe(dev, ret, "failed to get cci clk\n");
271         }
272
273         drv->inter_clk = devm_clk_get(dev, "intermediate");
274         if (IS_ERR(drv->inter_clk)) {
275                 ret = PTR_ERR(drv->inter_clk);
276                 return dev_err_probe(dev, ret,
277                                      "failed to get intermediate clk\n");
278         }
279
280         drv->proc_reg = devm_regulator_get_optional(dev, "proc");
281         if (IS_ERR(drv->proc_reg)) {
282                 ret = PTR_ERR(drv->proc_reg);
283                 return dev_err_probe(dev, ret,
284                                      "failed to get proc regulator\n");
285         }
286
287         ret = regulator_enable(drv->proc_reg);
288         if (ret) {
289                 dev_err(dev, "failed to enable proc regulator\n");
290                 return ret;
291         }
292
293         drv->sram_reg = devm_regulator_get_optional(dev, "sram");
294         if (IS_ERR(drv->sram_reg)) {
295                 ret = PTR_ERR(drv->sram_reg);
296                 if (ret == -EPROBE_DEFER)
297                         goto out_free_resources;
298
299                 drv->sram_reg = NULL;
300         } else {
301                 ret = regulator_enable(drv->sram_reg);
302                 if (ret) {
303                         dev_err(dev, "failed to enable sram regulator\n");
304                         goto out_free_resources;
305                 }
306         }
307
308         /*
309          * We assume min voltage is 0 and tracking target voltage using
310          * min_volt_shift for each iteration.
311          * The retry_max is 3 times of expected iteration count.
312          */
313         drv->vtrack_max = 3 * DIV_ROUND_UP(max(drv->soc_data->sram_max_volt,
314                                                drv->soc_data->proc_max_volt),
315                                            drv->soc_data->min_volt_shift);
316
317         ret = clk_prepare_enable(drv->cci_clk);
318         if (ret)
319                 goto out_free_resources;
320
321         ret = dev_pm_opp_of_add_table(dev);
322         if (ret) {
323                 dev_err(dev, "failed to add opp table: %d\n", ret);
324                 goto out_disable_cci_clk;
325         }
326
327         rate = clk_get_rate(drv->inter_clk);
328         opp = dev_pm_opp_find_freq_ceil(dev, &rate);
329         if (IS_ERR(opp)) {
330                 ret = PTR_ERR(opp);
331                 dev_err(dev, "failed to get intermediate opp: %d\n", ret);
332                 goto out_remove_opp_table;
333         }
334         drv->inter_voltage = dev_pm_opp_get_voltage(opp);
335         dev_pm_opp_put(opp);
336
337         rate = U32_MAX;
338         opp = dev_pm_opp_find_freq_floor(drv->dev, &rate);
339         if (IS_ERR(opp)) {
340                 dev_err(dev, "failed to get opp\n");
341                 ret = PTR_ERR(opp);
342                 goto out_remove_opp_table;
343         }
344
345         opp_volt = dev_pm_opp_get_voltage(opp);
346         dev_pm_opp_put(opp);
347         ret = mtk_ccifreq_set_voltage(drv, opp_volt);
348         if (ret) {
349                 dev_err(dev, "failed to scale to highest voltage %lu in proc_reg\n",
350                         opp_volt);
351                 goto out_remove_opp_table;
352         }
353
354         passive_data = devm_kzalloc(dev, sizeof(*passive_data), GFP_KERNEL);
355         if (!passive_data) {
356                 ret = -ENOMEM;
357                 goto out_remove_opp_table;
358         }
359
360         passive_data->parent_type = CPUFREQ_PARENT_DEV;
361         drv->devfreq = devm_devfreq_add_device(dev, &mtk_ccifreq_profile,
362                                                DEVFREQ_GOV_PASSIVE,
363                                                passive_data);
364         if (IS_ERR(drv->devfreq)) {
365                 ret = -EPROBE_DEFER;
366                 dev_err(dev, "failed to add devfreq device: %ld\n",
367                         PTR_ERR(drv->devfreq));
368                 goto out_remove_opp_table;
369         }
370
371         drv->opp_nb.notifier_call = mtk_ccifreq_opp_notifier;
372         ret = dev_pm_opp_register_notifier(dev, &drv->opp_nb);
373         if (ret) {
374                 dev_err(dev, "failed to register opp notifier: %d\n", ret);
375                 goto out_remove_opp_table;
376         }
377         return 0;
378
379 out_remove_opp_table:
380         dev_pm_opp_of_remove_table(dev);
381
382 out_disable_cci_clk:
383         clk_disable_unprepare(drv->cci_clk);
384
385 out_free_resources:
386         if (regulator_is_enabled(drv->proc_reg))
387                 regulator_disable(drv->proc_reg);
388         if (drv->sram_reg && regulator_is_enabled(drv->sram_reg))
389                 regulator_disable(drv->sram_reg);
390
391         return ret;
392 }
393
394 static int mtk_ccifreq_remove(struct platform_device *pdev)
395 {
396         struct device *dev = &pdev->dev;
397         struct mtk_ccifreq_drv *drv;
398
399         drv = platform_get_drvdata(pdev);
400
401         dev_pm_opp_unregister_notifier(dev, &drv->opp_nb);
402         dev_pm_opp_of_remove_table(dev);
403         clk_disable_unprepare(drv->cci_clk);
404         regulator_disable(drv->proc_reg);
405         if (drv->sram_reg)
406                 regulator_disable(drv->sram_reg);
407
408         return 0;
409 }
410
411 static const struct mtk_ccifreq_platform_data mt8183_platform_data = {
412         .min_volt_shift = 100000,
413         .max_volt_shift = 200000,
414         .proc_max_volt = 1150000,
415 };
416
417 static const struct mtk_ccifreq_platform_data mt8186_platform_data = {
418         .min_volt_shift = 100000,
419         .max_volt_shift = 250000,
420         .proc_max_volt = 1118750,
421         .sram_min_volt = 850000,
422         .sram_max_volt = 1118750,
423 };
424
425 static const struct of_device_id mtk_ccifreq_machines[] = {
426         { .compatible = "mediatek,mt8183-cci", .data = &mt8183_platform_data },
427         { .compatible = "mediatek,mt8186-cci", .data = &mt8186_platform_data },
428         { },
429 };
430 MODULE_DEVICE_TABLE(of, mtk_ccifreq_machines);
431
432 static struct platform_driver mtk_ccifreq_platdrv = {
433         .probe  = mtk_ccifreq_probe,
434         .remove = mtk_ccifreq_remove,
435         .driver = {
436                 .name = "mtk-ccifreq",
437                 .of_match_table = mtk_ccifreq_machines,
438         },
439 };
440 module_platform_driver(mtk_ccifreq_platdrv);
441
442 MODULE_DESCRIPTION("MediaTek CCI devfreq driver");
443 MODULE_AUTHOR("Jia-Wei Chang <jia-wei.chang@mediatek.com>");
444 MODULE_LICENSE("GPL v2");