diff options
Diffstat (limited to 'drivers/devfreq/exynos/exynos_ppmu.c')
-rw-r--r-- | drivers/devfreq/exynos/exynos_ppmu.c | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/drivers/devfreq/exynos/exynos_ppmu.c b/drivers/devfreq/exynos/exynos_ppmu.c index 85fc5ac1036a..75fcc5140ffb 100644 --- a/drivers/devfreq/exynos/exynos_ppmu.c +++ b/drivers/devfreq/exynos/exynos_ppmu.c | |||
@@ -54,3 +54,63 @@ unsigned int exynos_ppmu_read(void __iomem *ppmu_base, unsigned int ch) | |||
54 | 54 | ||
55 | return total; | 55 | return total; |
56 | } | 56 | } |
57 | |||
58 | void busfreq_mon_reset(struct busfreq_ppmu_data *ppmu_data) | ||
59 | { | ||
60 | unsigned int i; | ||
61 | |||
62 | for (i = 0; i < ppmu_data->ppmu_end; i++) { | ||
63 | void __iomem *ppmu_base = ppmu_data->ppmu[i].hw_base; | ||
64 | |||
65 | /* Reset the performance and cycle counters */ | ||
66 | exynos_ppmu_reset(ppmu_base); | ||
67 | |||
68 | /* Setup count registers to monitor read/write transactions */ | ||
69 | ppmu_data->ppmu[i].event[PPMU_PMNCNT3] = RDWR_DATA_COUNT; | ||
70 | exynos_ppmu_setevent(ppmu_base, PPMU_PMNCNT3, | ||
71 | ppmu_data->ppmu[i].event[PPMU_PMNCNT3]); | ||
72 | |||
73 | exynos_ppmu_start(ppmu_base); | ||
74 | } | ||
75 | } | ||
76 | |||
77 | void exynos_read_ppmu(struct busfreq_ppmu_data *ppmu_data) | ||
78 | { | ||
79 | int i, j; | ||
80 | |||
81 | for (i = 0; i < ppmu_data->ppmu_end; i++) { | ||
82 | void __iomem *ppmu_base = ppmu_data->ppmu[i].hw_base; | ||
83 | |||
84 | exynos_ppmu_stop(ppmu_base); | ||
85 | |||
86 | /* Update local data from PPMU */ | ||
87 | ppmu_data->ppmu[i].ccnt = __raw_readl(ppmu_base + PPMU_CCNT); | ||
88 | |||
89 | for (j = PPMU_PMNCNT0; j < PPMU_PMNCNT_MAX; j++) { | ||
90 | if (ppmu_data->ppmu[i].event[j] == 0) | ||
91 | ppmu_data->ppmu[i].count[j] = 0; | ||
92 | else | ||
93 | ppmu_data->ppmu[i].count[j] = | ||
94 | exynos_ppmu_read(ppmu_base, j); | ||
95 | } | ||
96 | } | ||
97 | |||
98 | busfreq_mon_reset(ppmu_data); | ||
99 | } | ||
100 | |||
101 | int exynos_get_busier_ppmu(struct busfreq_ppmu_data *ppmu_data) | ||
102 | { | ||
103 | unsigned int count = 0; | ||
104 | int i, j, busy = 0; | ||
105 | |||
106 | for (i = 0; i < ppmu_data->ppmu_end; i++) { | ||
107 | for (j = PPMU_PMNCNT0; j < PPMU_PMNCNT_MAX; j++) { | ||
108 | if (ppmu_data->ppmu[i].count[j] > count) { | ||
109 | count = ppmu_data->ppmu[i].count[j]; | ||
110 | busy = i; | ||
111 | } | ||
112 | } | ||
113 | } | ||
114 | |||
115 | return busy; | ||
116 | } | ||