6ac97eb7937c65e9fd9552aae4348c292e2ad624
[firefly-linux-kernel-4.4.55.git] / drivers / gpu / arm / midgard_for_linux / mali_kbase_ipa.c
1 /*
2  *
3  * (C) COPYRIGHT 2015 ARM Limited. All rights reserved.
4  *
5  * This program is free software and is provided to you under the terms of the
6  * GNU General Public License version 2 as published by the Free Software
7  * Foundation, and any use by you of this program is subject to the terms
8  * of such GNU licence.
9  *
10  * A copy of the licence is included with the program, and can also be obtained
11  * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
12  * Boston, MA  02110-1301, USA.
13  *
14  */
15
16
17 #include <linux/of.h>
18 #include <linux/sysfs.h>
19
20 #include <mali_kbase.h>
21
22 #define NR_IPA_GROUPS 8
23
24 struct kbase_ipa_context;
25
26 /**
27  * struct ipa_group - represents a single IPA group
28  * @name:               name of the IPA group
29  * @capacitance:        capacitance constant for IPA group
30  * @calc_power:         function to calculate power for IPA group
31  */
32 struct ipa_group {
33         const char *name;
34         u32 capacitance;
35         u32 (*calc_power)(struct kbase_ipa_context *,
36                         struct ipa_group *);
37 };
38
39 #include <mali_kbase_ipa_tables.h>
40
41 /**
42  * struct kbase_ipa_context - IPA context per device
43  * @kbdev:              pointer to kbase device
44  * @groups:             array of IPA groups for this context
45  * @vinstr_cli:         vinstr client handle
46  * @vinstr_buffer:      buffer to dump hardware counters onto
47  * @ipa_lock:           protects the entire IPA context
48  */
49 struct kbase_ipa_context {
50         struct kbase_device *kbdev;
51         struct ipa_group groups[NR_IPA_GROUPS];
52         struct kbase_vinstr_client *vinstr_cli;
53         void *vinstr_buffer;
54         struct mutex ipa_lock;
55 };
56
57 static ssize_t show_ipa_group(struct device *dev,
58                 struct device_attribute *attr,
59                 char *buf)
60 {
61         struct kbase_device *kbdev = dev_get_drvdata(dev);
62         struct kbase_ipa_context *ctx = kbdev->ipa_ctx;
63         ssize_t count = -EINVAL;
64         size_t i;
65
66         mutex_lock(&ctx->ipa_lock);
67         for (i = 0; i < ARRAY_SIZE(ctx->groups); i++) {
68                 if (!strcmp(ctx->groups[i].name, attr->attr.name)) {
69                         count = snprintf(buf, PAGE_SIZE, "%lu\n",
70                                 (unsigned long)ctx->groups[i].capacitance);
71                         break;
72                 }
73         }
74         mutex_unlock(&ctx->ipa_lock);
75         return count;
76 }
77
78 static ssize_t set_ipa_group(struct device *dev,
79                 struct device_attribute *attr,
80                 const char *buf,
81                 size_t count)
82 {
83         struct kbase_device *kbdev = dev_get_drvdata(dev);
84         struct kbase_ipa_context *ctx = kbdev->ipa_ctx;
85         unsigned long capacitance;
86         size_t i;
87         int err;
88
89         err = kstrtoul(buf, 0, &capacitance);
90         if (err < 0)
91                 return err;
92         if (capacitance > U32_MAX)
93                 return -ERANGE;
94
95         mutex_lock(&ctx->ipa_lock);
96         for (i = 0; i < ARRAY_SIZE(ctx->groups); i++) {
97                 if (!strcmp(ctx->groups[i].name, attr->attr.name)) {
98                         ctx->groups[i].capacitance = capacitance;
99                         mutex_unlock(&ctx->ipa_lock);
100                         return count;
101                 }
102         }
103         mutex_unlock(&ctx->ipa_lock);
104         return -EINVAL;
105 }
106
107 static DEVICE_ATTR(group0, S_IRUGO | S_IWUSR, show_ipa_group, set_ipa_group);
108 static DEVICE_ATTR(group1, S_IRUGO | S_IWUSR, show_ipa_group, set_ipa_group);
109 static DEVICE_ATTR(group2, S_IRUGO | S_IWUSR, show_ipa_group, set_ipa_group);
110 static DEVICE_ATTR(group3, S_IRUGO | S_IWUSR, show_ipa_group, set_ipa_group);
111 static DEVICE_ATTR(group4, S_IRUGO | S_IWUSR, show_ipa_group, set_ipa_group);
112 static DEVICE_ATTR(group5, S_IRUGO | S_IWUSR, show_ipa_group, set_ipa_group);
113 static DEVICE_ATTR(group6, S_IRUGO | S_IWUSR, show_ipa_group, set_ipa_group);
114 static DEVICE_ATTR(group7, S_IRUGO | S_IWUSR, show_ipa_group, set_ipa_group);
115
116 static struct attribute *kbase_ipa_attrs[] = {
117         &dev_attr_group0.attr,
118         &dev_attr_group1.attr,
119         &dev_attr_group2.attr,
120         &dev_attr_group3.attr,
121         &dev_attr_group4.attr,
122         &dev_attr_group5.attr,
123         &dev_attr_group6.attr,
124         &dev_attr_group7.attr,
125         NULL,
126 };
127
128 static struct attribute_group kbase_ipa_attr_group = {
129         .name = "ipa",
130         .attrs = kbase_ipa_attrs,
131 };
132
133 static void init_ipa_groups(struct kbase_ipa_context *ctx)
134 {
135         memcpy(ctx->groups, ipa_groups_def, sizeof(ctx->groups));
136 }
137
138 #if defined(CONFIG_OF) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
139 static int update_ipa_groups_from_dt(struct kbase_ipa_context *ctx)
140 {
141         struct kbase_device *kbdev = ctx->kbdev;
142         struct device_node *np, *child;
143         struct ipa_group *group;
144         size_t nr_groups;
145         size_t i;
146         int err;
147
148         np = of_find_node_by_name(kbdev->dev->of_node, "ipa-groups");
149         if (!np)
150                 return 0;
151
152         nr_groups = 0;
153         for_each_available_child_of_node(np, child)
154                 nr_groups++;
155         if (!nr_groups || nr_groups > ARRAY_SIZE(ctx->groups)) {
156                 dev_err(kbdev->dev, "invalid number of IPA groups: %zu", nr_groups);
157                 err = -EINVAL;
158                 goto err0;
159         }
160
161         for_each_available_child_of_node(np, child) {
162                 const char *name;
163                 u32 capacitance;
164
165                 name = of_get_property(child, "label", NULL);
166                 if (!name) {
167                         dev_err(kbdev->dev, "label missing for IPA group");
168                         err = -EINVAL;
169                         goto err0;
170                 }
171                 err = of_property_read_u32(child, "capacitance",
172                                 &capacitance);
173                 if (err < 0) {
174                         dev_err(kbdev->dev, "capacitance missing for IPA group");
175                         goto err0;
176                 }
177
178                 for (i = 0; i < ARRAY_SIZE(ctx->groups); i++) {
179                         group = &ctx->groups[i];
180                         if (!strcmp(group->name, name)) {
181                                 group->capacitance = capacitance;
182                                 break;
183                         }
184                 }
185         }
186
187         of_node_put(np);
188         return 0;
189 err0:
190         of_node_put(np);
191         return err;
192 }
193 #else
194 static int update_ipa_groups_from_dt(struct kbase_ipa_context *ctx)
195 {
196         return 0;
197 }
198 #endif
199
200 static int reset_ipa_groups(struct kbase_ipa_context *ctx)
201 {
202         init_ipa_groups(ctx);
203         return update_ipa_groups_from_dt(ctx);
204 }
205
206 static inline u32 read_hwcnt(struct kbase_ipa_context *ctx,
207         u32 offset)
208 {
209         u8 *p = ctx->vinstr_buffer;
210
211         return *(u32 *)&p[offset];
212 }
213
214 static inline u32 add_saturate(u32 a, u32 b)
215 {
216         if (U32_MAX - a < b)
217                 return U32_MAX;
218         return a + b;
219 }
220
221 /*
222  * Calculate power estimation based on hardware counter `c'
223  * across all shader cores.
224  */
225 static u32 calc_power_sc_single(struct kbase_ipa_context *ctx,
226         struct ipa_group *group, u32 c)
227 {
228         struct kbase_device *kbdev = ctx->kbdev;
229         u64 core_mask;
230         u32 base = 0, r = 0;
231
232         core_mask = kbdev->gpu_props.props.coherency_info.group[0].core_mask;
233         while (core_mask != 0ull) {
234                 if ((core_mask & 1ull) != 0ull) {
235                         u64 n = read_hwcnt(ctx, base + c);
236                         u32 d = read_hwcnt(ctx, GPU_ACTIVE);
237                         u32 s = group->capacitance;
238
239                         r = add_saturate(r, div_u64(n * s, d));
240                 }
241                 base += NR_CNT_PER_BLOCK * NR_BYTES_PER_CNT;
242                 core_mask >>= 1;
243         }
244         return r;
245 }
246
247 /*
248  * Calculate power estimation based on hardware counter `c1'
249  * and `c2' across all shader cores.
250  */
251 static u32 calc_power_sc_double(struct kbase_ipa_context *ctx,
252         struct ipa_group *group, u32 c1, u32 c2)
253 {
254         struct kbase_device *kbdev = ctx->kbdev;
255         u64 core_mask;
256         u32 base = 0, r = 0;
257
258         core_mask = kbdev->gpu_props.props.coherency_info.group[0].core_mask;
259         while (core_mask != 0ull) {
260                 if ((core_mask & 1ull) != 0ull) {
261                         u64 n = read_hwcnt(ctx, base + c1);
262                         u32 d = read_hwcnt(ctx, GPU_ACTIVE);
263                         u32 s = group->capacitance;
264
265                         r = add_saturate(r, div_u64(n * s, d));
266                         n = read_hwcnt(ctx, base + c2);
267                         r = add_saturate(r, div_u64(n * s, d));
268                 }
269                 base += NR_CNT_PER_BLOCK * NR_BYTES_PER_CNT;
270                 core_mask >>= 1;
271         }
272         return r;
273 }
274
275 static u32 calc_power_single(struct kbase_ipa_context *ctx,
276         struct ipa_group *group, u32 c)
277 {
278         u64 n = read_hwcnt(ctx, c);
279         u32 d = read_hwcnt(ctx, GPU_ACTIVE);
280         u32 s = group->capacitance;
281
282         return div_u64(n * s, d);
283 }
284
285 static u32 calc_power_group0(struct kbase_ipa_context *ctx,
286                 struct ipa_group *group)
287 {
288         return calc_power_single(ctx, group, L2_ANY_LOOKUP);
289 }
290
291 static u32 calc_power_group1(struct kbase_ipa_context *ctx,
292                 struct ipa_group *group)
293 {
294         return calc_power_single(ctx, group, TILER_ACTIVE);
295 }
296
297 static u32 calc_power_group2(struct kbase_ipa_context *ctx,
298                 struct ipa_group *group)
299 {
300         return calc_power_sc_single(ctx, group, FRAG_ACTIVE);
301 }
302
303 static u32 calc_power_group3(struct kbase_ipa_context *ctx,
304                 struct ipa_group *group)
305 {
306         return calc_power_sc_double(ctx, group, VARY_SLOT_32,
307                         VARY_SLOT_16);
308 }
309
310 static u32 calc_power_group4(struct kbase_ipa_context *ctx,
311                 struct ipa_group *group)
312 {
313         return calc_power_sc_single(ctx, group, TEX_COORD_ISSUE);
314 }
315
316 static u32 calc_power_group5(struct kbase_ipa_context *ctx,
317                 struct ipa_group *group)
318 {
319         return calc_power_sc_single(ctx, group, EXEC_INSTR_COUNT);
320 }
321
322 static u32 calc_power_group6(struct kbase_ipa_context *ctx,
323                 struct ipa_group *group)
324 {
325         return calc_power_sc_double(ctx, group, BEATS_RD_LSC,
326                         BEATS_WR_LSC);
327 }
328
329 static u32 calc_power_group7(struct kbase_ipa_context *ctx,
330                 struct ipa_group *group)
331 {
332         return calc_power_sc_single(ctx, group, EXEC_CORE_ACTIVE);
333 }
334
335 static int attach_vinstr(struct kbase_ipa_context *ctx)
336 {
337         struct kbase_device *kbdev = ctx->kbdev;
338         struct kbase_uk_hwcnt_reader_setup setup;
339         size_t dump_size;
340
341         dump_size = kbase_vinstr_dump_size(kbdev);
342         ctx->vinstr_buffer = kzalloc(dump_size, GFP_KERNEL);
343         if (!ctx->vinstr_buffer) {
344                 dev_err(kbdev->dev, "Failed to allocate IPA dump buffer");
345                 return -1;
346         }
347
348         setup.jm_bm = ~0u;
349         setup.shader_bm = ~0u;
350         setup.tiler_bm = ~0u;
351         setup.mmu_l2_bm = ~0u;
352         ctx->vinstr_cli = kbase_vinstr_hwcnt_kernel_setup(kbdev->vinstr_ctx,
353                         &setup, ctx->vinstr_buffer);
354         if (!ctx->vinstr_cli) {
355                 dev_err(kbdev->dev, "Failed to register IPA with vinstr core");
356                 kfree(ctx->vinstr_buffer);
357                 ctx->vinstr_buffer = NULL;
358                 return -1;
359         }
360         return 0;
361 }
362
363 static void detach_vinstr(struct kbase_ipa_context *ctx)
364 {
365         if (ctx->vinstr_cli)
366                 kbase_vinstr_detach_client(ctx->vinstr_cli);
367         ctx->vinstr_cli = NULL;
368         kfree(ctx->vinstr_buffer);
369         ctx->vinstr_buffer = NULL;
370 }
371
372 struct kbase_ipa_context *kbase_ipa_init(struct kbase_device *kbdev)
373 {
374         struct kbase_ipa_context *ctx;
375         int err;
376
377         ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
378         if (!ctx)
379                 return NULL;
380
381         mutex_init(&ctx->ipa_lock);
382         ctx->kbdev = kbdev;
383
384         err = reset_ipa_groups(ctx);
385         if (err < 0)
386                 goto err0;
387
388         err = sysfs_create_group(&kbdev->dev->kobj, &kbase_ipa_attr_group);
389         if (err < 0)
390                 goto err0;
391
392         return ctx;
393 err0:
394         kfree(ctx);
395         return NULL;
396 }
397
398 void kbase_ipa_term(struct kbase_ipa_context *ctx)
399 {
400         struct kbase_device *kbdev = ctx->kbdev;
401
402         detach_vinstr(ctx);
403         sysfs_remove_group(&kbdev->dev->kobj, &kbase_ipa_attr_group);
404         kfree(ctx);
405 }
406
407 u32 kbase_ipa_dynamic_power(struct kbase_ipa_context *ctx, int *err)
408 {
409         struct ipa_group *group;
410         u32 power = 0;
411         size_t i;
412
413         mutex_lock(&ctx->ipa_lock);
414         if (!ctx->vinstr_cli) {
415                 *err = attach_vinstr(ctx);
416                 if (*err < 0)
417                         goto err0;
418         }
419         *err = kbase_vinstr_hwc_dump(ctx->vinstr_cli,
420                         BASE_HWCNT_READER_EVENT_MANUAL);
421         if (*err)
422                 goto err0;
423         for (i = 0; i < ARRAY_SIZE(ctx->groups); i++) {
424                 group = &ctx->groups[i];
425                 power = add_saturate(power, group->calc_power(ctx, group));
426         }
427 err0:
428         mutex_unlock(&ctx->ipa_lock);
429         return power;
430 }
431 KBASE_EXPORT_TEST_API(kbase_ipa_dynamic_power);