1 /* drivers/gpu/arm/.../platform/gpu_custom_interface.c
3 * Copyright 2011 by S.LSI. Samsung Electronics Inc.
4 * San#24, Nongseo-Dong, Giheung-Gu, Yongin, Korea
6 * Samsung SoC Mali-T Series DVFS driver
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.
14 * @file gpu_custom_interface.c
18 #include <mali_kbase.h>
22 #if defined(CONFIG_MALI_DVFS) && defined(CONFIG_EXYNOS_THERMAL) && defined(CONFIG_GPU_THERMAL)
23 #include "exynos_tmu.h"
26 #include "mali_kbase_platform.h"
27 #include "gpu_dvfs_handler.h"
28 #include "gpu_dvfs_governor.h"
29 #include "gpu_control.h"
30 #ifdef CONFIG_CPU_THERMAL_IPA
32 #endif /* CONFIG_CPU_THERMAL_IPA */
33 #include "gpu_custom_interface.h"
35 #ifdef CONFIG_MALI_RT_PM
36 #include <soc/samsung/exynos-pd.h>
39 extern struct kbase_device
*pkbdev
;
41 int gpu_pmqos_dvfs_min_lock(int level
)
43 #ifdef CONFIG_MALI_DVFS
45 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
48 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "%s: platform context is not initialized\n", __func__
);
52 clock
= gpu_dvfs_get_clock(level
);
54 gpu_dvfs_clock_lock(GPU_DVFS_MIN_UNLOCK
, PMQOS_LOCK
, 0);
56 gpu_dvfs_clock_lock(GPU_DVFS_MIN_LOCK
, PMQOS_LOCK
, clock
);
57 #endif /* CONFIG_MALI_DVFS */
61 static ssize_t
show_clock(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
65 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
70 #ifdef CONFIG_MALI_RT_PM
71 if (platform
->exynos_pm_domain
) {
72 mutex_lock(&platform
->exynos_pm_domain
->access_lock
);
73 if(!platform
->dvs_is_enabled
&& gpu_is_power_on())
74 clock
= gpu_get_cur_clock(platform
);
75 mutex_unlock(&platform
->exynos_pm_domain
->access_lock
);
78 if (gpu_control_is_power_on(pkbdev
) == 1) {
79 mutex_lock(&platform
->gpu_clock_lock
);
80 if (!platform
->dvs_is_enabled
)
81 clock
= gpu_get_cur_clock(platform
);
82 mutex_unlock(&platform
->gpu_clock_lock
);
86 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "%d", clock
);
88 if (ret
< PAGE_SIZE
- 1) {
89 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
91 buf
[PAGE_SIZE
-2] = '\n';
92 buf
[PAGE_SIZE
-1] = '\0';
99 static ssize_t
set_clock(struct device
*dev
, struct device_attribute
*attr
, const char *buf
, size_t count
)
101 unsigned int clk
= 0;
102 int ret
, i
, policy_count
;
103 static bool cur_state
;
104 const struct kbase_pm_policy
*const *policy_list
;
105 static const struct kbase_pm_policy
*prev_policy
;
106 static bool prev_tmu_status
= true;
107 #ifdef CONFIG_MALI_DVFS
108 static bool prev_dvfs_status
= true;
109 #endif /* CONFIG_MALI_DVFS */
110 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
115 ret
= kstrtoint(buf
, 0, &clk
);
117 GPU_LOG(DVFS_WARNING
, DUMMY
, 0u, 0u, "%s: invalid value\n", __func__
);
122 prev_tmu_status
= platform
->tmu_status
;
123 #ifdef CONFIG_MALI_DVFS
124 prev_dvfs_status
= platform
->dvfs_status
;
125 #endif /* CONFIG_MALI_DVFS */
126 prev_policy
= kbase_pm_get_policy(pkbdev
);
130 kbase_pm_set_policy(pkbdev
, prev_policy
);
131 platform
->tmu_status
= prev_tmu_status
;
132 #ifdef CONFIG_MALI_DVFS
133 if (!platform
->dvfs_status
)
134 gpu_dvfs_on_off(true);
135 #endif /* CONFIG_MALI_DVFS */
138 policy_count
= kbase_pm_list_policies(&policy_list
);
139 for (i
= 0; i
< policy_count
; i
++) {
140 if (sysfs_streq(policy_list
[i
]->name
, "always_on")) {
141 kbase_pm_set_policy(pkbdev
, policy_list
[i
]);
145 platform
->tmu_status
= false;
146 #ifdef CONFIG_MALI_DVFS
147 if (platform
->dvfs_status
)
148 gpu_dvfs_on_off(false);
149 #endif /* CONFIG_MALI_DVFS */
150 gpu_set_target_clk_vol(clk
, false);
157 static ssize_t
show_vol(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
160 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
165 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "%d", gpu_get_cur_voltage(platform
));
167 if (ret
< PAGE_SIZE
- 1) {
168 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
170 buf
[PAGE_SIZE
-2] = '\n';
171 buf
[PAGE_SIZE
-1] = '\0';
178 static ssize_t
show_power_state(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
181 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
186 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "%d", gpu_control_is_power_on(pkbdev
));
188 if (ret
< PAGE_SIZE
- 1) {
189 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
191 buf
[PAGE_SIZE
-2] = '\n';
192 buf
[PAGE_SIZE
-1] = '\0';
199 static int gpu_get_asv_table(struct exynos_context
*platform
, char *buf
, size_t buf_size
)
209 cnt
+= snprintf(buf
+cnt
, buf_size
-cnt
, "GPU, vol, min, max, down_stay, mif, cpu0, cpu1\n");
211 for (i
= gpu_dvfs_get_level(platform
->gpu_max_clock
); i
<= gpu_dvfs_get_level(platform
->gpu_min_clock
); i
++) {
212 cnt
+= snprintf(buf
+cnt
, buf_size
-cnt
, "%d, %7d, %2d, %3d, %d, %7d, %7d, %7d\n",
213 platform
->table
[i
].clock
, platform
->table
[i
].voltage
, platform
->table
[i
].min_threshold
,
214 platform
->table
[i
].max_threshold
, platform
->table
[i
].down_staycount
, platform
->table
[i
].mem_freq
,
215 platform
->table
[i
].cpu_little_min_freq
, platform
->table
[i
].cpu_middle_min_freq
);
221 static ssize_t
show_asv_table(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
224 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
229 ret
+= gpu_get_asv_table(platform
, buf
+ret
, (size_t)PAGE_SIZE
-ret
);
231 if (ret
< PAGE_SIZE
- 1) {
232 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
234 buf
[PAGE_SIZE
-2] = '\n';
235 buf
[PAGE_SIZE
-1] = '\0';
242 static int gpu_get_dvfs_table(struct exynos_context
*platform
, char *buf
, size_t buf_size
)
252 for (i
= gpu_dvfs_get_level(platform
->gpu_max_clock
); i
<= gpu_dvfs_get_level(platform
->gpu_min_clock
); i
++)
253 cnt
+= snprintf(buf
+cnt
, buf_size
-cnt
, " %d", platform
->table
[i
].clock
);
255 cnt
+= snprintf(buf
+cnt
, buf_size
-cnt
, "\n");
260 static ssize_t
show_dvfs_table(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
263 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
268 ret
+= gpu_get_dvfs_table(platform
, buf
+ret
, (size_t)PAGE_SIZE
-ret
);
270 if (ret
< PAGE_SIZE
- 1) {
271 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
273 buf
[PAGE_SIZE
-2] = '\n';
274 buf
[PAGE_SIZE
-1] = '\0';
281 static ssize_t
show_time_in_state(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
285 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
290 gpu_dvfs_update_time_in_state(gpu_control_is_power_on(pkbdev
) * platform
->cur_clock
);
292 for (i
= gpu_dvfs_get_level(platform
->gpu_min_clock
); i
>= gpu_dvfs_get_level(platform
->gpu_max_clock
); i
--) {
293 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "%d %llu\n",
294 platform
->table
[i
].clock
,
295 platform
->table
[i
].time
);
298 if (ret
>= PAGE_SIZE
- 1) {
299 buf
[PAGE_SIZE
-2] = '\n';
300 buf
[PAGE_SIZE
-1] = '\0';
307 static ssize_t
set_time_in_state(struct device
*dev
, struct device_attribute
*attr
, const char *buf
, size_t count
)
309 gpu_dvfs_init_time_in_state();
314 static ssize_t
show_utilization(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
317 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
322 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "%d", gpu_control_is_power_on(pkbdev
) * platform
->env_data
.utilization
);
324 if (ret
< PAGE_SIZE
- 1) {
325 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
327 buf
[PAGE_SIZE
-2] = '\n';
328 buf
[PAGE_SIZE
-1] = '\0';
335 static ssize_t
show_perf(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
338 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
343 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "%d", gpu_control_is_power_on(pkbdev
) * platform
->env_data
.perf
);
345 if (ret
< PAGE_SIZE
- 1) {
346 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
348 buf
[PAGE_SIZE
-2] = '\n';
349 buf
[PAGE_SIZE
-1] = '\0';
356 #ifdef CONFIG_MALI_DVFS
357 static ssize_t
show_dvfs(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
360 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
365 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "%d", platform
->dvfs_status
);
367 if (ret
< PAGE_SIZE
- 1) {
368 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
370 buf
[PAGE_SIZE
-2] = '\n';
371 buf
[PAGE_SIZE
-1] = '\0';
378 static ssize_t
set_dvfs(struct device
*dev
, struct device_attribute
*attr
, const char *buf
, size_t count
)
380 if (sysfs_streq("0", buf
))
381 gpu_dvfs_on_off(false);
382 else if (sysfs_streq("1", buf
))
383 gpu_dvfs_on_off(true);
388 static ssize_t
show_governor(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
391 gpu_dvfs_governor_info
*governor_info
;
393 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
398 governor_info
= (gpu_dvfs_governor_info
*)gpu_dvfs_get_governor_info();
400 for (i
= 0; i
< G3D_MAX_GOVERNOR_NUM
; i
++)
401 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "%s\n", governor_info
[i
].name
);
403 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "[Current Governor] %s", governor_info
[platform
->governor_type
].name
);
405 if (ret
< PAGE_SIZE
- 1) {
406 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
408 buf
[PAGE_SIZE
-2] = '\n';
409 buf
[PAGE_SIZE
-1] = '\0';
416 static ssize_t
set_governor(struct device
*dev
, struct device_attribute
*attr
, const char *buf
, size_t count
)
419 int next_governor_type
;
420 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
425 ret
= kstrtoint(buf
, 0, &next_governor_type
);
427 if ((next_governor_type
< 0) || (next_governor_type
>= G3D_MAX_GOVERNOR_NUM
)) {
428 GPU_LOG(DVFS_WARNING
, DUMMY
, 0u, 0u, "%s: invalid value\n", __func__
);
432 ret
= gpu_dvfs_governor_change(next_governor_type
);
435 GPU_LOG(DVFS_WARNING
, DUMMY
, 0u, 0u,
436 "%s: fail to set the new governor (%d)\n", __func__
, next_governor_type
);
443 static ssize_t
show_max_lock_status(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
448 int max_lock_status
[NUMBER_LOCK
];
449 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
454 spin_lock_irqsave(&platform
->gpu_dvfs_spinlock
, flags
);
455 for (i
= 0; i
< NUMBER_LOCK
; i
++)
456 max_lock_status
[i
] = platform
->user_max_lock
[i
];
457 spin_unlock_irqrestore(&platform
->gpu_dvfs_spinlock
, flags
);
459 for (i
= 0; i
< NUMBER_LOCK
; i
++)
460 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "[%d:%d]", i
, max_lock_status
[i
]);
462 if (ret
< PAGE_SIZE
- 1) {
463 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
465 buf
[PAGE_SIZE
-2] = '\n';
466 buf
[PAGE_SIZE
-1] = '\0';
473 static ssize_t
show_min_lock_status(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
478 int min_lock_status
[NUMBER_LOCK
];
479 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
484 spin_lock_irqsave(&platform
->gpu_dvfs_spinlock
, flags
);
485 for (i
= 0; i
< NUMBER_LOCK
; i
++)
486 min_lock_status
[i
] = platform
->user_min_lock
[i
];
487 spin_unlock_irqrestore(&platform
->gpu_dvfs_spinlock
, flags
);
489 for (i
= 0; i
< NUMBER_LOCK
; i
++)
490 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "[%d:%d]", i
, min_lock_status
[i
]);
492 if (ret
< PAGE_SIZE
- 1) {
493 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
495 buf
[PAGE_SIZE
-2] = '\n';
496 buf
[PAGE_SIZE
-1] = '\0';
503 static ssize_t
show_max_lock_dvfs(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
507 int locked_clock
= -1;
508 int user_locked_clock
= -1;
509 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
514 spin_lock_irqsave(&platform
->gpu_dvfs_spinlock
, flags
);
515 locked_clock
= platform
->max_lock
;
516 user_locked_clock
= platform
->user_max_lock_input
;
517 spin_unlock_irqrestore(&platform
->gpu_dvfs_spinlock
, flags
);
519 if (locked_clock
> 0)
520 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "%d / %d", locked_clock
, user_locked_clock
);
522 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "-1");
524 if (ret
< PAGE_SIZE
- 1) {
525 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
527 buf
[PAGE_SIZE
-2] = '\n';
528 buf
[PAGE_SIZE
-1] = '\0';
535 static ssize_t
set_max_lock_dvfs(struct device
*dev
, struct device_attribute
*attr
, const char *buf
, size_t count
)
538 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
543 if (sysfs_streq("0", buf
)) {
544 platform
->user_max_lock_input
= 0;
545 gpu_dvfs_clock_lock(GPU_DVFS_MAX_UNLOCK
, SYSFS_LOCK
, 0);
547 ret
= kstrtoint(buf
, 0, &clock
);
549 GPU_LOG(DVFS_WARNING
, DUMMY
, 0u, 0u, "%s: invalid value\n", __func__
);
553 platform
->user_max_lock_input
= clock
;
555 clock
= gpu_dvfs_get_level_clock(clock
);
557 ret
= gpu_dvfs_get_level(clock
);
558 if ((ret
< gpu_dvfs_get_level(platform
->gpu_max_clock
)) || (ret
> gpu_dvfs_get_level(platform
->gpu_min_clock
))) {
559 GPU_LOG(DVFS_WARNING
, DUMMY
, 0u, 0u, "%s: invalid clock value (%d)\n", __func__
, clock
);
563 if (clock
== platform
->gpu_max_clock
)
564 gpu_dvfs_clock_lock(GPU_DVFS_MAX_UNLOCK
, SYSFS_LOCK
, 0);
566 gpu_dvfs_clock_lock(GPU_DVFS_MAX_LOCK
, SYSFS_LOCK
, clock
);
572 static ssize_t
show_min_lock_dvfs(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
576 int locked_clock
= -1;
577 int user_locked_clock
= -1;
578 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
583 spin_lock_irqsave(&platform
->gpu_dvfs_spinlock
, flags
);
584 locked_clock
= platform
->min_lock
;
585 user_locked_clock
= platform
->user_min_lock_input
;
586 spin_unlock_irqrestore(&platform
->gpu_dvfs_spinlock
, flags
);
588 if (locked_clock
> 0)
589 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "%d / %d", locked_clock
, user_locked_clock
);
591 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "-1");
593 if (ret
< PAGE_SIZE
- 1) {
594 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
596 buf
[PAGE_SIZE
-2] = '\n';
597 buf
[PAGE_SIZE
-1] = '\0';
604 static ssize_t
set_min_lock_dvfs(struct device
*dev
, struct device_attribute
*attr
, const char *buf
, size_t count
)
607 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
612 if (sysfs_streq("0", buf
)) {
613 platform
->user_min_lock_input
= 0;
614 gpu_dvfs_clock_lock(GPU_DVFS_MIN_UNLOCK
, SYSFS_LOCK
, 0);
616 ret
= kstrtoint(buf
, 0, &clock
);
618 GPU_LOG(DVFS_WARNING
, DUMMY
, 0u, 0u, "%s: invalid value\n", __func__
);
622 platform
->user_min_lock_input
= clock
;
624 clock
= gpu_dvfs_get_level_clock(clock
);
626 ret
= gpu_dvfs_get_level(clock
);
627 if ((ret
< gpu_dvfs_get_level(platform
->gpu_max_clock
)) || (ret
> gpu_dvfs_get_level(platform
->gpu_min_clock
))) {
628 GPU_LOG(DVFS_WARNING
, DUMMY
, 0u, 0u, "%s: invalid clock value (%d)\n", __func__
, clock
);
632 if (clock
> platform
->gpu_max_clock_limit
)
633 clock
= platform
->gpu_max_clock_limit
;
635 if (clock
== platform
->gpu_min_clock
)
636 gpu_dvfs_clock_lock(GPU_DVFS_MIN_UNLOCK
, SYSFS_LOCK
, 0);
638 gpu_dvfs_clock_lock(GPU_DVFS_MIN_LOCK
, SYSFS_LOCK
, clock
);
644 static ssize_t
show_down_staycount(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
649 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
654 spin_lock_irqsave(&platform
->gpu_dvfs_spinlock
, flags
);
655 for (i
= gpu_dvfs_get_level(platform
->gpu_max_clock
); i
<= gpu_dvfs_get_level(platform
->gpu_min_clock
); i
++)
656 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "Clock %d - %d\n",
657 platform
->table
[i
].clock
, platform
->table
[i
].down_staycount
);
658 spin_unlock_irqrestore(&platform
->gpu_dvfs_spinlock
, flags
);
660 if (ret
< PAGE_SIZE
- 1) {
661 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
663 buf
[PAGE_SIZE
-2] = '\n';
664 buf
[PAGE_SIZE
-1] = '\0';
671 #define MIN_DOWN_STAYCOUNT 1
672 #define MAX_DOWN_STAYCOUNT 10
673 static ssize_t
set_down_staycount(struct device
*dev
, struct device_attribute
*attr
, const char *buf
, size_t count
)
679 int clock
= -1, level
= -1, down_staycount
= 0;
680 unsigned int len
= 0;
681 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
686 len
= (unsigned int)min(count
, sizeof(tmpbuf
) - 1);
687 memcpy(tmpbuf
, buf
, len
);
691 tok
= strsep(&sptr
, " ,");
693 GPU_LOG(DVFS_WARNING
, DUMMY
, 0u, 0u, "%s: invalid input\n", __func__
);
697 ret
= kstrtoint(tok
, 0, &clock
);
699 GPU_LOG(DVFS_WARNING
, DUMMY
, 0u, 0u, "%s: invalid input %d\n", __func__
, clock
);
703 tok
= strsep(&sptr
, " ,");
705 GPU_LOG(DVFS_WARNING
, DUMMY
, 0u, 0u, "%s: invalid input\n", __func__
);
709 ret
= kstrtoint(tok
, 0, &down_staycount
);
711 GPU_LOG(DVFS_WARNING
, DUMMY
, 0u, 0u, "%s: invalid input %d\n", __func__
, down_staycount
);
715 level
= gpu_dvfs_get_level(clock
);
717 GPU_LOG(DVFS_WARNING
, DUMMY
, 0u, 0u, "%s: invalid clock value (%d)\n", __func__
, clock
);
721 if ((down_staycount
< MIN_DOWN_STAYCOUNT
) || (down_staycount
> MAX_DOWN_STAYCOUNT
)) {
722 GPU_LOG(DVFS_WARNING
, DUMMY
, 0u, 0u, "%s: down_staycount is out of range (%d, %d ~ %d)\n",
723 __func__
, down_staycount
, MIN_DOWN_STAYCOUNT
, MAX_DOWN_STAYCOUNT
);
727 spin_lock_irqsave(&platform
->gpu_dvfs_spinlock
, flags
);
728 platform
->table
[level
].down_staycount
= down_staycount
;
729 spin_unlock_irqrestore(&platform
->gpu_dvfs_spinlock
, flags
);
734 static ssize_t
show_highspeed_clock(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
738 int highspeed_clock
= -1;
739 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
744 spin_lock_irqsave(&platform
->gpu_dvfs_spinlock
, flags
);
745 highspeed_clock
= platform
->interactive
.highspeed_clock
;
746 spin_unlock_irqrestore(&platform
->gpu_dvfs_spinlock
, flags
);
748 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "%d", highspeed_clock
);
750 if (ret
< PAGE_SIZE
- 1) {
751 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
753 buf
[PAGE_SIZE
-2] = '\n';
754 buf
[PAGE_SIZE
-1] = '\0';
761 static ssize_t
set_highspeed_clock(struct device
*dev
, struct device_attribute
*attr
, const char *buf
, size_t count
)
765 int highspeed_clock
= -1;
766 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
771 ret
= kstrtoint(buf
, 0, &highspeed_clock
);
773 GPU_LOG(DVFS_WARNING
, DUMMY
, 0u, 0u, "%s: invalid value\n", __func__
);
777 ret
= gpu_dvfs_get_level(highspeed_clock
);
778 if ((ret
< gpu_dvfs_get_level(platform
->gpu_max_clock
)) || (ret
> gpu_dvfs_get_level(platform
->gpu_min_clock
))) {
779 GPU_LOG(DVFS_WARNING
, DUMMY
, 0u, 0u, "%s: invalid clock value (%d)\n", __func__
, highspeed_clock
);
783 if (highspeed_clock
> platform
->gpu_max_clock_limit
)
784 highspeed_clock
= platform
->gpu_max_clock_limit
;
786 spin_lock_irqsave(&platform
->gpu_dvfs_spinlock
, flags
);
787 platform
->interactive
.highspeed_clock
= highspeed_clock
;
788 spin_unlock_irqrestore(&platform
->gpu_dvfs_spinlock
, flags
);
793 static ssize_t
show_highspeed_load(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
797 int highspeed_load
= -1;
798 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
803 spin_lock_irqsave(&platform
->gpu_dvfs_spinlock
, flags
);
804 highspeed_load
= platform
->interactive
.highspeed_load
;
805 spin_unlock_irqrestore(&platform
->gpu_dvfs_spinlock
, flags
);
807 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "%d", highspeed_load
);
809 if (ret
< PAGE_SIZE
- 1) {
810 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
812 buf
[PAGE_SIZE
-2] = '\n';
813 buf
[PAGE_SIZE
-1] = '\0';
820 static ssize_t
set_highspeed_load(struct device
*dev
, struct device_attribute
*attr
, const char *buf
, size_t count
)
824 int highspeed_load
= -1;
825 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
830 ret
= kstrtoint(buf
, 0, &highspeed_load
);
832 GPU_LOG(DVFS_WARNING
, DUMMY
, 0u, 0u, "%s: invalid value\n", __func__
);
836 if ((highspeed_load
< 0) || (highspeed_load
> 100)) {
837 GPU_LOG(DVFS_WARNING
, DUMMY
, 0u, 0u, "%s: invalid load value (%d)\n", __func__
, highspeed_load
);
841 spin_lock_irqsave(&platform
->gpu_dvfs_spinlock
, flags
);
842 platform
->interactive
.highspeed_load
= highspeed_load
;
843 spin_unlock_irqrestore(&platform
->gpu_dvfs_spinlock
, flags
);
848 static ssize_t
show_highspeed_delay(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
852 int highspeed_delay
= -1;
853 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
858 spin_lock_irqsave(&platform
->gpu_dvfs_spinlock
, flags
);
859 highspeed_delay
= platform
->interactive
.highspeed_delay
;
860 spin_unlock_irqrestore(&platform
->gpu_dvfs_spinlock
, flags
);
862 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "%d", highspeed_delay
);
864 if (ret
< PAGE_SIZE
- 1) {
865 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
867 buf
[PAGE_SIZE
-2] = '\n';
868 buf
[PAGE_SIZE
-1] = '\0';
875 static ssize_t
set_highspeed_delay(struct device
*dev
, struct device_attribute
*attr
, const char *buf
, size_t count
)
879 int highspeed_delay
= -1;
880 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
885 ret
= kstrtoint(buf
, 0, &highspeed_delay
);
887 GPU_LOG(DVFS_WARNING
, DUMMY
, 0u, 0u, "%s: invalid value\n", __func__
);
891 if ((highspeed_delay
< 0) || (highspeed_delay
> 5)) {
892 GPU_LOG(DVFS_WARNING
, DUMMY
, 0u, 0u, "%s: invalid load value (%d)\n", __func__
, highspeed_delay
);
896 spin_lock_irqsave(&platform
->gpu_dvfs_spinlock
, flags
);
897 platform
->interactive
.highspeed_delay
= highspeed_delay
;
898 spin_unlock_irqrestore(&platform
->gpu_dvfs_spinlock
, flags
);
903 static ssize_t
show_wakeup_lock(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
906 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
911 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "%d", platform
->wakeup_lock
);
913 if (ret
< PAGE_SIZE
- 1) {
914 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
916 buf
[PAGE_SIZE
-2] = '\n';
917 buf
[PAGE_SIZE
-1] = '\0';
924 static ssize_t
set_wakeup_lock(struct device
*dev
, struct device_attribute
*attr
, const char *buf
, size_t count
)
926 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
931 if (sysfs_streq("0", buf
))
932 platform
->wakeup_lock
= false;
933 else if (sysfs_streq("1", buf
))
934 platform
->wakeup_lock
= true;
936 GPU_LOG(DVFS_WARNING
, DUMMY
, 0u, 0u, "%s: invalid val - only [0 or 1] is available\n", __func__
);
941 static ssize_t
show_polling_speed(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
944 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
949 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "%d", platform
->polling_speed
);
951 if (ret
< PAGE_SIZE
- 1) {
952 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
954 buf
[PAGE_SIZE
-2] = '\n';
955 buf
[PAGE_SIZE
-1] = '\0';
962 static ssize_t
set_polling_speed(struct device
*dev
, struct device_attribute
*attr
, const char *buf
, size_t count
)
964 int ret
, polling_speed
;
965 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
970 ret
= kstrtoint(buf
, 0, &polling_speed
);
973 GPU_LOG(DVFS_WARNING
, DUMMY
, 0u, 0u, "%s: invalid value\n", __func__
);
977 if ((polling_speed
< 100) || (polling_speed
> 1000)) {
978 GPU_LOG(DVFS_WARNING
, DUMMY
, 0u, 0u, "%s: out of range [100~1000] (%d)\n", __func__
, polling_speed
);
982 platform
->polling_speed
= polling_speed
;
987 static ssize_t
show_tmu(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
990 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
995 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "%d", platform
->tmu_status
);
997 if (ret
< PAGE_SIZE
- 1) {
998 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
1000 buf
[PAGE_SIZE
-2] = '\n';
1001 buf
[PAGE_SIZE
-1] = '\0';
1008 static ssize_t
set_tmu_control(struct device
*dev
, struct device_attribute
*attr
, const char *buf
, size_t count
)
1010 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
1015 if (sysfs_streq("0", buf
)) {
1016 if (platform
->voltage_margin
!= 0) {
1017 platform
->voltage_margin
= 0;
1018 gpu_set_target_clk_vol(platform
->cur_clock
, false);
1020 gpu_dvfs_clock_lock(GPU_DVFS_MAX_UNLOCK
, TMU_LOCK
, 0);
1021 platform
->tmu_status
= false;
1022 } else if (sysfs_streq("1", buf
))
1023 platform
->tmu_status
= true;
1025 GPU_LOG(DVFS_WARNING
, DUMMY
, 0u, 0u, "%s: invalid value - only [0 or 1] is available\n", __func__
);
1030 #ifdef CONFIG_CPU_THERMAL_IPA
1031 static ssize_t
show_norm_utilization(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
1034 #ifdef CONFIG_EXYNOS_THERMAL
1036 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "%d", gpu_ipa_dvfs_get_norm_utilisation(pkbdev
));
1038 if (ret
< PAGE_SIZE
- 1) {
1039 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
1041 buf
[PAGE_SIZE
-2] = '\n';
1042 buf
[PAGE_SIZE
-1] = '\0';
1046 GPU_LOG(DVFS_WARNING
, DUMMY
, 0u, 0u, "%s: EXYNOS THERMAL build config is disabled\n", __func__
);
1047 #endif /* CONFIG_EXYNOS_THERMAL */
1052 static ssize_t
show_utilization_stats(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
1055 #ifdef CONFIG_EXYNOS_THERMAL
1056 struct mali_debug_utilisation_stats stats
;
1058 gpu_ipa_dvfs_get_utilisation_stats(&stats
);
1060 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "util=%d norm_util=%d norm_freq=%d time_busy=%u time_idle=%u time_tick=%d",
1061 stats
.s
.utilisation
, stats
.s
.norm_utilisation
,
1062 stats
.s
.freq_for_norm
, stats
.time_busy
, stats
.time_idle
,
1065 if (ret
< PAGE_SIZE
- 1) {
1066 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
1068 buf
[PAGE_SIZE
-2] = '\n';
1069 buf
[PAGE_SIZE
-1] = '\0';
1073 GPU_LOG(DVFS_WARNING
, DUMMY
, 0u, 0u, "%s: EXYNOS THERMAL build config is disabled\n", __func__
);
1074 #endif /* CONFIG_EXYNOS_THERMAL */
1078 #endif /* CONFIG_CPU_THERMAL_IPA */
1079 #endif /* CONFIG_MALI_DVFS */
1081 static ssize_t
show_debug_level(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
1085 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "[Current] %d (%d ~ %d)",
1086 gpu_get_debug_level(), DVFS_DEBUG_START
+1, DVFS_DEBUG_END
-1);
1088 if (ret
< PAGE_SIZE
- 1) {
1089 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
1091 buf
[PAGE_SIZE
-2] = '\n';
1092 buf
[PAGE_SIZE
-1] = '\0';
1099 static ssize_t
set_debug_level(struct device
*dev
, struct device_attribute
*attr
, const char *buf
, size_t count
)
1101 int debug_level
, ret
;
1103 ret
= kstrtoint(buf
, 0, &debug_level
);
1105 GPU_LOG(DVFS_WARNING
, DUMMY
, 0u, 0u, "%s: invalid value\n", __func__
);
1109 if ((debug_level
<= DVFS_DEBUG_START
) || (debug_level
>= DVFS_DEBUG_END
)) {
1110 GPU_LOG(DVFS_WARNING
, DUMMY
, 0u, 0u, "%s: invalid debug level (%d)\n", __func__
, debug_level
);
1114 gpu_set_debug_level(debug_level
);
1119 #ifdef CONFIG_MALI_EXYNOS_TRACE
1120 static ssize_t
show_trace_level(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
1125 for (level
= TRACE_NONE
+ 1; level
< TRACE_END
- 1; level
++)
1126 if (gpu_check_trace_level(level
))
1127 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "<%d> ", level
);
1128 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\nList: %d ~ %d\n(None: %d, All: %d)",
1129 TRACE_NONE
+ 1, TRACE_ALL
- 1, TRACE_NONE
, TRACE_ALL
);
1131 if (ret
< PAGE_SIZE
- 1) {
1132 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
1134 buf
[PAGE_SIZE
-2] = '\n';
1135 buf
[PAGE_SIZE
-1] = '\0';
1142 static ssize_t
set_trace_level(struct device
*dev
, struct device_attribute
*attr
, const char *buf
, size_t count
)
1144 int trace_level
, ret
;
1146 ret
= kstrtoint(buf
, 0, &trace_level
);
1148 GPU_LOG(DVFS_WARNING
, DUMMY
, 0u, 0u, "%s: invalid value\n", __func__
);
1152 if ((trace_level
<= TRACE_START
) || (trace_level
>= TRACE_END
)) {
1153 GPU_LOG(DVFS_WARNING
, DUMMY
, 0u, 0u, "%s: invalid trace level (%d)\n", __func__
, trace_level
);
1157 gpu_set_trace_level(trace_level
);
1162 extern void kbasep_trace_format_msg(struct kbase_trace
*trace_msg
, char *buffer
, int len
);
1163 static ssize_t
show_trace_dump(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
1166 unsigned long flags
;
1169 spin_lock_irqsave(&pkbdev
->trace_lock
, flags
);
1170 start
= pkbdev
->trace_first_out
;
1171 end
= pkbdev
->trace_next_in
;
1173 while (start
!= end
) {
1174 char buffer
[KBASE_TRACE_SIZE
];
1175 struct kbase_trace
*trace_msg
= &pkbdev
->trace_rbuf
[start
];
1177 kbasep_trace_format_msg(trace_msg
, buffer
, KBASE_TRACE_SIZE
);
1178 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "%s\n", buffer
);
1180 if (ret
>= PAGE_SIZE
- 1)
1183 start
= (start
+ 1) & KBASE_TRACE_MASK
;
1186 spin_unlock_irqrestore(&pkbdev
->trace_lock
, flags
);
1187 KBASE_TRACE_CLEAR(pkbdev
);
1189 if (ret
< PAGE_SIZE
- 1) {
1190 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
1192 buf
[PAGE_SIZE
-2] = '\n';
1193 buf
[PAGE_SIZE
-1] = '\0';
1200 static ssize_t
init_trace_dump(struct device
*dev
, struct device_attribute
*attr
, const char *buf
, size_t count
)
1202 KBASE_TRACE_CLEAR(pkbdev
);
1206 #endif /* CONFIG_MALI_EXYNOS_TRACE */
1209 static ssize_t
show_fbdev(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
1214 for (i
= 0; i
< num_registered_fb
; i
++)
1215 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "fb[%d] xres=%d, yres=%d, addr=0x%lx\n", i
, registered_fb
[i
]->var
.xres
, registered_fb
[i
]->var
.yres
, registered_fb
[i
]->fix
.smem_start
);
1217 if (ret
< PAGE_SIZE
- 1) {
1218 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
1220 buf
[PAGE_SIZE
-2] = '\n';
1221 buf
[PAGE_SIZE
-1] = '\0';
1229 static int gpu_get_status(struct exynos_context
*platform
, char *buf
, size_t buf_size
)
1233 int mmu_fault_cnt
= 0;
1241 for (i
= GPU_MMU_TRANSLATION_FAULT
; i
<= GPU_MMU_MEMORY_ATTRIBUTES_FAULT
; i
++)
1242 mmu_fault_cnt
+= platform
->gpu_exception_count
[i
];
1244 cnt
+= snprintf(buf
+cnt
, buf_size
-cnt
, "reset count : %d\n", platform
->gpu_exception_count
[GPU_RESET
]);
1245 cnt
+= snprintf(buf
+cnt
, buf_size
-cnt
, "data invalid count : %d\n", platform
->gpu_exception_count
[GPU_DATA_INVALIDATE_FAULT
]);
1246 cnt
+= snprintf(buf
+cnt
, buf_size
-cnt
, "mmu fault count : %d\n", mmu_fault_cnt
);
1248 for (i
= 0; i
< BMAX_RETRY_CNT
; i
++)
1249 cnt
+= snprintf(buf
+cnt
, buf_size
-cnt
, "warmup retry count %d : %d\n", i
+1, platform
->balance_retry_count
[i
]);
1254 static ssize_t
show_gpu_status(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
1257 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
1262 ret
+= gpu_get_status(platform
, buf
+ret
, (size_t)PAGE_SIZE
-ret
);
1264 if (ret
< PAGE_SIZE
- 1) {
1265 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
1267 buf
[PAGE_SIZE
-2] = '\n';
1268 buf
[PAGE_SIZE
-1] = '\0';
1275 #ifdef CONFIG_MALI_VK_BOOST
1276 static ssize_t
show_vk_boost_status(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
1279 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
1284 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "%d", platform
->ctx_vk_need_qos
);
1286 if (ret
< PAGE_SIZE
- 1) {
1287 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
1289 buf
[PAGE_SIZE
-2] = '\n';
1290 buf
[PAGE_SIZE
-1] = '\0';
1298 #ifdef CONFIG_MALI_SUSTAINABLE_OPT
1299 static ssize_t
show_sustainable_status(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
1302 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
1307 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "%d", platform
->sustainable
.status
);
1309 if (ret
< PAGE_SIZE
- 1) {
1310 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
1312 buf
[PAGE_SIZE
-2] = '\n';
1313 buf
[PAGE_SIZE
-1] = '\0';
1321 #ifdef CONFIG_MALI_SEC_CL_BOOST
1322 static ssize_t
set_cl_boost_disable(struct device
*dev
, struct device_attribute
*attr
, const char *buf
, size_t count
)
1324 unsigned int cl_boost_disable
= 0;
1327 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
1332 ret
= kstrtoint(buf
, 0, &cl_boost_disable
);
1334 GPU_LOG(DVFS_WARNING
, DUMMY
, 0u, 0u, "%s: invalid value\n", __func__
);
1338 if (cl_boost_disable
== 0)
1339 platform
->cl_boost_disable
= false;
1341 platform
->cl_boost_disable
= true;
1346 static ssize_t
show_cl_boost_disable(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
1349 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
1354 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "%d", platform
->cl_boost_disable
);
1356 if (ret
< PAGE_SIZE
- 1) {
1357 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
1359 buf
[PAGE_SIZE
-2] = '\n';
1360 buf
[PAGE_SIZE
-1] = '\0';
1367 /** The sysfs file @c clock, fbdev.
1369 * This is used for obtaining information about the mali t series operating clock & framebuffer address,
1372 DEVICE_ATTR(clock
, S_IRUGO
|S_IWUSR
, show_clock
, set_clock
);
1373 DEVICE_ATTR(vol
, S_IRUGO
, show_vol
, NULL
);
1374 DEVICE_ATTR(power_state
, S_IRUGO
, show_power_state
, NULL
);
1375 DEVICE_ATTR(asv_table
, S_IRUGO
, show_asv_table
, NULL
);
1376 DEVICE_ATTR(dvfs_table
, S_IRUGO
, show_dvfs_table
, NULL
);
1377 DEVICE_ATTR(time_in_state
, S_IRUGO
|S_IWUSR
, show_time_in_state
, set_time_in_state
);
1378 DEVICE_ATTR(utilization
, S_IRUGO
, show_utilization
, NULL
);
1379 DEVICE_ATTR(perf
, S_IRUGO
, show_perf
, NULL
);
1380 #ifdef CONFIG_MALI_DVFS
1381 DEVICE_ATTR(dvfs
, S_IRUGO
|S_IWUSR
, show_dvfs
, set_dvfs
);
1382 DEVICE_ATTR(dvfs_governor
, S_IRUGO
|S_IWUSR
, show_governor
, set_governor
);
1383 DEVICE_ATTR(dvfs_max_lock_status
, S_IRUGO
, show_max_lock_status
, NULL
);
1384 DEVICE_ATTR(dvfs_min_lock_status
, S_IRUGO
, show_min_lock_status
, NULL
);
1385 DEVICE_ATTR(dvfs_max_lock
, S_IRUGO
|S_IWUSR
, show_max_lock_dvfs
, set_max_lock_dvfs
);
1386 DEVICE_ATTR(dvfs_min_lock
, S_IRUGO
|S_IWUSR
, show_min_lock_dvfs
, set_min_lock_dvfs
);
1387 DEVICE_ATTR(down_staycount
, S_IRUGO
|S_IWUSR
, show_down_staycount
, set_down_staycount
);
1388 DEVICE_ATTR(highspeed_clock
, S_IRUGO
|S_IWUSR
, show_highspeed_clock
, set_highspeed_clock
);
1389 DEVICE_ATTR(highspeed_load
, S_IRUGO
|S_IWUSR
, show_highspeed_load
, set_highspeed_load
);
1390 DEVICE_ATTR(highspeed_delay
, S_IRUGO
|S_IWUSR
, show_highspeed_delay
, set_highspeed_delay
);
1391 DEVICE_ATTR(wakeup_lock
, S_IRUGO
|S_IWUSR
, show_wakeup_lock
, set_wakeup_lock
);
1392 DEVICE_ATTR(polling_speed
, S_IRUGO
|S_IWUSR
, show_polling_speed
, set_polling_speed
);
1393 DEVICE_ATTR(tmu
, S_IRUGO
|S_IWUSR
, show_tmu
, set_tmu_control
);
1394 #ifdef CONFIG_CPU_THERMAL_IPA
1395 DEVICE_ATTR(norm_utilization
, S_IRUGO
, show_norm_utilization
, NULL
);
1396 DEVICE_ATTR(utilization_stats
, S_IRUGO
, show_utilization_stats
, NULL
);
1397 #endif /* CONFIG_CPU_THERMAL_IPA */
1398 #endif /* CONFIG_MALI_DVFS */
1399 DEVICE_ATTR(debug_level
, S_IRUGO
|S_IWUSR
, show_debug_level
, set_debug_level
);
1400 #ifdef CONFIG_MALI_EXYNOS_TRACE
1401 DEVICE_ATTR(trace_level
, S_IRUGO
|S_IWUSR
, show_trace_level
, set_trace_level
);
1402 DEVICE_ATTR(trace_dump
, S_IRUGO
|S_IWUSR
, show_trace_dump
, init_trace_dump
);
1403 #endif /* CONFIG_MALI_EXYNOS_TRACE */
1405 DEVICE_ATTR(fbdev
, S_IRUGO
, show_fbdev
, NULL
);
1407 DEVICE_ATTR(gpu_status
, S_IRUGO
, show_gpu_status
, NULL
);
1408 #ifdef CONFIG_MALI_VK_BOOST
1409 DEVICE_ATTR(vk_boost_status
, S_IRUGO
, show_vk_boost_status
, NULL
);
1411 #ifdef CONFIG_MALI_SUSTAINABLE_OPT
1412 DEVICE_ATTR(sustainable_status
, S_IRUGO
, show_sustainable_status
, NULL
);
1414 #ifdef CONFIG_MALI_SEC_CL_BOOST
1415 DEVICE_ATTR(cl_boost_disable
, S_IRUGO
|S_IWUSR
, show_cl_boost_disable
, set_cl_boost_disable
);
1418 #ifdef CONFIG_MALI_DEBUG_KERNEL_SYSFS
1419 #ifdef CONFIG_MALI_DVFS
1420 #define BUF_SIZE 1000
1421 static ssize_t
show_kernel_sysfs_gpu_info(struct kobject
*kobj
, struct kobj_attribute
*attr
, char *buf
)
1423 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
1432 ret
+= snprintf(buf
+ret
, BUF_SIZE
-ret
, "\"SSTOP\":\"%d\",", platform
->gpu_exception_count
[GPU_SOFT_STOP
]);
1433 ret
+= snprintf(buf
+ret
, BUF_SIZE
-ret
, "\"HSTOP\":\"%d\",", platform
->gpu_exception_count
[GPU_HARD_STOP
]);
1434 ret
+= snprintf(buf
+ret
, BUF_SIZE
-ret
, "\"RESET\":\"%d\",", platform
->gpu_exception_count
[GPU_RESET
]);
1435 ret
+= snprintf(buf
+ret
, BUF_SIZE
-ret
, "\"DIFLT\":\"%d\",", platform
->gpu_exception_count
[GPU_DATA_INVALIDATE_FAULT
]);
1436 ret
+= snprintf(buf
+ret
, BUF_SIZE
-ret
, "\"TRFLT\":\"%d\",", platform
->gpu_exception_count
[GPU_MMU_TRANSLATION_FAULT
]);
1437 ret
+= snprintf(buf
+ret
, BUF_SIZE
-ret
, "\"PMFLT\":\"%d\",", platform
->gpu_exception_count
[GPU_MMU_PERMISSION_FAULT
]);
1438 ret
+= snprintf(buf
+ret
, BUF_SIZE
-ret
, "\"BFLT\":\"%d\",", platform
->gpu_exception_count
[GPU_MMU_TRANSTAB_BUS_FAULT
]);
1439 ret
+= snprintf(buf
+ret
, BUF_SIZE
-ret
, "\"ACCFG\":\"%d\",", platform
->gpu_exception_count
[GPU_MMU_ACCESS_FLAG_FAULT
]);
1440 ret
+= snprintf(buf
+ret
, BUF_SIZE
-ret
, "\"ASFLT\":\"%d\",", platform
->gpu_exception_count
[GPU_MMU_ADDRESS_SIZE_FAULT
]);
1441 ret
+= snprintf(buf
+ret
, BUF_SIZE
-ret
, "\"ATFLT\":\"%d\",", platform
->gpu_exception_count
[GPU_MMU_MEMORY_ATTRIBUTES_FAULT
]);
1442 ret
+= snprintf(buf
+ret
, BUF_SIZE
-ret
, "\"UNKN\":\"%d\"", platform
->gpu_exception_count
[GPU_UNKNOWN
]);
1444 if (ret
< PAGE_SIZE
- 1) {
1445 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
1447 buf
[PAGE_SIZE
-2] = '\n';
1448 buf
[PAGE_SIZE
-1] = '\0';
1455 static ssize_t
show_kernel_sysfs_max_lock_dvfs(struct kobject
*kobj
, struct kobj_attribute
*attr
, char *buf
)
1458 unsigned long flags
;
1459 int locked_clock
= -1;
1460 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
1465 spin_lock_irqsave(&platform
->gpu_dvfs_spinlock
, flags
);
1466 locked_clock
= platform
->max_lock
;
1467 spin_unlock_irqrestore(&platform
->gpu_dvfs_spinlock
, flags
);
1469 if (locked_clock
> 0)
1470 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "%d", locked_clock
);
1472 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "%d", platform
->gpu_max_clock
);
1474 if (ret
< PAGE_SIZE
- 1) {
1475 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
1477 buf
[PAGE_SIZE
-2] = '\n';
1478 buf
[PAGE_SIZE
-1] = '\0';
1485 static ssize_t
set_kernel_sysfs_max_lock_dvfs(struct kobject
*kobj
, struct kobj_attribute
*attr
, const char *buf
, size_t count
)
1488 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
1493 if (sysfs_streq("0", buf
)) {
1494 platform
->user_max_lock_input
= 0;
1495 gpu_dvfs_clock_lock(GPU_DVFS_MAX_UNLOCK
, SYSFS_LOCK
, 0);
1497 ret
= kstrtoint(buf
, 0, &clock
);
1499 GPU_LOG(DVFS_WARNING
, DUMMY
, 0u, 0u, "%s: invalid value\n", __func__
);
1503 platform
->user_max_lock_input
= clock
;
1505 clock
= gpu_dvfs_get_level_clock(clock
);
1507 ret
= gpu_dvfs_get_level(clock
);
1508 if ((ret
< gpu_dvfs_get_level(platform
->gpu_max_clock
)) || (ret
> gpu_dvfs_get_level(platform
->gpu_min_clock
))) {
1509 GPU_LOG(DVFS_WARNING
, DUMMY
, 0u, 0u, "%s: invalid clock value (%d)\n", __func__
, clock
);
1513 if (clock
== platform
->gpu_max_clock
)
1514 gpu_dvfs_clock_lock(GPU_DVFS_MAX_UNLOCK
, SYSFS_LOCK
, 0);
1516 gpu_dvfs_clock_lock(GPU_DVFS_MAX_LOCK
, SYSFS_LOCK
, clock
);
1522 static ssize_t
show_kernel_sysfs_available_governor(struct kobject
*kobj
, struct kobj_attribute
*attr
, char *buf
)
1525 gpu_dvfs_governor_info
*governor_info
;
1527 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
1532 governor_info
= (gpu_dvfs_governor_info
*)gpu_dvfs_get_governor_info();
1534 for (i
= 0; i
< G3D_MAX_GOVERNOR_NUM
; i
++)
1535 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "%s ", governor_info
[i
].name
);
1537 if (ret
< PAGE_SIZE
- 1) {
1538 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
1540 buf
[PAGE_SIZE
-2] = '\n';
1541 buf
[PAGE_SIZE
-1] = '\0';
1548 static ssize_t
show_kernel_sysfs_min_lock_dvfs(struct kobject
*kobj
, struct kobj_attribute
*attr
, char *buf
)
1551 unsigned long flags
;
1552 int locked_clock
= -1;
1553 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
1558 spin_lock_irqsave(&platform
->gpu_dvfs_spinlock
, flags
);
1559 locked_clock
= platform
->min_lock
;
1560 spin_unlock_irqrestore(&platform
->gpu_dvfs_spinlock
, flags
);
1562 if (locked_clock
> 0)
1563 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "%d", locked_clock
);
1565 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "%d", platform
->gpu_min_clock
);
1567 if (ret
< PAGE_SIZE
- 1) {
1568 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
1570 buf
[PAGE_SIZE
-2] = '\n';
1571 buf
[PAGE_SIZE
-1] = '\0';
1578 static ssize_t
set_kernel_sysfs_min_lock_dvfs(struct kobject
*kobj
, struct kobj_attribute
*attr
, const char *buf
, size_t count
)
1581 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
1586 if (sysfs_streq("0", buf
)) {
1587 platform
->user_min_lock_input
= 0;
1588 gpu_dvfs_clock_lock(GPU_DVFS_MIN_UNLOCK
, SYSFS_LOCK
, 0);
1590 ret
= kstrtoint(buf
, 0, &clock
);
1592 GPU_LOG(DVFS_WARNING
, DUMMY
, 0u, 0u, "%s: invalid value\n", __func__
);
1596 platform
->user_min_lock_input
= clock
;
1598 clock
= gpu_dvfs_get_level_clock(clock
);
1600 ret
= gpu_dvfs_get_level(clock
);
1601 if ((ret
< gpu_dvfs_get_level(platform
->gpu_max_clock
)) || (ret
> gpu_dvfs_get_level(platform
->gpu_min_clock
))) {
1602 GPU_LOG(DVFS_WARNING
, DUMMY
, 0u, 0u, "%s: invalid clock value (%d)\n", __func__
, clock
);
1606 if (clock
> platform
->gpu_max_clock_limit
)
1607 clock
= platform
->gpu_max_clock_limit
;
1609 if (clock
== platform
->gpu_min_clock
)
1610 gpu_dvfs_clock_lock(GPU_DVFS_MIN_UNLOCK
, SYSFS_LOCK
, 0);
1612 gpu_dvfs_clock_lock(GPU_DVFS_MIN_LOCK
, SYSFS_LOCK
, clock
);
1617 #endif /* #ifdef CONFIG_MALI_DVFS */
1619 static ssize_t
show_kernel_sysfs_utilization(struct kobject
*kobj
, struct kobj_attribute
*attr
, char *buf
)
1622 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
1627 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "%3d%%", platform
->env_data
.utilization
);
1629 if (ret
< PAGE_SIZE
- 1) {
1630 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
1632 buf
[PAGE_SIZE
-2] = '\n';
1633 buf
[PAGE_SIZE
-1] = '\0';
1640 static ssize_t
show_kernel_sysfs_clock(struct kobject
*kobj
, struct kobj_attribute
*attr
, char *buf
)
1644 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
1649 #ifdef CONFIG_MALI_RT_PM
1650 if (platform
->exynos_pm_domain
) {
1651 mutex_lock(&platform
->exynos_pm_domain
->access_lock
);
1652 if (!platform
->dvs_is_enabled
&& gpu_is_power_on())
1653 clock
= gpu_get_cur_clock(platform
);
1654 mutex_unlock(&platform
->exynos_pm_domain
->access_lock
);
1657 if (gpu_control_is_power_on(pkbdev
) == 1) {
1658 mutex_lock(&platform
->gpu_clock_lock
);
1659 if (!platform
->dvs_is_enabled
)
1660 clock
= gpu_get_cur_clock(platform
);
1661 mutex_unlock(&platform
->gpu_clock_lock
);
1665 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "%d", clock
);
1667 if (ret
< PAGE_SIZE
- 1) {
1668 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
1670 buf
[PAGE_SIZE
-2] = '\n';
1671 buf
[PAGE_SIZE
-1] = '\0';
1678 static ssize_t
show_kernel_sysfs_freq_table(struct kobject
*kobj
, struct kobj_attribute
*attr
, char *buf
)
1682 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
1687 for (i
= gpu_dvfs_get_level(platform
->gpu_min_clock
); i
>= gpu_dvfs_get_level(platform
->gpu_max_clock
); i
--) {
1688 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "%d ", platform
->table
[i
].clock
);
1691 if (ret
< PAGE_SIZE
- 1) {
1692 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
1694 buf
[PAGE_SIZE
-2] = '\n';
1695 buf
[PAGE_SIZE
-1] = '\0';
1702 #ifdef CONFIG_MALI_DVFS
1703 static ssize_t
show_kernel_sysfs_governor(struct kobject
*kobj
, struct kobj_attribute
*attr
, char *buf
)
1706 gpu_dvfs_governor_info
*governor_info
= NULL
;
1707 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
1712 governor_info
= (gpu_dvfs_governor_info
*)gpu_dvfs_get_governor_info();
1714 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "%s", governor_info
[platform
->governor_type
].name
);
1716 if (ret
< PAGE_SIZE
- 1) {
1717 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
1719 buf
[PAGE_SIZE
-2] = '\n';
1720 buf
[PAGE_SIZE
-1] = '\0';
1727 static ssize_t
set_kernel_sysfs_governor(struct kobject
*kobj
, struct kobj_attribute
*attr
, const char *buf
, size_t count
)
1731 int next_governor_type
= -1;
1732 size_t governor_name_size
= 0;
1733 gpu_dvfs_governor_info
*governor_info
= NULL
;
1734 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
1739 governor_info
= (gpu_dvfs_governor_info
*)gpu_dvfs_get_governor_info();
1741 for (i
= 0; i
< G3D_MAX_GOVERNOR_NUM
; i
++) {
1742 governor_name_size
= strlen(governor_info
[i
].name
);
1743 if (!strncmp(buf
, governor_info
[i
].name
, governor_name_size
)) {
1744 next_governor_type
= i
;
1749 if ((next_governor_type
< 0) || (next_governor_type
>= G3D_MAX_GOVERNOR_NUM
)) {
1750 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "%s: invalid value\n", __func__
);
1754 ret
= gpu_dvfs_governor_change(next_governor_type
);
1757 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u,
1758 "%s: fail to set the new governor (%d)\n", __func__
, next_governor_type
);
1764 #endif /* #ifdef CONFIG_MALI_DVFS */
1766 static ssize_t
show_kernel_sysfs_gpu_model(struct kobject
*kobj
, struct kobj_attribute
*attr
, char *buf
)
1768 /* COPY from mali_kbase_core_linux.c : 2594 line, last updated: 20161017, r2p0-03rel0 */
1769 static const struct gpu_product_id_name
{
1772 } gpu_product_id_names
[] = {
1773 { .id
= GPU_ID_PI_T60X
, .name
= "Mali-T60x" },
1774 { .id
= GPU_ID_PI_T62X
, .name
= "Mali-T62x" },
1775 { .id
= GPU_ID_PI_T72X
, .name
= "Mali-T72x" },
1776 { .id
= GPU_ID_PI_T76X
, .name
= "Mali-T76x" },
1777 { .id
= GPU_ID_PI_T82X
, .name
= "Mali-T82x" },
1778 { .id
= GPU_ID_PI_T83X
, .name
= "Mali-T83x" },
1779 { .id
= GPU_ID_PI_T86X
, .name
= "Mali-T86x" },
1780 { .id
= GPU_ID_PI_TFRX
, .name
= "Mali-T88x" },
1781 { .id
= GPU_ID2_PRODUCT_TMIX
>> GPU_ID_VERSION_PRODUCT_ID_SHIFT
,
1782 .name
= "Mali-G71" },
1783 { .id
= GPU_ID2_PRODUCT_THEX
>> GPU_ID_VERSION_PRODUCT_ID_SHIFT
,
1784 .name
= "Mali-THEx" },
1786 const char *product_name
= "(Unknown Mali GPU)";
1787 struct kbase_device
*kbdev
;
1789 unsigned product_id
, product_id_mask
;
1797 gpu_id
= kbdev
->gpu_props
.props
.raw_props
.gpu_id
;
1798 product_id
= gpu_id
>> GPU_ID_VERSION_PRODUCT_ID_SHIFT
;
1799 is_new_format
= GPU_ID_IS_NEW_FORMAT(product_id
);
1802 GPU_ID2_PRODUCT_MODEL
:
1803 GPU_ID_VERSION_PRODUCT_ID
) >>
1804 GPU_ID_VERSION_PRODUCT_ID_SHIFT
;
1806 for (i
= 0; i
< ARRAY_SIZE(gpu_product_id_names
); ++i
) {
1807 const struct gpu_product_id_name
*p
= &gpu_product_id_names
[i
];
1809 if ((GPU_ID_IS_NEW_FORMAT(p
->id
) == is_new_format
) &&
1810 (p
->id
& product_id_mask
) ==
1811 (product_id
& product_id_mask
)) {
1812 product_name
= p
->name
;
1817 return scnprintf(buf
, PAGE_SIZE
, "%s\n", product_name
);
1820 #if defined(CONFIG_MALI_DVFS) && defined(CONFIG_EXYNOS_THERMAL) && defined(CONFIG_GPU_THERMAL)
1822 extern struct exynos_tmu_data
*gpu_thermal_data
;
1824 static ssize_t
show_kernel_sysfs_gpu_temp(struct kobject
*kobj
, struct kobj_attribute
*attr
, char *buf
)
1828 int gpu_temp_int
= 0;
1829 int gpu_temp_point
= 0;
1832 if (!gpu_thermal_data
) {
1833 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "[Kernel group SYSFS] thermal driver does not ready\n");
1837 mutex_lock(&gpu_thermal_data
->lock
);
1839 if (gpu_thermal_data
->num_of_sensors
)
1840 gpu_temp
= gpu_thermal_data
->tmu_read(gpu_thermal_data
) * MCELSIUS
;
1842 mutex_unlock(&gpu_thermal_data
->lock
);
1844 gpu_temp_int
= gpu_temp
/ 1000;
1845 gpu_temp_point
= gpu_temp
% gpu_temp_int
;
1846 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "%d.%d", gpu_temp_int
, gpu_temp_point
);
1848 if (ret
< PAGE_SIZE
- 1) {
1849 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
1851 buf
[PAGE_SIZE
-2] = '\n';
1852 buf
[PAGE_SIZE
-1] = '\0';
1859 static struct kobj_attribute gpu_temp_attribute
=
1860 __ATTR(gpu_tmu
, S_IRUGO
, show_kernel_sysfs_gpu_temp
, NULL
);
1863 #ifdef CONFIG_MALI_DVFS
1864 static struct kobj_attribute gpu_info_attribute
=
1865 __ATTR(gpu_info
, S_IRUGO
, show_kernel_sysfs_gpu_info
, NULL
);
1867 static struct kobj_attribute gpu_max_lock_attribute
=
1868 __ATTR(gpu_max_clock
, S_IRUGO
|S_IWUSR
, show_kernel_sysfs_max_lock_dvfs
, set_kernel_sysfs_max_lock_dvfs
);
1870 static struct kobj_attribute gpu_min_lock_attribute
=
1871 __ATTR(gpu_min_clock
, S_IRUGO
|S_IWUSR
, show_kernel_sysfs_min_lock_dvfs
, set_kernel_sysfs_min_lock_dvfs
);
1872 #endif /* #ifdef CONFIG_MALI_DVFS */
1874 static struct kobj_attribute gpu_busy_attribute
=
1875 __ATTR(gpu_busy
, S_IRUGO
, show_kernel_sysfs_utilization
, NULL
);
1877 static struct kobj_attribute gpu_clock_attribute
=
1878 __ATTR(gpu_clock
, S_IRUGO
, show_kernel_sysfs_clock
, NULL
);
1880 static struct kobj_attribute gpu_freq_table_attribute
=
1881 __ATTR(gpu_freq_table
, S_IRUGO
, show_kernel_sysfs_freq_table
, NULL
);
1883 #ifdef CONFIG_MALI_DVFS
1884 static struct kobj_attribute gpu_governor_attribute
=
1885 __ATTR(gpu_governor
, S_IRUGO
|S_IWUSR
, show_kernel_sysfs_governor
, set_kernel_sysfs_governor
);
1887 static struct kobj_attribute gpu_available_governor_attribute
=
1888 __ATTR(gpu_available_governor
, S_IRUGO
, show_kernel_sysfs_available_governor
, NULL
);
1889 #endif /* #ifdef CONFIG_MALI_DVFS */
1891 static struct kobj_attribute gpu_model_attribute
=
1892 __ATTR(gpu_model
, S_IRUGO
, show_kernel_sysfs_gpu_model
, NULL
);
1895 static struct attribute
*attrs
[] = {
1896 #ifdef CONFIG_MALI_DVFS
1897 #if defined(CONFIG_EXYNOS_THERMAL) && defined(CONFIG_GPU_THERMAL)
1898 &gpu_temp_attribute
.attr
,
1900 &gpu_info_attribute
.attr
,
1901 &gpu_max_lock_attribute
.attr
,
1902 &gpu_min_lock_attribute
.attr
,
1903 #endif /* #ifdef CONFIG_MALI_DVFS */
1904 &gpu_busy_attribute
.attr
,
1905 &gpu_clock_attribute
.attr
,
1906 &gpu_freq_table_attribute
.attr
,
1907 #ifdef CONFIG_MALI_DVFS
1908 &gpu_governor_attribute
.attr
,
1909 &gpu_available_governor_attribute
.attr
,
1910 #endif /* #ifdef CONFIG_MALI_DVFS */
1911 &gpu_model_attribute
.attr
,
1915 static struct attribute_group attr_group
= {
1918 static struct kobject
*external_kobj
;
1921 int gpu_create_sysfs_file(struct device
*dev
)
1923 #ifdef CONFIG_MALI_DEBUG_KERNEL_SYSFS
1927 if (device_create_file(dev
, &dev_attr_clock
)) {
1928 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [clock]\n");
1932 if (device_create_file(dev
, &dev_attr_vol
)) {
1933 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [vol]\n");
1937 if (device_create_file(dev
, &dev_attr_power_state
)) {
1938 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [power_state]\n");
1942 if (device_create_file(dev
, &dev_attr_asv_table
)) {
1943 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [asv_table]\n");
1947 if (device_create_file(dev
, &dev_attr_dvfs_table
)) {
1948 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [dvfs_table]\n");
1952 if (device_create_file(dev
, &dev_attr_time_in_state
)) {
1953 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [time_in_state]\n");
1957 if (device_create_file(dev
, &dev_attr_utilization
)) {
1958 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [utilization]\n");
1962 if (device_create_file(dev
, &dev_attr_perf
)) {
1963 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [perf]\n");
1966 #ifdef CONFIG_MALI_DVFS
1967 if (device_create_file(dev
, &dev_attr_dvfs
)) {
1968 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [dvfs]\n");
1972 if (device_create_file(dev
, &dev_attr_dvfs_governor
)) {
1973 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [dvfs_governor]\n");
1977 if (device_create_file(dev
, &dev_attr_dvfs_max_lock_status
)) {
1978 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [dvfs_max_lock_status]\n");
1982 if (device_create_file(dev
, &dev_attr_dvfs_min_lock_status
)) {
1983 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [dvfs_min_lock_status]\n");
1987 if (device_create_file(dev
, &dev_attr_dvfs_max_lock
)) {
1988 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [dvfs_max_lock]\n");
1992 if (device_create_file(dev
, &dev_attr_dvfs_min_lock
)) {
1993 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [dvfs_min_lock]\n");
1997 if (device_create_file(dev
, &dev_attr_down_staycount
)) {
1998 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [down_staycount]\n");
2002 if (device_create_file(dev
, &dev_attr_highspeed_clock
)) {
2003 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [highspeed_clock]\n");
2007 if (device_create_file(dev
, &dev_attr_highspeed_load
)) {
2008 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [highspeed_load]\n");
2012 if (device_create_file(dev
, &dev_attr_highspeed_delay
)) {
2013 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [highspeed_delay]\n");
2017 if (device_create_file(dev
, &dev_attr_wakeup_lock
)) {
2018 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [wakeup_lock]\n");
2022 if (device_create_file(dev
, &dev_attr_polling_speed
)) {
2023 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [polling_speed]\n");
2027 if (device_create_file(dev
, &dev_attr_tmu
)) {
2028 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [tmu]\n");
2031 #ifdef CONFIG_CPU_THERMAL_IPA
2032 if (device_create_file(dev
, &dev_attr_norm_utilization
)) {
2033 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [norm_utilization]\n");
2037 if (device_create_file(dev
, &dev_attr_utilization_stats
)) {
2038 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [utilization_stats]\n");
2041 #endif /* CONFIG_CPU_THERMAL_IPA */
2042 #endif /* CONFIG_MALI_DVFS */
2043 if (device_create_file(dev
, &dev_attr_debug_level
)) {
2044 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [debug_level]\n");
2047 #ifdef CONFIG_MALI_EXYNOS_TRACE
2048 if (device_create_file(dev
, &dev_attr_trace_level
)) {
2049 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [trace_level]\n");
2053 if (device_create_file(dev
, &dev_attr_trace_dump
)) {
2054 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [trace_dump]\n");
2057 #endif /* CONFIG_MALI_EXYNOS_TRACE */
2059 if (device_create_file(dev
, &dev_attr_fbdev
)) {
2060 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [fbdev]\n");
2065 if (device_create_file(dev
, &dev_attr_gpu_status
)) {
2066 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [gpu_status]\n");
2070 #ifdef CONFIG_MALI_VK_BOOST
2071 if (device_create_file(dev
, &dev_attr_vk_boost_status
)) {
2072 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [vk_boost_status]\n");
2077 #ifdef CONFIG_MALI_SUSTAINABLE_OPT
2078 if (device_create_file(dev
, &dev_attr_sustainable_status
)) {
2079 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [sustainable_status]\n");
2084 #ifdef CONFIG_MALI_SEC_CL_BOOST
2085 if (device_create_file(dev
, &dev_attr_cl_boost_disable
)) {
2086 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [cl_boost_disable]\n");
2091 #ifdef CONFIG_MALI_DEBUG_KERNEL_SYSFS
2092 external_kobj
= kobject_create_and_add("gpu", kernel_kobj
);
2093 if (!external_kobj
) {
2094 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create Kobj for group [KERNEL - GPU]\n");
2098 retval
= sysfs_create_group(external_kobj
, &attr_group
);
2100 kobject_put(external_kobj
);
2101 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't add sysfs group [KERNEL - GPU]\n");
2111 void gpu_remove_sysfs_file(struct device
*dev
)
2113 device_remove_file(dev
, &dev_attr_clock
);
2114 device_remove_file(dev
, &dev_attr_vol
);
2115 device_remove_file(dev
, &dev_attr_power_state
);
2116 device_remove_file(dev
, &dev_attr_asv_table
);
2117 device_remove_file(dev
, &dev_attr_dvfs_table
);
2118 device_remove_file(dev
, &dev_attr_time_in_state
);
2119 device_remove_file(dev
, &dev_attr_utilization
);
2120 device_remove_file(dev
, &dev_attr_perf
);
2121 #ifdef CONFIG_MALI_DVFS
2122 device_remove_file(dev
, &dev_attr_dvfs
);
2123 device_remove_file(dev
, &dev_attr_dvfs_governor
);
2124 device_remove_file(dev
, &dev_attr_dvfs_max_lock_status
);
2125 device_remove_file(dev
, &dev_attr_dvfs_min_lock_status
);
2126 device_remove_file(dev
, &dev_attr_dvfs_max_lock
);
2127 device_remove_file(dev
, &dev_attr_dvfs_min_lock
);
2128 device_remove_file(dev
, &dev_attr_down_staycount
);
2129 device_remove_file(dev
, &dev_attr_highspeed_clock
);
2130 device_remove_file(dev
, &dev_attr_highspeed_load
);
2131 device_remove_file(dev
, &dev_attr_highspeed_delay
);
2132 device_remove_file(dev
, &dev_attr_wakeup_lock
);
2133 device_remove_file(dev
, &dev_attr_polling_speed
);
2134 device_remove_file(dev
, &dev_attr_tmu
);
2135 #ifdef CONFIG_CPU_THERMAL_IPA
2136 device_remove_file(dev
, &dev_attr_norm_utilization
);
2137 device_remove_file(dev
, &dev_attr_utilization_stats
);
2138 #endif /* CONFIG_CPU_THERMAL_IPA */
2139 #endif /* CONFIG_MALI_DVFS */
2140 device_remove_file(dev
, &dev_attr_debug_level
);
2141 #ifdef CONFIG_MALI_EXYNOS_TRACE
2142 device_remove_file(dev
, &dev_attr_trace_level
);
2143 device_remove_file(dev
, &dev_attr_trace_dump
);
2144 #endif /* CONFIG_MALI_EXYNOS_TRACE */
2146 device_remove_file(dev
, &dev_attr_fbdev
);
2148 device_remove_file(dev
, &dev_attr_gpu_status
);
2149 #ifdef CONFIG_MALI_VK_BOOST
2150 device_remove_file(dev
, &dev_attr_vk_boost_status
);
2152 #ifdef CONFIG_MALI_SUSTAINABLE_OPT
2153 device_remove_file(dev
, &dev_attr_sustainable_status
);
2155 #ifdef CONFIG_MALI_SEC_CL_BOOST
2156 device_remove_file(dev
, &dev_attr_cl_boost_disable
);
2158 #ifdef CONFIG_MALI_DEBUG_KERNEL_SYSFS
2159 kobject_put(external_kobj
);