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
);
1179 start
= (start
+ 1) & KBASE_TRACE_MASK
;
1182 spin_unlock_irqrestore(&pkbdev
->trace_lock
, flags
);
1183 KBASE_TRACE_CLEAR(pkbdev
);
1185 if (ret
< PAGE_SIZE
- 1) {
1186 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
1188 buf
[PAGE_SIZE
-2] = '\n';
1189 buf
[PAGE_SIZE
-1] = '\0';
1196 static ssize_t
init_trace_dump(struct device
*dev
, struct device_attribute
*attr
, const char *buf
, size_t count
)
1198 KBASE_TRACE_CLEAR(pkbdev
);
1202 #endif /* CONFIG_MALI_EXYNOS_TRACE */
1205 static ssize_t
show_fbdev(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
1210 for (i
= 0; i
< num_registered_fb
; i
++)
1211 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
);
1213 if (ret
< PAGE_SIZE
- 1) {
1214 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
1216 buf
[PAGE_SIZE
-2] = '\n';
1217 buf
[PAGE_SIZE
-1] = '\0';
1225 static int gpu_get_status(struct exynos_context
*platform
, char *buf
, size_t buf_size
)
1229 int mmu_fault_cnt
= 0;
1237 for (i
= GPU_MMU_TRANSLATION_FAULT
; i
<= GPU_MMU_MEMORY_ATTRIBUTES_FAULT
; i
++)
1238 mmu_fault_cnt
+= platform
->gpu_exception_count
[i
];
1240 cnt
+= snprintf(buf
+cnt
, buf_size
-cnt
, "reset count : %d\n", platform
->gpu_exception_count
[GPU_RESET
]);
1241 cnt
+= snprintf(buf
+cnt
, buf_size
-cnt
, "data invalid count : %d\n", platform
->gpu_exception_count
[GPU_DATA_INVALIDATE_FAULT
]);
1242 cnt
+= snprintf(buf
+cnt
, buf_size
-cnt
, "mmu fault count : %d\n", mmu_fault_cnt
);
1244 for (i
= 0; i
< BMAX_RETRY_CNT
; i
++)
1245 cnt
+= snprintf(buf
+cnt
, buf_size
-cnt
, "warmup retry count %d : %d\n", i
+1, platform
->balance_retry_count
[i
]);
1250 static ssize_t
show_gpu_status(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
1253 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
1258 ret
+= gpu_get_status(platform
, buf
+ret
, (size_t)PAGE_SIZE
-ret
);
1260 if (ret
< PAGE_SIZE
- 1) {
1261 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
1263 buf
[PAGE_SIZE
-2] = '\n';
1264 buf
[PAGE_SIZE
-1] = '\0';
1271 #ifdef CONFIG_MALI_VK_BOOST
1272 static ssize_t
show_vk_boost_status(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
1275 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
1280 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "%d", platform
->ctx_vk_need_qos
);
1282 if (ret
< PAGE_SIZE
- 1) {
1283 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
1285 buf
[PAGE_SIZE
-2] = '\n';
1286 buf
[PAGE_SIZE
-1] = '\0';
1294 #ifdef CONFIG_MALI_SUSTAINABLE_OPT
1295 static ssize_t
show_sustainable_status(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
1298 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
1303 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "%d", platform
->sustainable
.status
);
1305 if (ret
< PAGE_SIZE
- 1) {
1306 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
1308 buf
[PAGE_SIZE
-2] = '\n';
1309 buf
[PAGE_SIZE
-1] = '\0';
1317 #ifdef CONFIG_MALI_SEC_CL_BOOST
1318 static ssize_t
set_cl_boost_disable(struct device
*dev
, struct device_attribute
*attr
, const char *buf
, size_t count
)
1320 unsigned int cl_boost_disable
= 0;
1323 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
1328 ret
= kstrtoint(buf
, 0, &cl_boost_disable
);
1330 GPU_LOG(DVFS_WARNING
, DUMMY
, 0u, 0u, "%s: invalid value\n", __func__
);
1334 if (cl_boost_disable
== 0)
1335 platform
->cl_boost_disable
= false;
1337 platform
->cl_boost_disable
= true;
1342 static ssize_t
show_cl_boost_disable(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
1345 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
1350 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "%d", platform
->cl_boost_disable
);
1352 if (ret
< PAGE_SIZE
- 1) {
1353 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
1355 buf
[PAGE_SIZE
-2] = '\n';
1356 buf
[PAGE_SIZE
-1] = '\0';
1363 /** The sysfs file @c clock, fbdev.
1365 * This is used for obtaining information about the mali t series operating clock & framebuffer address,
1368 DEVICE_ATTR(clock
, S_IRUGO
|S_IWUSR
, show_clock
, set_clock
);
1369 DEVICE_ATTR(vol
, S_IRUGO
, show_vol
, NULL
);
1370 DEVICE_ATTR(power_state
, S_IRUGO
, show_power_state
, NULL
);
1371 DEVICE_ATTR(asv_table
, S_IRUGO
, show_asv_table
, NULL
);
1372 DEVICE_ATTR(dvfs_table
, S_IRUGO
, show_dvfs_table
, NULL
);
1373 DEVICE_ATTR(time_in_state
, S_IRUGO
|S_IWUSR
, show_time_in_state
, set_time_in_state
);
1374 DEVICE_ATTR(utilization
, S_IRUGO
, show_utilization
, NULL
);
1375 DEVICE_ATTR(perf
, S_IRUGO
, show_perf
, NULL
);
1376 #ifdef CONFIG_MALI_DVFS
1377 DEVICE_ATTR(dvfs
, S_IRUGO
|S_IWUSR
, show_dvfs
, set_dvfs
);
1378 DEVICE_ATTR(dvfs_governor
, S_IRUGO
|S_IWUSR
, show_governor
, set_governor
);
1379 DEVICE_ATTR(dvfs_max_lock_status
, S_IRUGO
, show_max_lock_status
, NULL
);
1380 DEVICE_ATTR(dvfs_min_lock_status
, S_IRUGO
, show_min_lock_status
, NULL
);
1381 DEVICE_ATTR(dvfs_max_lock
, S_IRUGO
|S_IWUSR
, show_max_lock_dvfs
, set_max_lock_dvfs
);
1382 DEVICE_ATTR(dvfs_min_lock
, S_IRUGO
|S_IWUSR
, show_min_lock_dvfs
, set_min_lock_dvfs
);
1383 DEVICE_ATTR(down_staycount
, S_IRUGO
|S_IWUSR
, show_down_staycount
, set_down_staycount
);
1384 DEVICE_ATTR(highspeed_clock
, S_IRUGO
|S_IWUSR
, show_highspeed_clock
, set_highspeed_clock
);
1385 DEVICE_ATTR(highspeed_load
, S_IRUGO
|S_IWUSR
, show_highspeed_load
, set_highspeed_load
);
1386 DEVICE_ATTR(highspeed_delay
, S_IRUGO
|S_IWUSR
, show_highspeed_delay
, set_highspeed_delay
);
1387 DEVICE_ATTR(wakeup_lock
, S_IRUGO
|S_IWUSR
, show_wakeup_lock
, set_wakeup_lock
);
1388 DEVICE_ATTR(polling_speed
, S_IRUGO
|S_IWUSR
, show_polling_speed
, set_polling_speed
);
1389 DEVICE_ATTR(tmu
, S_IRUGO
|S_IWUSR
, show_tmu
, set_tmu_control
);
1390 #ifdef CONFIG_CPU_THERMAL_IPA
1391 DEVICE_ATTR(norm_utilization
, S_IRUGO
, show_norm_utilization
, NULL
);
1392 DEVICE_ATTR(utilization_stats
, S_IRUGO
, show_utilization_stats
, NULL
);
1393 #endif /* CONFIG_CPU_THERMAL_IPA */
1394 #endif /* CONFIG_MALI_DVFS */
1395 DEVICE_ATTR(debug_level
, S_IRUGO
|S_IWUSR
, show_debug_level
, set_debug_level
);
1396 #ifdef CONFIG_MALI_EXYNOS_TRACE
1397 DEVICE_ATTR(trace_level
, S_IRUGO
|S_IWUSR
, show_trace_level
, set_trace_level
);
1398 DEVICE_ATTR(trace_dump
, S_IRUGO
|S_IWUSR
, show_trace_dump
, init_trace_dump
);
1399 #endif /* CONFIG_MALI_EXYNOS_TRACE */
1401 DEVICE_ATTR(fbdev
, S_IRUGO
, show_fbdev
, NULL
);
1403 DEVICE_ATTR(gpu_status
, S_IRUGO
, show_gpu_status
, NULL
);
1404 #ifdef CONFIG_MALI_VK_BOOST
1405 DEVICE_ATTR(vk_boost_status
, S_IRUGO
, show_vk_boost_status
, NULL
);
1407 #ifdef CONFIG_MALI_SUSTAINABLE_OPT
1408 DEVICE_ATTR(sustainable_status
, S_IRUGO
, show_sustainable_status
, NULL
);
1410 #ifdef CONFIG_MALI_SEC_CL_BOOST
1411 DEVICE_ATTR(cl_boost_disable
, S_IRUGO
|S_IWUSR
, show_cl_boost_disable
, set_cl_boost_disable
);
1414 #ifdef CONFIG_MALI_DEBUG_KERNEL_SYSFS
1415 #ifdef CONFIG_MALI_DVFS
1416 #define BUF_SIZE 1000
1417 static ssize_t
show_kernel_sysfs_gpu_info(struct kobject
*kobj
, struct kobj_attribute
*attr
, char *buf
)
1419 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
1428 ret
+= snprintf(buf
+ret
, BUF_SIZE
-ret
, "\"SSTOP\":\"%d\",", platform
->gpu_exception_count
[GPU_SOFT_STOP
]);
1429 ret
+= snprintf(buf
+ret
, BUF_SIZE
-ret
, "\"HSTOP\":\"%d\",", platform
->gpu_exception_count
[GPU_HARD_STOP
]);
1430 ret
+= snprintf(buf
+ret
, BUF_SIZE
-ret
, "\"RESET\":\"%d\",", platform
->gpu_exception_count
[GPU_RESET
]);
1431 ret
+= snprintf(buf
+ret
, BUF_SIZE
-ret
, "\"DIFLT\":\"%d\",", platform
->gpu_exception_count
[GPU_DATA_INVALIDATE_FAULT
]);
1432 ret
+= snprintf(buf
+ret
, BUF_SIZE
-ret
, "\"TRFLT\":\"%d\",", platform
->gpu_exception_count
[GPU_MMU_TRANSLATION_FAULT
]);
1433 ret
+= snprintf(buf
+ret
, BUF_SIZE
-ret
, "\"PMFLT\":\"%d\",", platform
->gpu_exception_count
[GPU_MMU_PERMISSION_FAULT
]);
1434 ret
+= snprintf(buf
+ret
, BUF_SIZE
-ret
, "\"BFLT\":\"%d\",", platform
->gpu_exception_count
[GPU_MMU_TRANSTAB_BUS_FAULT
]);
1435 ret
+= snprintf(buf
+ret
, BUF_SIZE
-ret
, "\"ACCFG\":\"%d\",", platform
->gpu_exception_count
[GPU_MMU_ACCESS_FLAG_FAULT
]);
1436 ret
+= snprintf(buf
+ret
, BUF_SIZE
-ret
, "\"ASFLT\":\"%d\",", platform
->gpu_exception_count
[GPU_MMU_ADDRESS_SIZE_FAULT
]);
1437 ret
+= snprintf(buf
+ret
, BUF_SIZE
-ret
, "\"ATFLT\":\"%d\",", platform
->gpu_exception_count
[GPU_MMU_MEMORY_ATTRIBUTES_FAULT
]);
1438 ret
+= snprintf(buf
+ret
, BUF_SIZE
-ret
, "\"UNKN\":\"%d\"", platform
->gpu_exception_count
[GPU_UNKNOWN
]);
1440 if (ret
< PAGE_SIZE
- 1) {
1441 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
1443 buf
[PAGE_SIZE
-2] = '\n';
1444 buf
[PAGE_SIZE
-1] = '\0';
1451 static ssize_t
show_kernel_sysfs_max_lock_dvfs(struct kobject
*kobj
, struct kobj_attribute
*attr
, char *buf
)
1454 unsigned long flags
;
1455 int locked_clock
= -1;
1456 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
1461 spin_lock_irqsave(&platform
->gpu_dvfs_spinlock
, flags
);
1462 locked_clock
= platform
->max_lock
;
1463 spin_unlock_irqrestore(&platform
->gpu_dvfs_spinlock
, flags
);
1465 if (locked_clock
> 0)
1466 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "%d", locked_clock
);
1468 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "%d", platform
->gpu_max_clock
);
1470 if (ret
< PAGE_SIZE
- 1) {
1471 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
1473 buf
[PAGE_SIZE
-2] = '\n';
1474 buf
[PAGE_SIZE
-1] = '\0';
1481 static ssize_t
set_kernel_sysfs_max_lock_dvfs(struct kobject
*kobj
, struct kobj_attribute
*attr
, const char *buf
, size_t count
)
1484 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
1489 if (sysfs_streq("0", buf
)) {
1490 platform
->user_max_lock_input
= 0;
1491 gpu_dvfs_clock_lock(GPU_DVFS_MAX_UNLOCK
, SYSFS_LOCK
, 0);
1493 ret
= kstrtoint(buf
, 0, &clock
);
1495 GPU_LOG(DVFS_WARNING
, DUMMY
, 0u, 0u, "%s: invalid value\n", __func__
);
1499 platform
->user_max_lock_input
= clock
;
1501 clock
= gpu_dvfs_get_level_clock(clock
);
1503 ret
= gpu_dvfs_get_level(clock
);
1504 if ((ret
< gpu_dvfs_get_level(platform
->gpu_max_clock
)) || (ret
> gpu_dvfs_get_level(platform
->gpu_min_clock
))) {
1505 GPU_LOG(DVFS_WARNING
, DUMMY
, 0u, 0u, "%s: invalid clock value (%d)\n", __func__
, clock
);
1509 if (clock
== platform
->gpu_max_clock
)
1510 gpu_dvfs_clock_lock(GPU_DVFS_MAX_UNLOCK
, SYSFS_LOCK
, 0);
1512 gpu_dvfs_clock_lock(GPU_DVFS_MAX_LOCK
, SYSFS_LOCK
, clock
);
1518 static ssize_t
show_kernel_sysfs_available_governor(struct kobject
*kobj
, struct kobj_attribute
*attr
, char *buf
)
1521 gpu_dvfs_governor_info
*governor_info
;
1523 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
1528 governor_info
= (gpu_dvfs_governor_info
*)gpu_dvfs_get_governor_info();
1530 for (i
= 0; i
< G3D_MAX_GOVERNOR_NUM
; i
++)
1531 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "%s ", governor_info
[i
].name
);
1533 if (ret
< PAGE_SIZE
- 1) {
1534 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
1536 buf
[PAGE_SIZE
-2] = '\n';
1537 buf
[PAGE_SIZE
-1] = '\0';
1544 static ssize_t
show_kernel_sysfs_min_lock_dvfs(struct kobject
*kobj
, struct kobj_attribute
*attr
, char *buf
)
1547 unsigned long flags
;
1548 int locked_clock
= -1;
1549 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
1554 spin_lock_irqsave(&platform
->gpu_dvfs_spinlock
, flags
);
1555 locked_clock
= platform
->min_lock
;
1556 spin_unlock_irqrestore(&platform
->gpu_dvfs_spinlock
, flags
);
1558 if (locked_clock
> 0)
1559 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "%d", locked_clock
);
1561 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "%d", platform
->gpu_min_clock
);
1563 if (ret
< PAGE_SIZE
- 1) {
1564 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
1566 buf
[PAGE_SIZE
-2] = '\n';
1567 buf
[PAGE_SIZE
-1] = '\0';
1574 static ssize_t
set_kernel_sysfs_min_lock_dvfs(struct kobject
*kobj
, struct kobj_attribute
*attr
, const char *buf
, size_t count
)
1577 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
1582 if (sysfs_streq("0", buf
)) {
1583 platform
->user_min_lock_input
= 0;
1584 gpu_dvfs_clock_lock(GPU_DVFS_MIN_UNLOCK
, SYSFS_LOCK
, 0);
1586 ret
= kstrtoint(buf
, 0, &clock
);
1588 GPU_LOG(DVFS_WARNING
, DUMMY
, 0u, 0u, "%s: invalid value\n", __func__
);
1592 platform
->user_min_lock_input
= clock
;
1594 clock
= gpu_dvfs_get_level_clock(clock
);
1596 ret
= gpu_dvfs_get_level(clock
);
1597 if ((ret
< gpu_dvfs_get_level(platform
->gpu_max_clock
)) || (ret
> gpu_dvfs_get_level(platform
->gpu_min_clock
))) {
1598 GPU_LOG(DVFS_WARNING
, DUMMY
, 0u, 0u, "%s: invalid clock value (%d)\n", __func__
, clock
);
1602 if (clock
> platform
->gpu_max_clock_limit
)
1603 clock
= platform
->gpu_max_clock_limit
;
1605 if (clock
== platform
->gpu_min_clock
)
1606 gpu_dvfs_clock_lock(GPU_DVFS_MIN_UNLOCK
, SYSFS_LOCK
, 0);
1608 gpu_dvfs_clock_lock(GPU_DVFS_MIN_LOCK
, SYSFS_LOCK
, clock
);
1613 #endif /* #ifdef CONFIG_MALI_DVFS */
1615 static ssize_t
show_kernel_sysfs_utilization(struct kobject
*kobj
, struct kobj_attribute
*attr
, char *buf
)
1618 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
1623 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "%3d%%", platform
->env_data
.utilization
);
1625 if (ret
< PAGE_SIZE
- 1) {
1626 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
1628 buf
[PAGE_SIZE
-2] = '\n';
1629 buf
[PAGE_SIZE
-1] = '\0';
1636 static ssize_t
show_kernel_sysfs_clock(struct kobject
*kobj
, struct kobj_attribute
*attr
, char *buf
)
1640 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
1645 #ifdef CONFIG_MALI_RT_PM
1646 if (platform
->exynos_pm_domain
) {
1647 mutex_lock(&platform
->exynos_pm_domain
->access_lock
);
1648 if (!platform
->dvs_is_enabled
&& gpu_is_power_on())
1649 clock
= gpu_get_cur_clock(platform
);
1650 mutex_unlock(&platform
->exynos_pm_domain
->access_lock
);
1653 if (gpu_control_is_power_on(pkbdev
) == 1) {
1654 mutex_lock(&platform
->gpu_clock_lock
);
1655 if (!platform
->dvs_is_enabled
)
1656 clock
= gpu_get_cur_clock(platform
);
1657 mutex_unlock(&platform
->gpu_clock_lock
);
1661 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "%d", clock
);
1663 if (ret
< PAGE_SIZE
- 1) {
1664 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
1666 buf
[PAGE_SIZE
-2] = '\n';
1667 buf
[PAGE_SIZE
-1] = '\0';
1674 static ssize_t
show_kernel_sysfs_freq_table(struct kobject
*kobj
, struct kobj_attribute
*attr
, char *buf
)
1678 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
1683 for (i
= gpu_dvfs_get_level(platform
->gpu_min_clock
); i
>= gpu_dvfs_get_level(platform
->gpu_max_clock
); i
--) {
1684 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "%d ", platform
->table
[i
].clock
);
1687 if (ret
< PAGE_SIZE
- 1) {
1688 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
1690 buf
[PAGE_SIZE
-2] = '\n';
1691 buf
[PAGE_SIZE
-1] = '\0';
1698 #ifdef CONFIG_MALI_DVFS
1699 static ssize_t
show_kernel_sysfs_governor(struct kobject
*kobj
, struct kobj_attribute
*attr
, char *buf
)
1702 gpu_dvfs_governor_info
*governor_info
= NULL
;
1703 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
1708 governor_info
= (gpu_dvfs_governor_info
*)gpu_dvfs_get_governor_info();
1710 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "%s", governor_info
[platform
->governor_type
].name
);
1712 if (ret
< PAGE_SIZE
- 1) {
1713 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
1715 buf
[PAGE_SIZE
-2] = '\n';
1716 buf
[PAGE_SIZE
-1] = '\0';
1723 static ssize_t
set_kernel_sysfs_governor(struct kobject
*kobj
, struct kobj_attribute
*attr
, const char *buf
, size_t count
)
1727 int next_governor_type
= -1;
1728 size_t governor_name_size
= 0;
1729 gpu_dvfs_governor_info
*governor_info
= NULL
;
1730 struct exynos_context
*platform
= (struct exynos_context
*)pkbdev
->platform_context
;
1735 governor_info
= (gpu_dvfs_governor_info
*)gpu_dvfs_get_governor_info();
1737 for (i
= 0; i
< G3D_MAX_GOVERNOR_NUM
; i
++) {
1738 governor_name_size
= strlen(governor_info
[i
].name
);
1739 if (!strncmp(buf
, governor_info
[i
].name
, governor_name_size
)) {
1740 next_governor_type
= i
;
1745 if ((next_governor_type
< 0) || (next_governor_type
>= G3D_MAX_GOVERNOR_NUM
)) {
1746 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "%s: invalid value\n", __func__
);
1750 ret
= gpu_dvfs_governor_change(next_governor_type
);
1753 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u,
1754 "%s: fail to set the new governor (%d)\n", __func__
, next_governor_type
);
1760 #endif /* #ifdef CONFIG_MALI_DVFS */
1762 static ssize_t
show_kernel_sysfs_gpu_model(struct kobject
*kobj
, struct kobj_attribute
*attr
, char *buf
)
1764 /* COPY from mali_kbase_core_linux.c : 2594 line, last updated: 20161017, r2p0-03rel0 */
1765 static const struct gpu_product_id_name
{
1768 } gpu_product_id_names
[] = {
1769 { .id
= GPU_ID_PI_T60X
, .name
= "Mali-T60x" },
1770 { .id
= GPU_ID_PI_T62X
, .name
= "Mali-T62x" },
1771 { .id
= GPU_ID_PI_T72X
, .name
= "Mali-T72x" },
1772 { .id
= GPU_ID_PI_T76X
, .name
= "Mali-T76x" },
1773 { .id
= GPU_ID_PI_T82X
, .name
= "Mali-T82x" },
1774 { .id
= GPU_ID_PI_T83X
, .name
= "Mali-T83x" },
1775 { .id
= GPU_ID_PI_T86X
, .name
= "Mali-T86x" },
1776 { .id
= GPU_ID_PI_TFRX
, .name
= "Mali-T88x" },
1777 { .id
= GPU_ID2_PRODUCT_TMIX
>> GPU_ID_VERSION_PRODUCT_ID_SHIFT
,
1778 .name
= "Mali-G71" },
1779 { .id
= GPU_ID2_PRODUCT_THEX
>> GPU_ID_VERSION_PRODUCT_ID_SHIFT
,
1780 .name
= "Mali-THEx" },
1782 const char *product_name
= "(Unknown Mali GPU)";
1783 struct kbase_device
*kbdev
;
1785 unsigned product_id
, product_id_mask
;
1793 gpu_id
= kbdev
->gpu_props
.props
.raw_props
.gpu_id
;
1794 product_id
= gpu_id
>> GPU_ID_VERSION_PRODUCT_ID_SHIFT
;
1795 is_new_format
= GPU_ID_IS_NEW_FORMAT(product_id
);
1798 GPU_ID2_PRODUCT_MODEL
:
1799 GPU_ID_VERSION_PRODUCT_ID
) >>
1800 GPU_ID_VERSION_PRODUCT_ID_SHIFT
;
1802 for (i
= 0; i
< ARRAY_SIZE(gpu_product_id_names
); ++i
) {
1803 const struct gpu_product_id_name
*p
= &gpu_product_id_names
[i
];
1805 if ((GPU_ID_IS_NEW_FORMAT(p
->id
) == is_new_format
) &&
1806 (p
->id
& product_id_mask
) ==
1807 (product_id
& product_id_mask
)) {
1808 product_name
= p
->name
;
1813 return scnprintf(buf
, PAGE_SIZE
, "%s\n", product_name
);
1816 #if defined(CONFIG_MALI_DVFS) && defined(CONFIG_EXYNOS_THERMAL) && defined(CONFIG_GPU_THERMAL)
1818 extern struct exynos_tmu_data
*gpu_thermal_data
;
1820 static ssize_t
show_kernel_sysfs_gpu_temp(struct kobject
*kobj
, struct kobj_attribute
*attr
, char *buf
)
1824 int gpu_temp_int
= 0;
1825 int gpu_temp_point
= 0;
1828 if (!gpu_thermal_data
) {
1829 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "[Kernel group SYSFS] thermal driver does not ready\n");
1833 mutex_lock(&gpu_thermal_data
->lock
);
1835 if (gpu_thermal_data
->num_of_sensors
)
1836 gpu_temp
= gpu_thermal_data
->tmu_read(gpu_thermal_data
) * MCELSIUS
;
1838 mutex_unlock(&gpu_thermal_data
->lock
);
1840 gpu_temp_int
= gpu_temp
/ 1000;
1841 gpu_temp_point
= gpu_temp
% gpu_temp_int
;
1842 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "%d.%d", gpu_temp_int
, gpu_temp_point
);
1844 if (ret
< PAGE_SIZE
- 1) {
1845 ret
+= snprintf(buf
+ret
, PAGE_SIZE
-ret
, "\n");
1847 buf
[PAGE_SIZE
-2] = '\n';
1848 buf
[PAGE_SIZE
-1] = '\0';
1855 static struct kobj_attribute gpu_temp_attribute
=
1856 __ATTR(gpu_tmu
, S_IRUGO
, show_kernel_sysfs_gpu_temp
, NULL
);
1859 #ifdef CONFIG_MALI_DVFS
1860 static struct kobj_attribute gpu_info_attribute
=
1861 __ATTR(gpu_info
, S_IRUGO
, show_kernel_sysfs_gpu_info
, NULL
);
1863 static struct kobj_attribute gpu_max_lock_attribute
=
1864 __ATTR(gpu_max_clock
, S_IRUGO
|S_IWUSR
, show_kernel_sysfs_max_lock_dvfs
, set_kernel_sysfs_max_lock_dvfs
);
1866 static struct kobj_attribute gpu_min_lock_attribute
=
1867 __ATTR(gpu_min_clock
, S_IRUGO
|S_IWUSR
, show_kernel_sysfs_min_lock_dvfs
, set_kernel_sysfs_min_lock_dvfs
);
1868 #endif /* #ifdef CONFIG_MALI_DVFS */
1870 static struct kobj_attribute gpu_busy_attribute
=
1871 __ATTR(gpu_busy
, S_IRUGO
, show_kernel_sysfs_utilization
, NULL
);
1873 static struct kobj_attribute gpu_clock_attribute
=
1874 __ATTR(gpu_clock
, S_IRUGO
, show_kernel_sysfs_clock
, NULL
);
1876 static struct kobj_attribute gpu_freq_table_attribute
=
1877 __ATTR(gpu_freq_table
, S_IRUGO
, show_kernel_sysfs_freq_table
, NULL
);
1879 #ifdef CONFIG_MALI_DVFS
1880 static struct kobj_attribute gpu_governor_attribute
=
1881 __ATTR(gpu_governor
, S_IRUGO
|S_IWUSR
, show_kernel_sysfs_governor
, set_kernel_sysfs_governor
);
1883 static struct kobj_attribute gpu_available_governor_attribute
=
1884 __ATTR(gpu_available_governor
, S_IRUGO
, show_kernel_sysfs_available_governor
, NULL
);
1885 #endif /* #ifdef CONFIG_MALI_DVFS */
1887 static struct kobj_attribute gpu_model_attribute
=
1888 __ATTR(gpu_model
, S_IRUGO
, show_kernel_sysfs_gpu_model
, NULL
);
1891 static struct attribute
*attrs
[] = {
1892 #ifdef CONFIG_MALI_DVFS
1893 #if defined(CONFIG_EXYNOS_THERMAL) && defined(CONFIG_GPU_THERMAL)
1894 &gpu_temp_attribute
.attr
,
1896 &gpu_info_attribute
.attr
,
1897 &gpu_max_lock_attribute
.attr
,
1898 &gpu_min_lock_attribute
.attr
,
1899 #endif /* #ifdef CONFIG_MALI_DVFS */
1900 &gpu_busy_attribute
.attr
,
1901 &gpu_clock_attribute
.attr
,
1902 &gpu_freq_table_attribute
.attr
,
1903 #ifdef CONFIG_MALI_DVFS
1904 &gpu_governor_attribute
.attr
,
1905 &gpu_available_governor_attribute
.attr
,
1906 #endif /* #ifdef CONFIG_MALI_DVFS */
1907 &gpu_model_attribute
.attr
,
1911 static struct attribute_group attr_group
= {
1914 static struct kobject
*external_kobj
;
1917 int gpu_create_sysfs_file(struct device
*dev
)
1919 #ifdef CONFIG_MALI_DEBUG_KERNEL_SYSFS
1923 if (device_create_file(dev
, &dev_attr_clock
)) {
1924 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [clock]\n");
1928 if (device_create_file(dev
, &dev_attr_vol
)) {
1929 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [vol]\n");
1933 if (device_create_file(dev
, &dev_attr_power_state
)) {
1934 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [power_state]\n");
1938 if (device_create_file(dev
, &dev_attr_asv_table
)) {
1939 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [asv_table]\n");
1943 if (device_create_file(dev
, &dev_attr_dvfs_table
)) {
1944 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [dvfs_table]\n");
1948 if (device_create_file(dev
, &dev_attr_time_in_state
)) {
1949 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [time_in_state]\n");
1953 if (device_create_file(dev
, &dev_attr_utilization
)) {
1954 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [utilization]\n");
1958 if (device_create_file(dev
, &dev_attr_perf
)) {
1959 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [perf]\n");
1962 #ifdef CONFIG_MALI_DVFS
1963 if (device_create_file(dev
, &dev_attr_dvfs
)) {
1964 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [dvfs]\n");
1968 if (device_create_file(dev
, &dev_attr_dvfs_governor
)) {
1969 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [dvfs_governor]\n");
1973 if (device_create_file(dev
, &dev_attr_dvfs_max_lock_status
)) {
1974 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [dvfs_max_lock_status]\n");
1978 if (device_create_file(dev
, &dev_attr_dvfs_min_lock_status
)) {
1979 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [dvfs_min_lock_status]\n");
1983 if (device_create_file(dev
, &dev_attr_dvfs_max_lock
)) {
1984 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [dvfs_max_lock]\n");
1988 if (device_create_file(dev
, &dev_attr_dvfs_min_lock
)) {
1989 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [dvfs_min_lock]\n");
1993 if (device_create_file(dev
, &dev_attr_down_staycount
)) {
1994 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [down_staycount]\n");
1998 if (device_create_file(dev
, &dev_attr_highspeed_clock
)) {
1999 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [highspeed_clock]\n");
2003 if (device_create_file(dev
, &dev_attr_highspeed_load
)) {
2004 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [highspeed_load]\n");
2008 if (device_create_file(dev
, &dev_attr_highspeed_delay
)) {
2009 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [highspeed_delay]\n");
2013 if (device_create_file(dev
, &dev_attr_wakeup_lock
)) {
2014 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [wakeup_lock]\n");
2018 if (device_create_file(dev
, &dev_attr_polling_speed
)) {
2019 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [polling_speed]\n");
2023 if (device_create_file(dev
, &dev_attr_tmu
)) {
2024 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [tmu]\n");
2027 #ifdef CONFIG_CPU_THERMAL_IPA
2028 if (device_create_file(dev
, &dev_attr_norm_utilization
)) {
2029 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [norm_utilization]\n");
2033 if (device_create_file(dev
, &dev_attr_utilization_stats
)) {
2034 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [utilization_stats]\n");
2037 #endif /* CONFIG_CPU_THERMAL_IPA */
2038 #endif /* CONFIG_MALI_DVFS */
2039 if (device_create_file(dev
, &dev_attr_debug_level
)) {
2040 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [debug_level]\n");
2043 #ifdef CONFIG_MALI_EXYNOS_TRACE
2044 if (device_create_file(dev
, &dev_attr_trace_level
)) {
2045 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [trace_level]\n");
2049 if (device_create_file(dev
, &dev_attr_trace_dump
)) {
2050 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [trace_dump]\n");
2053 #endif /* CONFIG_MALI_EXYNOS_TRACE */
2055 if (device_create_file(dev
, &dev_attr_fbdev
)) {
2056 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [fbdev]\n");
2061 if (device_create_file(dev
, &dev_attr_gpu_status
)) {
2062 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [gpu_status]\n");
2066 #ifdef CONFIG_MALI_VK_BOOST
2067 if (device_create_file(dev
, &dev_attr_vk_boost_status
)) {
2068 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [vk_boost_status]\n");
2073 #ifdef CONFIG_MALI_SUSTAINABLE_OPT
2074 if (device_create_file(dev
, &dev_attr_sustainable_status
)) {
2075 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [sustainable_status]\n");
2080 #ifdef CONFIG_MALI_SEC_CL_BOOST
2081 if (device_create_file(dev
, &dev_attr_cl_boost_disable
)) {
2082 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create sysfs file [cl_boost_disable]\n");
2087 #ifdef CONFIG_MALI_DEBUG_KERNEL_SYSFS
2088 external_kobj
= kobject_create_and_add("gpu", kernel_kobj
);
2089 if (!external_kobj
) {
2090 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't create Kobj for group [KERNEL - GPU]\n");
2094 retval
= sysfs_create_group(external_kobj
, &attr_group
);
2096 kobject_put(external_kobj
);
2097 GPU_LOG(DVFS_ERROR
, DUMMY
, 0u, 0u, "couldn't add sysfs group [KERNEL - GPU]\n");
2107 void gpu_remove_sysfs_file(struct device
*dev
)
2109 device_remove_file(dev
, &dev_attr_clock
);
2110 device_remove_file(dev
, &dev_attr_vol
);
2111 device_remove_file(dev
, &dev_attr_power_state
);
2112 device_remove_file(dev
, &dev_attr_asv_table
);
2113 device_remove_file(dev
, &dev_attr_dvfs_table
);
2114 device_remove_file(dev
, &dev_attr_time_in_state
);
2115 device_remove_file(dev
, &dev_attr_utilization
);
2116 device_remove_file(dev
, &dev_attr_perf
);
2117 #ifdef CONFIG_MALI_DVFS
2118 device_remove_file(dev
, &dev_attr_dvfs
);
2119 device_remove_file(dev
, &dev_attr_dvfs_governor
);
2120 device_remove_file(dev
, &dev_attr_dvfs_max_lock_status
);
2121 device_remove_file(dev
, &dev_attr_dvfs_min_lock_status
);
2122 device_remove_file(dev
, &dev_attr_dvfs_max_lock
);
2123 device_remove_file(dev
, &dev_attr_dvfs_min_lock
);
2124 device_remove_file(dev
, &dev_attr_down_staycount
);
2125 device_remove_file(dev
, &dev_attr_highspeed_clock
);
2126 device_remove_file(dev
, &dev_attr_highspeed_load
);
2127 device_remove_file(dev
, &dev_attr_highspeed_delay
);
2128 device_remove_file(dev
, &dev_attr_wakeup_lock
);
2129 device_remove_file(dev
, &dev_attr_polling_speed
);
2130 device_remove_file(dev
, &dev_attr_tmu
);
2131 #ifdef CONFIG_CPU_THERMAL_IPA
2132 device_remove_file(dev
, &dev_attr_norm_utilization
);
2133 device_remove_file(dev
, &dev_attr_utilization_stats
);
2134 #endif /* CONFIG_CPU_THERMAL_IPA */
2135 #endif /* CONFIG_MALI_DVFS */
2136 device_remove_file(dev
, &dev_attr_debug_level
);
2137 #ifdef CONFIG_MALI_EXYNOS_TRACE
2138 device_remove_file(dev
, &dev_attr_trace_level
);
2139 device_remove_file(dev
, &dev_attr_trace_dump
);
2140 #endif /* CONFIG_MALI_EXYNOS_TRACE */
2142 device_remove_file(dev
, &dev_attr_fbdev
);
2144 device_remove_file(dev
, &dev_attr_gpu_status
);
2145 #ifdef CONFIG_MALI_VK_BOOST
2146 device_remove_file(dev
, &dev_attr_vk_boost_status
);
2148 #ifdef CONFIG_MALI_SUSTAINABLE_OPT
2149 device_remove_file(dev
, &dev_attr_sustainable_status
);
2151 #ifdef CONFIG_MALI_SEC_CL_BOOST
2152 device_remove_file(dev
, &dev_attr_cl_boost_disable
);
2154 #ifdef CONFIG_MALI_DEBUG_KERNEL_SYSFS
2155 kobject_put(external_kobj
);