[COMMON] soc: samsung: exynos-dm: Remove unsued dvfs_type
[GitHub/moto-9609/android_kernel_motorola_exynos9610.git] / drivers / soc / samsung / exynos-dm.c
CommitLineData
eea99674
EJ
1/* linux/drivers/soc/samsung/exynos-dm.c
2 *
3 * Copyright (C) 2016 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * Samsung Exynos SoC series DVFS Manager
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/kernel.h>
14#include <linux/module.h>
15#include <linux/platform_device.h>
16#include <linux/errno.h>
17#include <linux/of.h>
18#include <linux/slab.h>
9af57ec7 19#include <linux/exynos-ss.h>
4c8286c2
JY
20#include "acpm/acpm.h"
21#include "acpm/acpm_ipc.h"
eea99674
EJ
22
23#include <soc/samsung/exynos-dm.h>
24
25static struct list_head *get_min_constraint_list(struct exynos_dm_data *dm_data);
26static struct list_head *get_max_constraint_list(struct exynos_dm_data *dm_data);
27static void get_governor_min_freq(struct exynos_dm_data *dm_data, u32 *gov_min_freq);
28static void get_min_max_freq(struct exynos_dm_data *dm_data, u32 *min_freq, u32 *max_freq);
29static void update_min_max_freq(struct exynos_dm_data *dm_data, u32 min_freq, u32 max_freq);
30static void get_policy_min_max_freq(struct exynos_dm_data *dm_data, u32 *min_freq, u32 *max_freq);
31static void update_policy_min_max_freq(struct exynos_dm_data *dm_data, u32 min_freq, u32 max_freq);
32static void get_current_freq(struct exynos_dm_data *dm_data, u32 *cur_freq);
33static void get_target_freq(struct exynos_dm_data *dm_data, u32 *target_freq);
34
8bf488d2 35#define DM_EMPTY 0xFF
eea99674 36static struct exynos_dm_device *exynos_dm;
8bf488d2
TK
37static enum exynos_dm_type min_order[DM_TYPE_END + 1] = {DM_EMPTY, };
38static enum exynos_dm_type max_order[DM_TYPE_END + 1] = {DM_EMPTY, };
eea99674
EJ
39
40/*
41 * SYSFS for Debugging
42 */
43static ssize_t show_available(struct device *dev,
44 struct device_attribute *attr, char *buf)
45{
46 struct platform_device *pdev = container_of(dev, struct platform_device, dev);
47 struct exynos_dm_device *dm = platform_get_drvdata(pdev);
48 ssize_t count = 0;
49 int i;
50
51 for (i = 0; i < DM_TYPE_END; i++) {
52 if (!dm->dm_data[i].available)
53 continue;
54
55 count += snprintf(buf + count, PAGE_SIZE,
291af6ce 56 "dm_type: %d(%s), available = %s\n",
eea99674 57 dm->dm_data[i].dm_type, dm->dm_data[i].dm_type_name,
eea99674
EJ
58 dm->dm_data[i].available ? "true" : "false");
59 }
60
61 return count;
62}
63
9e58ad01
HG
64static ssize_t show_constraint_table(struct device *dev, struct device_attribute *attr, char *buf)
65{
66 struct list_head *constraint_list;
67 struct exynos_dm_constraint *constraint;
68 struct exynos_dm_data *dm_data;
69 struct exynos_dm_attrs *dm_attrs;
70 ssize_t count = 0;
71 int i;
72
73 dm_attrs = container_of(attr, struct exynos_dm_attrs, attr);
74 dm_data = container_of(dm_attrs, struct exynos_dm_data, constraint_table_attr);
75
76 if (!dm_data->available) {
77 count += snprintf(buf + count, PAGE_SIZE,
78 "This dm_type is not available\n");
79 return count;
80 }
81
82 count += snprintf(buf + count, PAGE_SIZE, "dm_type: %s\n",
83 dm_data->dm_type_name);
84
85 constraint_list = get_min_constraint_list(dm_data);
86 if (list_empty(constraint_list)) {
87 count += snprintf(buf + count, PAGE_SIZE,
88 "This dm_type have not min constraint tables\n\n");
89 goto next;
90 }
91
92 list_for_each_entry(constraint, constraint_list, node) {
93 count += snprintf(buf + count, PAGE_SIZE,
94 "-------------------------------------------------\n");
95 count += snprintf(buf + count, PAGE_SIZE,
96 "constraint_dm_type = %s\n", constraint->dm_type_name);
97 count += snprintf(buf + count, PAGE_SIZE, "constraint_type: %s\n",
98 constraint->constraint_type ? "MAX" : "MIN");
99 count += snprintf(buf + count, PAGE_SIZE, "guidance: %s\n",
100 constraint->guidance ? "true" : "false");
101 count += snprintf(buf + count, PAGE_SIZE,
102 "min_freq = %u, max_freq =%u\n",
103 constraint->min_freq, constraint->max_freq);
104 count += snprintf(buf + count, PAGE_SIZE,
105 "master_freq\t constraint_freq\n");
106 for (i = 0; i < constraint->table_length; i++)
107 count += snprintf(buf + count, PAGE_SIZE, "%10u\t %10u\n",
108 constraint->freq_table[i].master_freq,
109 constraint->freq_table[i].constraint_freq);
110 count += snprintf(buf + count, PAGE_SIZE,
111 "-------------------------------------------------\n");
112 }
113
114next:
115 constraint_list = get_max_constraint_list(dm_data);
116 if (list_empty(constraint_list)) {
117 count += snprintf(buf + count, PAGE_SIZE,
118 "This dm_type have not max constraint tables\n\n");
119 return count;
120 }
121
122 list_for_each_entry(constraint, constraint_list, node) {
123 count += snprintf(buf + count, PAGE_SIZE,
124 "-------------------------------------------------\n");
125 count += snprintf(buf + count, PAGE_SIZE,
126 "constraint_dm_type = %s\n", constraint->dm_type_name);
127 count += snprintf(buf + count, PAGE_SIZE, "constraint_type: %s\n",
128 constraint->constraint_type ? "MAX" : "MIN");
129 count += snprintf(buf + count, PAGE_SIZE, "guidance: %s\n",
130 constraint->guidance ? "true" : "false");
131 count += snprintf(buf + count, PAGE_SIZE,
132 "min_freq = %u, max_freq =%u\n",
133 constraint->min_freq, constraint->max_freq);
134 count += snprintf(buf + count, PAGE_SIZE,
135 "master_freq\t constraint_freq\n");
136 for (i = 0; i < constraint->table_length; i++)
137 count += snprintf(buf + count, PAGE_SIZE, "%10u\t %10u\n",
138 constraint->freq_table[i].master_freq,
139 constraint->freq_table[i].constraint_freq);
140 count += snprintf(buf + count, PAGE_SIZE,
141 "-------------------------------------------------\n");
142 }
eea99674 143
9e58ad01 144 return count;
eea99674
EJ
145}
146
9e58ad01
HG
147static ssize_t show_dm_policy(struct device *dev, struct device_attribute *attr, char *buf)
148{
149 struct list_head *constraint_list;
150 struct exynos_dm_constraint *constraint;
151 struct exynos_dm_data *dm_data;
152 struct exynos_dm_attrs *dm_attrs;
153 ssize_t count = 0;
154 u32 gov_min_freq, min_freq, max_freq;
155 u32 policy_min_freq, policy_max_freq, cur_freq, target_freq;
156 u32 find;
157 int i;
158
159 dm_attrs = container_of(attr, struct exynos_dm_attrs, attr);
160 dm_data = container_of(dm_attrs, struct exynos_dm_data, dm_policy_attr);
161
162 if (!dm_data->available) {
163 count += snprintf(buf + count, PAGE_SIZE,
164 "This dm_type is not available\n");
165 return count;
166 }
167
168 count += snprintf(buf + count, PAGE_SIZE, "dm_type: %s\n",
169 dm_data->dm_type_name);
170
171 get_governor_min_freq(dm_data, &gov_min_freq);
172 get_min_max_freq(dm_data, &min_freq, &max_freq);
173 get_policy_min_max_freq(dm_data, &policy_min_freq, &policy_max_freq);
174 get_current_freq(dm_data, &cur_freq);
175 get_target_freq(dm_data, &target_freq);
176
177 count += snprintf(buf + count, PAGE_SIZE,
178 "governor_min_freq = %u\n", gov_min_freq);
179 count += snprintf(buf + count, PAGE_SIZE,
180 "policy_min_freq = %u, policy_max_freq = %u\n",
181 policy_min_freq, policy_max_freq);
182 count += snprintf(buf + count, PAGE_SIZE,
183 "min_freq = %u, max_freq = %u\n", min_freq, max_freq);
184 count += snprintf(buf + count, PAGE_SIZE, "current_freq = %u\n", cur_freq);
185 count += snprintf(buf + count, PAGE_SIZE, "target_freq = %u\n", target_freq);
186 count += snprintf(buf + count, PAGE_SIZE,
187 "-------------------------------------------------\n");
188 count += snprintf(buf + count, PAGE_SIZE, "min constraint by\n");
189 find = 0;
190
191 for (i = 0; i < DM_TYPE_END; i++) {
192 if (!exynos_dm->dm_data[i].available)
193 continue;
194
195 constraint_list = get_min_constraint_list(&exynos_dm->dm_data[i]);
196 if (list_empty(constraint_list))
197 continue;
198 list_for_each_entry(constraint, constraint_list, node) {
199 if (constraint->constraint_dm_type == dm_data->dm_type) {
200 count += snprintf(buf + count, PAGE_SIZE,
201 "%s : %u ---> %s : %u",
202 exynos_dm->dm_data[i].dm_type_name,
203 constraint->master_freq,
204 constraint->dm_type_name,
205 constraint->min_freq);
206 if (constraint->guidance)
207 count += snprintf(buf+count, PAGE_SIZE,
208 " [guidance]\n");
209 else
210 count += snprintf(buf+count, PAGE_SIZE, "\n");
211 find = max(find, constraint->min_freq);
212 }
213 }
214 }
215 if (find == 0)
216 count += snprintf(buf + count, PAGE_SIZE,
217 "There is no min constraint\n\n");
218 else
219 count += snprintf(buf + count, PAGE_SIZE,
220 "min constraint freq = %u\n", find);
221 count += snprintf(buf + count, PAGE_SIZE,
222 "-------------------------------------------------\n");
223 count += snprintf(buf + count, PAGE_SIZE, "max constraint by\n");
224 find = INT_MAX;
225
226 for (i = 0; i < DM_TYPE_END; i++) {
227 if (!exynos_dm->dm_data[i].available)
228 continue;
229
230 constraint_list = get_max_constraint_list(&exynos_dm->dm_data[i]);
231 if (list_empty(constraint_list))
232 continue;
233 list_for_each_entry(constraint, constraint_list, node) {
234 if (constraint->constraint_dm_type == dm_data->dm_type) {
235 count += snprintf(buf + count, PAGE_SIZE,
236 "%s : %u ---> %s : %u",
237 exynos_dm->dm_data[i].dm_type_name,
238 constraint->master_freq,
239 constraint->dm_type_name,
240 constraint->max_freq);
241 if (constraint->guidance)
242 count += snprintf(buf+count, PAGE_SIZE,
243 " [guidance]\n");
244 else
245 count += snprintf(buf+count, PAGE_SIZE, "\n");
246 find = min(find, constraint->max_freq);
247 }
248 }
249 }
250 if (find == INT_MAX)
251 count += snprintf(buf + count, PAGE_SIZE,
252 "There is no max constraint\n\n");
253 else
254 count += snprintf(buf + count, PAGE_SIZE,
255 "max constraint freq = %u\n", find);
256 count += snprintf(buf + count, PAGE_SIZE,
257 "-------------------------------------------------\n");
258 return count;
259}
eea99674
EJ
260
261static DEVICE_ATTR(available, 0440, show_available, NULL);
eea99674
EJ
262
263static struct attribute *exynos_dm_sysfs_entries[] = {
264 &dev_attr_available.attr,
eea99674
EJ
265 NULL,
266};
267
268static struct attribute_group exynos_dm_attr_group = {
269 .name = "exynos_dm",
270 .attrs = exynos_dm_sysfs_entries,
271};
272/*
273 * SYSFS for Debugging end
274 */
275
276static void print_available_dm_data(struct exynos_dm_device *dm)
277{
278 int i;
279
280 for (i = 0; i < DM_TYPE_END; i++) {
281 if (!dm->dm_data[i].available)
282 continue;
283
291af6ce 284 dev_info(dm->dev, "dm_type: %d(%s), available = %s\n",
eea99674 285 dm->dm_data[i].dm_type, dm->dm_data[i].dm_type_name,
eea99674
EJ
286 dm->dm_data[i].available ? "true" : "false");
287 }
288}
289
290static int exynos_dm_index_validate(enum exynos_dm_type index)
291{
291af6ce 292 if ((index < 0) || (index >= DM_TYPE_END)) {
eea99674
EJ
293 dev_err(exynos_dm->dev, "invalid dm_index (%d)\n", index);
294 return -EINVAL;
295 }
296
297 return 0;
298}
299
eea99674
EJ
300#ifdef CONFIG_OF
301static int exynos_dm_parse_dt(struct device_node *np, struct exynos_dm_device *dm)
302{
303 struct device_node *child_np;
9e58ad01 304 const char *name;
eea99674
EJ
305 int ret = 0;
306
307 if (!np)
308 return -ENODEV;
309
310 for_each_child_of_node(np, child_np) {
311 int index;
312 const char *available;
bfd629b3 313#ifdef CONFIG_EXYNOS_ACPM
b63c8889 314 const char *policy_use;
bfd629b3 315#endif
eea99674
EJ
316 if (of_property_read_u32(child_np, "dm-index", &index))
317 return -ENODEV;
318
319 ret = exynos_dm_index_validate(index);
320 if (ret)
321 return ret;
322
323 if (of_property_read_string(child_np, "available", &available))
324 return -ENODEV;
325
326 if (!strcmp(available, "true")) {
327 dm->dm_data[index].dm_type = index;
328 dm->dm_data[index].available = true;
9e58ad01
HG
329
330 if (!of_property_read_string(child_np, "dm_type_name", &name))
331 strncpy(dm->dm_data[index].dm_type_name, name, EXYNOS_DM_TYPE_NAME_LEN);
332
eea99674
EJ
333 INIT_LIST_HEAD(&dm->dm_data[index].min_clist);
334 INIT_LIST_HEAD(&dm->dm_data[index].max_clist);
335 } else {
336 dm->dm_data[index].available = false;
337 }
bfd629b3 338#ifdef CONFIG_EXYNOS_ACPM
b63c8889
JY
339 if (of_property_read_string(child_np, "policy_use", &policy_use)) {
340 dev_info(dm->dev, "This doesn't need to send policy to ACPM\n");
341 } else {
342 if (!strcmp(policy_use, "true"))
343 dm->dm_data[index].policy_use = true;
344 }
2c1c92a3
JY
345
346 if (of_property_read_u32(child_np, "cal_id", &dm->dm_data[index].cal_id))
347 return -ENODEV;
bfd629b3 348#endif
eea99674
EJ
349 }
350
351 return ret;
352}
353#else
354static int exynos_dm_parse_dt(struct device_node *np, struct exynos_dm_device *dm)
355{
356 return -ENODEV;
357}
358#endif
359
360static struct list_head *get_min_constraint_list(struct exynos_dm_data *dm_data)
361{
362 return &dm_data->min_clist;
363}
364
365static struct list_head *get_max_constraint_list(struct exynos_dm_data *dm_data)
366{
367 return &dm_data->max_clist;
368}
369
370/*
371 * This function should be called from each DVFS drivers
372 * before DVFS driver registration to DVFS framework.
373 * Initialize sequence Step.1
374 */
26129728 375int exynos_dm_data_init(enum exynos_dm_type dm_type, void *data,
eea99674
EJ
376 u32 min_freq, u32 max_freq, u32 cur_freq)
377{
378 int ret = 0;
379
380 ret = exynos_dm_index_validate(dm_type);
381 if (ret)
382 return ret;
383
384 mutex_lock(&exynos_dm->lock);
385
386 if (!exynos_dm->dm_data[dm_type].available) {
387 dev_err(exynos_dm->dev,
388 "This dm type(%d) is not available\n", dm_type);
389 ret = -ENODEV;
390 goto out;
391 }
392
393 exynos_dm->dm_data[dm_type].gov_min_freq = min_freq;
394 exynos_dm->dm_data[dm_type].policy_min_freq = min_freq;
395 exynos_dm->dm_data[dm_type].policy_max_freq = max_freq;
396 exynos_dm->dm_data[dm_type].cur_freq = cur_freq;
397
398 if (!exynos_dm->dm_data[dm_type].min_freq)
399 exynos_dm->dm_data[dm_type].min_freq = min_freq;
400
401 if (!exynos_dm->dm_data[dm_type].max_freq)
402 exynos_dm->dm_data[dm_type].max_freq = max_freq;
403
26129728
HG
404 exynos_dm->dm_data[dm_type].devdata = data;
405
eea99674
EJ
406out:
407 mutex_unlock(&exynos_dm->lock);
408
409 return ret;
410}
411
412/*
413 * Initialize sequence Step.2
414 */
415int register_exynos_dm_constraint_table(enum exynos_dm_type dm_type,
416 struct exynos_dm_constraint *constraint)
417{
418 struct exynos_dm_constraint *sub_constraint;
419 int i, ret = 0;
420
421 ret = exynos_dm_index_validate(dm_type);
422 if (ret)
423 return ret;
424
425 if (!constraint) {
426 dev_err(exynos_dm->dev, "constraint is not valid\n");
427 return -EINVAL;
428 }
429
430 /* check member invalid */
431 if ((constraint->constraint_type < CONSTRAINT_MIN) ||
432 (constraint->constraint_type > CONSTRAINT_MAX)) {
433 dev_err(exynos_dm->dev, "constraint_type is invalid\n");
434 return -EINVAL;
435 }
436
437 ret = exynos_dm_index_validate(constraint->constraint_dm_type);
438 if (ret)
439 return ret;
440
441 if (!constraint->freq_table) {
442 dev_err(exynos_dm->dev, "No frequency table for constraint\n");
443 return -EINVAL;
444 }
445
446 mutex_lock(&exynos_dm->lock);
447
448 strncpy(constraint->dm_type_name,
9e58ad01 449 exynos_dm->dm_data[constraint->constraint_dm_type].dm_type_name,
eea99674
EJ
450 EXYNOS_DM_TYPE_NAME_LEN);
451 constraint->min_freq = 0;
452 constraint->max_freq = UINT_MAX;
453
454 if (constraint->constraint_type == CONSTRAINT_MIN)
455 list_add(&constraint->node, &exynos_dm->dm_data[dm_type].min_clist);
456 else if (constraint->constraint_type == CONSTRAINT_MAX)
457 list_add(&constraint->node, &exynos_dm->dm_data[dm_type].max_clist);
458
459 /* check guidance and sub constraint table generations */
460 if (constraint->guidance && (constraint->constraint_type == CONSTRAINT_MIN)) {
461 sub_constraint = kzalloc(sizeof(struct exynos_dm_constraint), GFP_KERNEL);
462 if (sub_constraint == NULL) {
463 dev_err(exynos_dm->dev, "failed to allocate sub constraint\n");
464 ret = -ENOMEM;
465 goto err_sub_const;
466 }
467
468 sub_constraint->guidance = true;
469 sub_constraint->table_length = constraint->table_length;
470 sub_constraint->constraint_type = CONSTRAINT_MAX;
471 sub_constraint->constraint_dm_type = dm_type;
472 strncpy(sub_constraint->dm_type_name,
9e58ad01 473 exynos_dm->dm_data[sub_constraint->constraint_dm_type].dm_type_name,
eea99674
EJ
474 EXYNOS_DM_TYPE_NAME_LEN);
475 sub_constraint->min_freq = 0;
476 sub_constraint->max_freq = UINT_MAX;
477
478 sub_constraint->freq_table =
479 kzalloc(sizeof(struct exynos_dm_freq) * sub_constraint->table_length, GFP_KERNEL);
480 if (sub_constraint->freq_table == NULL) {
481 dev_err(exynos_dm->dev, "failed to allocate freq table for sub const\n");
482 ret = -ENOMEM;
483 goto err_freq_table;
484 }
485
486 /* generation table */
487 for (i = 0; i < constraint->table_length; i++) {
488 sub_constraint->freq_table[i].master_freq =
489 constraint->freq_table[i].constraint_freq;
490 sub_constraint->freq_table[i].constraint_freq =
491 constraint->freq_table[i].master_freq;
492 }
493
494 list_add(&sub_constraint->node,
495 &exynos_dm->dm_data[constraint->constraint_dm_type].max_clist);
496
497 /* linked sub constraint */
498 constraint->sub_constraint = sub_constraint;
499 }
500
501 mutex_unlock(&exynos_dm->lock);
502
503 return 0;
504
505err_freq_table:
506 kfree(sub_constraint);
507err_sub_const:
508 list_del(&constraint->node);
509
510 mutex_unlock(&exynos_dm->lock);
511
512 return ret;
513}
514
515int unregister_exynos_dm_constraint_table(enum exynos_dm_type dm_type,
516 struct exynos_dm_constraint *constraint)
517{
518 struct exynos_dm_constraint *sub_constraint;
519 int ret = 0;
520
521 ret = exynos_dm_index_validate(dm_type);
522 if (ret)
523 return ret;
524
525 if (!constraint) {
526 dev_err(exynos_dm->dev, "constraint is not valid\n");
527 return -EINVAL;
528 }
529
530 mutex_lock(&exynos_dm->lock);
531
532 if (constraint->sub_constraint) {
533 sub_constraint = constraint->sub_constraint;
534 list_del(&sub_constraint->node);
535 kfree(sub_constraint->freq_table);
536 kfree(sub_constraint);
537 }
538
539 list_del(&constraint->node);
540
541 mutex_unlock(&exynos_dm->lock);
542
543 return 0;
544}
545
546/*
547 * This function should be called from each DVFS driver registration function
548 * before return to corresponding DVFS drvier.
549 * Initialize sequence Step.3
550 */
551int register_exynos_dm_freq_scaler(enum exynos_dm_type dm_type,
26129728 552 int (*scaler_func)(enum exynos_dm_type dm_type, void *devdata, u32 target_freq, unsigned int relation))
eea99674
EJ
553{
554 int ret = 0;
555
556 ret = exynos_dm_index_validate(dm_type);
557 if (ret)
558 return ret;
559
560 if (!scaler_func) {
561 dev_err(exynos_dm->dev, "function is not valid\n");
562 return -EINVAL;
563 }
564
565 mutex_lock(&exynos_dm->lock);
566
567 if (!exynos_dm->dm_data[dm_type].available) {
568 dev_err(exynos_dm->dev,
569 "This dm type(%d) is not available\n", dm_type);
570 ret = -ENODEV;
571 goto out;
572 }
573
574 if (!exynos_dm->dm_data[dm_type].freq_scaler)
575 exynos_dm->dm_data[dm_type].freq_scaler = scaler_func;
576
577out:
578 mutex_unlock(&exynos_dm->lock);
579
580 return 0;
581}
582
583int unregister_exynos_dm_freq_scaler(enum exynos_dm_type dm_type)
584{
585 int ret = 0;
586
587 ret = exynos_dm_index_validate(dm_type);
588 if (ret)
589 return ret;
590
591 mutex_lock(&exynos_dm->lock);
592
593 if (!exynos_dm->dm_data[dm_type].available) {
594 dev_err(exynos_dm->dev,
595 "This dm type(%d) is not available\n", dm_type);
596 ret = -ENODEV;
597 goto out;
598 }
599
600 if (exynos_dm->dm_data[dm_type].freq_scaler)
601 exynos_dm->dm_data[dm_type].freq_scaler = NULL;
602
603out:
604 mutex_unlock(&exynos_dm->lock);
605
606 return 0;
607}
608
609/*
610 * Policy Updater
611 *
612 * @dm_type: DVFS domain type for updating policy
613 * @min_freq: Minimum frequency decided by policy
614 * @max_freq: Maximum frequency decided by policy
615 *
616 * In this function, policy_min_freq and policy_max_freq will be changed.
617 * After that, DVFS Manager will decide min/max freq. of current domain
618 * and check dependent domains whether update is necessary.
619 */
620static int dm_data_updater(enum exynos_dm_type dm_type);
621static int constraint_checker_min(struct list_head *head, u32 freq);
622static int constraint_checker_max(struct list_head *head, u32 freq);
623static int constraint_data_updater(enum exynos_dm_type dm_type, int cnt);
8bf488d2 624static int max_constraint_data_updater(enum exynos_dm_type dm_type, int cnt);
eea99674
EJ
625static int scaling_callback(enum dvfs_direction dir, unsigned int relation);
626
8bf488d2
TK
627static bool max_flag = false;
628
4c8286c2
JY
629#define POLICY_REQ 4
630
eea99674
EJ
631int policy_update_call_to_DM(enum exynos_dm_type dm_type, u32 min_freq, u32 max_freq)
632{
633 struct exynos_dm_data *dm;
9af57ec7 634 struct timeval pre, before, after;
bfd629b3 635#ifdef CONFIG_EXYNOS_ACPM
4c8286c2
JY
636 struct ipc_config config;
637 unsigned int cmd[4];
638 int size, ch_num, ret;
bfd629b3 639#endif
9af57ec7 640 s32 time = 0, pre_time = 0;
eea99674 641
5e3661d7
EJ
642 exynos_ss_dm((int)dm_type, min_freq, max_freq, pre_time, time);
643
9af57ec7 644 do_gettimeofday(&pre);
eea99674 645 mutex_lock(&exynos_dm->lock);
9af57ec7 646 do_gettimeofday(&before);
eea99674 647
3b5cf835
HG
648 min_freq = min(min_freq, max_freq);
649
eea99674 650 dm = &exynos_dm->dm_data[dm_type];
8bf488d2 651 if ((dm->policy_min_freq == min_freq) && (dm->policy_max_freq == max_freq))
4c8286c2
JY
652 goto out;
653
eea99674
EJ
654 update_policy_min_max_freq(dm, min_freq, max_freq);
655
656 /* Check dependent domains */
eea99674 657
4c8286c2 658 /*Send policy to FVP*/
bfd629b3 659#ifdef CONFIG_EXYNOS_ACPM
b63c8889 660 if (dm->policy_use) {
4c8286c2
JY
661 ret = acpm_ipc_request_channel(exynos_dm->dev->of_node, NULL, &ch_num, &size);
662 if (ret) {
663 dev_err(exynos_dm->dev,
664 "acpm request channel is failed, id:%u, size:%u\n", ch_num, size);
fe26bb84 665 goto out;
4c8286c2
JY
666 }
667 config.cmd = cmd;
668 config.response = true;
669 config.indirection = false;
2c1c92a3 670 config.cmd[0] = dm->cal_id;
4c8286c2
JY
671 config.cmd[1] = max_freq;
672 config.cmd[2] = POLICY_REQ;
4c8286c2
JY
673
674 ret = acpm_ipc_send_data(ch_num, &config);
675 if (ret) {
676 dev_err(exynos_dm->dev, "Failed to send policy data to FVP");
fe26bb84 677 goto out;
4c8286c2
JY
678 }
679 }
bfd629b3 680#endif
4c8286c2
JY
681
682out:
9af57ec7 683 do_gettimeofday(&after);
eea99674
EJ
684 mutex_unlock(&exynos_dm->lock);
685
9af57ec7
EJ
686 pre_time = (before.tv_sec - pre.tv_sec) * USEC_PER_SEC +
687 (before.tv_usec - pre.tv_usec);
688 time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
689 (after.tv_usec - before.tv_usec);
690
691 exynos_ss_dm((int)dm_type, min_freq, max_freq, pre_time, time);
692
eea99674
EJ
693 return 0;
694}
695
696static int constraint_checker_min(struct list_head *head, u32 freq)
697{
698 struct exynos_dm_data *dm;
699 struct exynos_dm_constraint *constraint;
700 int i;
701
702 if (!list_empty(head)) {
703 list_for_each_entry(constraint, head, node) {
704 for (i = constraint->table_length - 1; i >= 0; i--) {
705 if (freq <= constraint->freq_table[i].master_freq) {
706 constraint->min_freq = constraint->freq_table[i].constraint_freq;
d677f547 707 constraint->master_freq = freq;
eea99674
EJ
708 break;
709 }
710 }
711 dm_data_updater(constraint->constraint_dm_type);
712 dm = &exynos_dm->dm_data[constraint->constraint_dm_type];
713 constraint_checker_min(get_min_constraint_list(dm), dm->min_freq);
714 }
715 }
716
717 return 0;
718}
719
720static int constraint_checker_max(struct list_head *head, u32 freq)
721{
722 struct exynos_dm_data *dm;
723 struct exynos_dm_constraint *constraint;
724 int i;
725
726 if (!list_empty(head)) {
727 list_for_each_entry(constraint, head, node) {
728 for (i = 0; i < constraint->table_length; i++) {
729 if (freq >= constraint->freq_table[i].master_freq) {
730 constraint->max_freq = constraint->freq_table[i].constraint_freq;
731 break;
732 }
733 }
734 dm_data_updater(constraint->constraint_dm_type);
735 dm = &exynos_dm->dm_data[constraint->constraint_dm_type];
736 constraint_checker_max(get_max_constraint_list(dm), dm->max_freq);
737 }
738 }
739
740 return 0;
741}
742
743/*
744 * DM CALL
745 */
746int DM_CALL(enum exynos_dm_type dm_type, unsigned long *target_freq)
747{
748 struct exynos_dm_data *dm;
749 int i;
750 int ret;
751 unsigned int relation = EXYNOS_DM_RELATION_L;
5e3661d7 752 u32 old_min_freq;
9af57ec7
EJ
753 struct timeval pre, before, after;
754 s32 time = 0, pre_time = 0;
eea99674 755
5e3661d7
EJ
756 exynos_ss_dm((int)dm_type, *target_freq, 1, pre_time, time);
757
9af57ec7 758 do_gettimeofday(&pre);
eea99674 759 mutex_lock(&exynos_dm->lock);
9af57ec7 760 do_gettimeofday(&before);
eea99674
EJ
761
762 dm = &exynos_dm->dm_data[dm_type];
5e3661d7 763 old_min_freq = dm->min_freq;
c67684b9 764 dm->gov_min_freq = (u32)(*target_freq);
eea99674
EJ
765
766 for (i = 0; i < DM_TYPE_END; i++)
767 (&exynos_dm->dm_data[i])->constraint_checked = 0;
768
5e3661d7
EJ
769 if (dm->policy_max_freq < dm->cur_freq)
770 max_flag = true;
771 else
772 max_flag = false;
773
eea99674
EJ
774 ret = dm_data_updater(dm_type);
775 if (ret) {
776 pr_err("Failed to update DM DATA!\n");
fe26bb84 777 mutex_unlock(&exynos_dm->lock);
eea99674
EJ
778 return -EAGAIN;
779 }
780
c67684b9 781 dm->target_freq = (u32)(*target_freq);
aa425e39
TK
782
783 if (dm->target_freq < dm->min_freq)
eea99674 784 dm->target_freq = dm->min_freq;
aa425e39 785 if (dm->target_freq >= dm->max_freq) {
eea99674
EJ
786 dm->target_freq = dm->max_freq;
787 relation = EXYNOS_DM_RELATION_H;
788 }
789
790 *target_freq = dm->target_freq;
791
792 /* Constratin checker should be called to decide target frequency */
793 constraint_data_updater(dm_type, 1);
8bf488d2 794 max_constraint_data_updater(dm_type, 1);
eea99674
EJ
795
796 if (dm->target_freq > dm->cur_freq)
797 scaling_callback(UP, relation);
798 else if (dm->target_freq < dm->cur_freq)
799 scaling_callback(DOWN, relation);
5e3661d7
EJ
800 else if (dm->min_freq > old_min_freq)
801 scaling_callback(UP, relation);
802 else if (dm->min_freq < old_min_freq)
803 scaling_callback(DOWN, relation);
804
805 /* min/max order clear */
806 for (i = 0; i <= DM_TYPE_END; i++) {
807 min_order[i] = DM_EMPTY;
808 max_order[i] = DM_EMPTY;
809 }
eea99674 810
9af57ec7 811 do_gettimeofday(&after);
eea99674
EJ
812 mutex_unlock(&exynos_dm->lock);
813
9af57ec7
EJ
814 pre_time = (before.tv_sec - pre.tv_sec) * USEC_PER_SEC +
815 (before.tv_usec - pre.tv_usec);
816 time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
817 (after.tv_usec - before.tv_usec);
818
5e3661d7 819 exynos_ss_dm((int)dm_type, *target_freq, 3, pre_time, time);
9af57ec7 820
eea99674
EJ
821 return 0;
822}
823
824static int dm_data_updater(enum exynos_dm_type dm_type)
825{
826 struct exynos_dm_data *dm;
827 struct exynos_dm_constraint *constraint;
828 struct list_head *constraint_list;
829 int i;
830 /* Initial min/max frequency is set to policy min/max frequency */
831 u32 min_freq;
832 u32 max_freq;
833
834 dm = &exynos_dm->dm_data[dm_type];
835 min_freq = dm->policy_min_freq;
836 max_freq = dm->policy_max_freq;
837
838 /* Check min/max constraint conditions */
839 for (i = 0; i < DM_TYPE_END; i++) {
840 if (!exynos_dm->dm_data[i].available)
841 continue;
842
843 constraint_list = get_min_constraint_list(&exynos_dm->dm_data[i]);
844 if (list_empty(constraint_list))
845 continue;
846 list_for_each_entry(constraint, constraint_list, node) {
847 if (constraint->constraint_dm_type == dm_type)
848 min_freq = max(min_freq, constraint->min_freq);
849 }
850 }
851 for (i = 0; i < DM_TYPE_END; i++) {
852 if (!exynos_dm->dm_data[i].available)
853 continue;
854
855 constraint_list = get_max_constraint_list(&exynos_dm->dm_data[i]);
856 if (list_empty(constraint_list))
857 continue;
858 list_for_each_entry(constraint, constraint_list, node) {
859 if (constraint->constraint_dm_type == dm_type)
860 max_freq = min(max_freq, constraint->max_freq);
861 }
862 }
863
864 min_freq = max(min_freq, dm->gov_min_freq); //MIN freq should be checked with gov_min_freq
865 update_min_max_freq(dm, min_freq, max_freq);
866
867 return 0;
868}
869
870static int constraint_data_updater(enum exynos_dm_type dm_type, int cnt)
871{
872 struct exynos_dm_data *dm;
873 struct exynos_dm_constraint *constraint;
874 struct list_head *constraint_list;
875
876 dm = &exynos_dm->dm_data[dm_type];
877
878 /* Check dependent domains */
8bf488d2
TK
879 constraint_checker_min(get_min_constraint_list(dm), dm->min_freq);
880
881 if (!dm->constraint_checked)
882 dm->constraint_checked += cnt;
eea99674 883
8bf488d2 884 min_order[dm->constraint_checked] = dm_type;
eea99674
EJ
885
886 constraint_list = get_min_constraint_list(dm);
887 if (list_empty(constraint_list))
888 return 0;
889
8bf488d2
TK
890 min_order[0] = 0;
891
eea99674
EJ
892 list_for_each_entry(constraint, constraint_list, node) {
893 dm = &exynos_dm->dm_data[constraint->constraint_dm_type];
894 dm_data_updater(dm->dm_type);
895
896 dm->target_freq = dm->min_freq;
897 if (dm->target_freq >= dm->max_freq)
898 dm->target_freq = dm->max_freq;
899
900 constraint_data_updater(dm->dm_type, cnt + 1);
901 }
902
903 return 0;
904}
905
8bf488d2
TK
906static int max_constraint_data_updater(enum exynos_dm_type dm_type, int cnt)
907{
908 struct exynos_dm_data *dm;
909 struct exynos_dm_constraint *constraint;
910 struct list_head *constraint_list;
911
912 dm = &exynos_dm->dm_data[dm_type];
913
914 /* Check dependent domains */
915 constraint_checker_max(get_max_constraint_list(dm), dm->max_freq);
916
917 if (!dm->constraint_checked)
918 dm->constraint_checked += cnt;
919
920 max_order[dm->constraint_checked] = dm_type;
921
922 constraint_list = get_max_constraint_list(dm);
923 if (list_empty(constraint_list))
924 return 0;
925
926 max_order[0] = 0;
927
928 list_for_each_entry(constraint, constraint_list, node) {
929 dm = &exynos_dm->dm_data[constraint->constraint_dm_type];
930 dm_data_updater(dm->dm_type);
931
932 dm->target_freq = dm->min_freq;
933 if (dm->target_freq >= dm->max_freq)
934 dm->target_freq = dm->max_freq;
935
936 max_constraint_data_updater(dm->dm_type, cnt + 1);
937 }
938
939 return 0;
940}
941
eea99674
EJ
942/*
943 * Scaling Callback
944 * Call callback function in each DVFS drivers to scaling frequency
945 */
946static int scaling_callback(enum dvfs_direction dir, unsigned int relation)
947{
948 struct exynos_dm_data *dm;
8bf488d2 949 int i;
eea99674
EJ
950
951 switch (dir) {
952 case DOWN:
8bf488d2
TK
953 if (min_order[0] == 0 && max_flag == false) {
954 for (i = 1; i <= DM_TYPE_END; i++) {
955 if (min_order[i] == DM_EMPTY)
956 continue;
957
958 dm = &exynos_dm->dm_data[min_order[i]];
959 if (dm->constraint_checked) {
960 if (dm->freq_scaler) {
26129728 961 dm->freq_scaler(dm->dm_type, dm->devdata, dm->target_freq, relation);
8bf488d2
TK
962 dm->cur_freq = dm->target_freq;
963 }
964 dm->constraint_checked = 0;
eea99674 965 }
8bf488d2 966 }
5e3661d7 967 } else if (max_order[0] == 0 && max_flag == true) {
8bf488d2
TK
968 for (i = DM_TYPE_END; i > 0; i--) {
969 if (max_order[i] == DM_EMPTY)
970 continue;
971
972 dm = &exynos_dm->dm_data[max_order[i]];
973 if (dm->constraint_checked) {
974 if (dm->freq_scaler) {
26129728 975 dm->freq_scaler(dm->dm_type, dm->devdata, dm->target_freq, relation);
8bf488d2
TK
976 dm->cur_freq = dm->target_freq;
977 }
978 dm->constraint_checked = 0;
eea99674 979 }
eea99674
EJ
980 }
981 }
982 break;
983 case UP:
8bf488d2
TK
984 if (min_order[0] == 0) {
985 for (i = DM_TYPE_END; i > 0; i--) {
986 if (min_order[i] == DM_EMPTY)
987 continue;
988
989 dm = &exynos_dm->dm_data[min_order[i]];
990 if (dm->constraint_checked) {
991 if (dm->freq_scaler) {
26129728 992 dm->freq_scaler(dm->dm_type, dm->devdata, dm->target_freq, relation);
8bf488d2
TK
993 dm->cur_freq = dm->target_freq;
994 }
995 dm->constraint_checked = 0;
eea99674 996 }
8bf488d2
TK
997 }
998 } else if (max_order[0] == 0) {
999 for (i = 1; i <= DM_TYPE_END; i++) {
1000 if (max_order[i] == DM_EMPTY)
1001 continue;
1002
1003 dm = &exynos_dm->dm_data[max_order[i]];
1004 if (dm->constraint_checked) {
1005 if (dm->freq_scaler) {
26129728 1006 dm->freq_scaler(dm->dm_type, dm->devdata, dm->target_freq, relation);
8bf488d2
TK
1007 dm->cur_freq = dm->target_freq;
1008 }
1009 dm->constraint_checked = 0;
eea99674 1010 }
eea99674
EJ
1011 }
1012 }
1013 break;
1014 default:
1015 break;
1016 }
1017
8bf488d2
TK
1018 for (i = 1; i <= DM_TYPE_END; i++) {
1019 if (min_order[i] == DM_EMPTY)
1020 continue;
1021
1022 dm = &exynos_dm->dm_data[min_order[i]];
1023 if (dm->constraint_checked) {
eea99674 1024 if (dm->freq_scaler) {
26129728 1025 dm->freq_scaler(dm->dm_type, dm->devdata, dm->target_freq, relation);
eea99674
EJ
1026 dm->cur_freq = dm->target_freq;
1027 }
8bf488d2 1028 dm->constraint_checked = 0;
eea99674 1029 }
8bf488d2
TK
1030 }
1031
8bf488d2 1032 max_flag = false;
eea99674
EJ
1033
1034 return 0;
1035}
1036
1037static void get_governor_min_freq(struct exynos_dm_data *dm_data, u32 *gov_min_freq)
1038{
1039 *gov_min_freq = dm_data->gov_min_freq;
1040}
1041
1042static void get_min_max_freq(struct exynos_dm_data *dm_data, u32 *min_freq, u32 *max_freq)
1043{
1044 *min_freq = dm_data->min_freq;
1045 *max_freq = dm_data->max_freq;
1046}
1047
1048static void update_min_max_freq(struct exynos_dm_data *dm_data, u32 min_freq, u32 max_freq)
1049{
1050 dm_data->min_freq = min_freq;
1051 dm_data->max_freq = max_freq;
1052}
1053
1054static void get_policy_min_max_freq(struct exynos_dm_data *dm_data, u32 *min_freq, u32 *max_freq)
1055{
1056 *min_freq = dm_data->policy_min_freq;
1057 *max_freq = dm_data->policy_max_freq;
1058}
1059
1060static void update_policy_min_max_freq(struct exynos_dm_data *dm_data, u32 min_freq, u32 max_freq)
1061{
1062 dm_data->policy_min_freq = min_freq;
1063 dm_data->policy_max_freq = max_freq;
1064}
1065
1066static void get_current_freq(struct exynos_dm_data *dm_data, u32 *cur_freq)
1067{
1068 *cur_freq = dm_data->cur_freq;
1069}
1070
1071static void get_target_freq(struct exynos_dm_data *dm_data, u32 *target_freq)
1072{
1073 *target_freq = dm_data->target_freq;
1074}
1075
1076static int exynos_dm_suspend(struct device *dev)
1077{
1078 /* Suspend callback function might be registered if necessary */
1079
1080 return 0;
1081}
1082
1083static int exynos_dm_resume(struct device *dev)
1084{
1085 /* Resume callback function might be registered if necessary */
1086
1087 return 0;
1088}
1089
1090static int exynos_dm_probe(struct platform_device *pdev)
1091{
1092 int ret = 0;
1093 struct exynos_dm_device *dm;
9e58ad01 1094 int i;
eea99674
EJ
1095
1096 dm = kzalloc(sizeof(struct exynos_dm_device), GFP_KERNEL);
1097 if (dm == NULL) {
1098 dev_err(&pdev->dev, "failed to allocate DVFS Manager device\n");
1099 ret = -ENOMEM;
1100 goto err_device;
1101 }
1102
1103 dm->dev = &pdev->dev;
1104
1105 mutex_init(&dm->lock);
1106
1107 /* parsing devfreq dts data for exynos-dvfs-manager */
1108 ret = exynos_dm_parse_dt(dm->dev->of_node, dm);
1109 if (ret) {
1110 dev_err(dm->dev, "failed to parse private data\n");
1111 goto err_parse_dt;
1112 }
1113
1114 print_available_dm_data(dm);
1115
1116 ret = sysfs_create_group(&dm->dev->kobj, &exynos_dm_attr_group);
1117 if (ret)
1118 dev_warn(dm->dev, "failed create sysfs for DVFS Manager\n");
1119
9e58ad01
HG
1120 for (i = 0; i < DM_TYPE_END; i++) {
1121 if (!dm->dm_data[i].available)
1122 continue;
1123
1124 snprintf(dm->dm_data[i].dm_policy_attr.name, EXYNOS_DM_ATTR_NAME_LEN,
1125 "dm_policy_%s", dm->dm_data[i].dm_type_name);
1126 sysfs_attr_init(&dm->dm_data[i].dm_policy_attr.attr.attr);
1127 dm->dm_data[i].dm_policy_attr.attr.attr.name =
1128 dm->dm_data[i].dm_policy_attr.name;
1129 dm->dm_data[i].dm_policy_attr.attr.attr.mode = (S_IRUSR | S_IRGRP);
1130 dm->dm_data[i].dm_policy_attr.attr.show = show_dm_policy;
1131
1132 ret = sysfs_add_file_to_group(&dm->dev->kobj, &dm->dm_data[i].dm_policy_attr.attr.attr, exynos_dm_attr_group.name);
1133 if (ret)
1134 dev_warn(dm->dev, "failed create sysfs for DM policy %s\n", dm->dm_data[i].dm_type_name);
1135
1136
1137 snprintf(dm->dm_data[i].constraint_table_attr.name, EXYNOS_DM_ATTR_NAME_LEN,
1138 "constaint_table_%s", dm->dm_data[i].dm_type_name);
1139 sysfs_attr_init(&dm->dm_data[i].constraint_table_attr.attr.attr);
1140 dm->dm_data[i].constraint_table_attr.attr.attr.name =
1141 dm->dm_data[i].constraint_table_attr.name;
1142 dm->dm_data[i].constraint_table_attr.attr.attr.mode = (S_IRUSR | S_IRGRP);
1143 dm->dm_data[i].constraint_table_attr.attr.show = show_constraint_table;
1144
1145 ret = sysfs_add_file_to_group(&dm->dev->kobj, &dm->dm_data[i].constraint_table_attr.attr.attr, exynos_dm_attr_group.name);
1146 if (ret)
1147 dev_warn(dm->dev, "failed create sysfs for constraint_table %s\n", dm->dm_data[i].dm_type_name);
1148 }
1149
eea99674
EJ
1150 exynos_dm = dm;
1151 platform_set_drvdata(pdev, dm);
1152
1153 return 0;
1154
1155err_parse_dt:
1156 mutex_destroy(&dm->lock);
1157 kfree(dm);
1158err_device:
1159
1160 return ret;
1161}
1162
1163static int exynos_dm_remove(struct platform_device *pdev)
1164{
1165 struct exynos_dm_device *dm = platform_get_drvdata(pdev);
1166
1167 sysfs_remove_group(&dm->dev->kobj, &exynos_dm_attr_group);
1168 mutex_destroy(&dm->lock);
1169 kfree(dm);
1170
1171 return 0;
1172}
1173
1174static struct platform_device_id exynos_dm_driver_ids[] = {
1175 {
1176 .name = EXYNOS_DM_MODULE_NAME,
1177 },
1178 {},
1179};
1180MODULE_DEVICE_TABLE(platform, exynos_dm_driver_ids);
1181
1182static const struct of_device_id exynos_dm_match[] = {
1183 {
1184 .compatible = "samsung,exynos-dvfs-manager",
1185 },
1186 {},
1187};
1188MODULE_DEVICE_TABLE(of, exynos_dm_match);
1189
1190static const struct dev_pm_ops exynos_dm_pm_ops = {
1191 .suspend = exynos_dm_suspend,
1192 .resume = exynos_dm_resume,
1193};
1194
1195static struct platform_driver exynos_dm_driver = {
1196 .probe = exynos_dm_probe,
1197 .remove = exynos_dm_remove,
1198 .id_table = exynos_dm_driver_ids,
1199 .driver = {
1200 .name = EXYNOS_DM_MODULE_NAME,
1201 .owner = THIS_MODULE,
1202 .pm = &exynos_dm_pm_ops,
1203 .of_match_table = exynos_dm_match,
1204 },
1205};
1206
1207static int __init exynos_dm_init(void)
1208{
1209 return platform_driver_register(&exynos_dm_driver);
1210}
1211subsys_initcall(exynos_dm_init);
1212
1213static void __exit exynos_dm_exit(void)
1214{
1215 platform_driver_unregister(&exynos_dm_driver);
1216}
1217module_exit(exynos_dm_exit);
1218
1219MODULE_AUTHOR("Taekki Kim <taekki.kim@samsung.com>");
1220MODULE_AUTHOR("Eunok Jo <eunok25.jo@samsung.com>");
1221MODULE_DESCRIPTION("Samsung EXYNOS SoC series DVFS Manager");
1222MODULE_LICENSE("GPL");