3 * (C) COPYRIGHT 2015 ARM Limited. All rights reserved.
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
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.
18 #include <linux/sysfs.h>
20 #include <mali_kbase.h>
22 #define NR_IPA_GROUPS 8
24 struct kbase_ipa_context;
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
35 u32 (*calc_power)(struct kbase_ipa_context *,
39 #include <mali_kbase_ipa_tables.h>
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
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;
54 struct mutex ipa_lock;
57 static ssize_t show_ipa_group(struct device *dev,
58 struct device_attribute *attr,
61 struct kbase_device *kbdev = dev_get_drvdata(dev);
62 struct kbase_ipa_context *ctx = kbdev->ipa_ctx;
63 ssize_t count = -EINVAL;
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);
74 mutex_unlock(&ctx->ipa_lock);
78 static ssize_t set_ipa_group(struct device *dev,
79 struct device_attribute *attr,
83 struct kbase_device *kbdev = dev_get_drvdata(dev);
84 struct kbase_ipa_context *ctx = kbdev->ipa_ctx;
85 unsigned long capacitance;
89 err = kstrtoul(buf, 0, &capacitance);
92 if (capacitance > U32_MAX)
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);
103 mutex_unlock(&ctx->ipa_lock);
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);
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,
128 static struct attribute_group kbase_ipa_attr_group = {
130 .attrs = kbase_ipa_attrs,
133 static void init_ipa_groups(struct kbase_ipa_context *ctx)
135 memcpy(ctx->groups, ipa_groups_def, sizeof(ctx->groups));
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)
141 struct kbase_device *kbdev = ctx->kbdev;
142 struct device_node *np, *child;
143 struct ipa_group *group;
148 np = of_find_node_by_name(kbdev->dev->of_node, "ipa-groups");
153 for_each_available_child_of_node(np, child)
155 if (!nr_groups || nr_groups > ARRAY_SIZE(ctx->groups)) {
156 dev_err(kbdev->dev, "invalid number of IPA groups: %zu", nr_groups);
161 for_each_available_child_of_node(np, child) {
165 name = of_get_property(child, "label", NULL);
167 dev_err(kbdev->dev, "label missing for IPA group");
171 err = of_property_read_u32(child, "capacitance",
174 dev_err(kbdev->dev, "capacitance missing for IPA group");
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;
194 static int update_ipa_groups_from_dt(struct kbase_ipa_context *ctx)
200 static int reset_ipa_groups(struct kbase_ipa_context *ctx)
202 init_ipa_groups(ctx);
203 return update_ipa_groups_from_dt(ctx);
206 static inline u32 read_hwcnt(struct kbase_ipa_context *ctx,
209 u8 *p = ctx->vinstr_buffer;
211 return *(u32 *)&p[offset];
214 static inline u32 add_saturate(u32 a, u32 b)
222 * Calculate power estimation based on hardware counter `c'
223 * across all shader cores.
225 static u32 calc_power_sc_single(struct kbase_ipa_context *ctx,
226 struct ipa_group *group, u32 c)
228 struct kbase_device *kbdev = ctx->kbdev;
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;
239 r = add_saturate(r, div_u64(n * s, d));
241 base += NR_CNT_PER_BLOCK * NR_BYTES_PER_CNT;
248 * Calculate power estimation based on hardware counter `c1'
249 * and `c2' across all shader cores.
251 static u32 calc_power_sc_double(struct kbase_ipa_context *ctx,
252 struct ipa_group *group, u32 c1, u32 c2)
254 struct kbase_device *kbdev = ctx->kbdev;
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;
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));
269 base += NR_CNT_PER_BLOCK * NR_BYTES_PER_CNT;
275 static u32 calc_power_single(struct kbase_ipa_context *ctx,
276 struct ipa_group *group, u32 c)
278 u64 n = read_hwcnt(ctx, c);
279 u32 d = read_hwcnt(ctx, GPU_ACTIVE);
280 u32 s = group->capacitance;
282 return div_u64(n * s, d);
285 static u32 calc_power_group0(struct kbase_ipa_context *ctx,
286 struct ipa_group *group)
288 return calc_power_single(ctx, group, L2_ANY_LOOKUP);
291 static u32 calc_power_group1(struct kbase_ipa_context *ctx,
292 struct ipa_group *group)
294 return calc_power_single(ctx, group, TILER_ACTIVE);
297 static u32 calc_power_group2(struct kbase_ipa_context *ctx,
298 struct ipa_group *group)
300 return calc_power_sc_single(ctx, group, FRAG_ACTIVE);
303 static u32 calc_power_group3(struct kbase_ipa_context *ctx,
304 struct ipa_group *group)
306 return calc_power_sc_double(ctx, group, VARY_SLOT_32,
310 static u32 calc_power_group4(struct kbase_ipa_context *ctx,
311 struct ipa_group *group)
313 return calc_power_sc_single(ctx, group, TEX_COORD_ISSUE);
316 static u32 calc_power_group5(struct kbase_ipa_context *ctx,
317 struct ipa_group *group)
319 return calc_power_sc_single(ctx, group, EXEC_INSTR_COUNT);
322 static u32 calc_power_group6(struct kbase_ipa_context *ctx,
323 struct ipa_group *group)
325 return calc_power_sc_double(ctx, group, BEATS_RD_LSC,
329 static u32 calc_power_group7(struct kbase_ipa_context *ctx,
330 struct ipa_group *group)
332 return calc_power_sc_single(ctx, group, EXEC_CORE_ACTIVE);
335 static int attach_vinstr(struct kbase_ipa_context *ctx)
337 struct kbase_device *kbdev = ctx->kbdev;
338 struct kbase_uk_hwcnt_reader_setup setup;
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");
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;
363 static void detach_vinstr(struct kbase_ipa_context *ctx)
366 kbase_vinstr_detach_client(ctx->vinstr_cli);
367 ctx->vinstr_cli = NULL;
368 kfree(ctx->vinstr_buffer);
369 ctx->vinstr_buffer = NULL;
372 struct kbase_ipa_context *kbase_ipa_init(struct kbase_device *kbdev)
374 struct kbase_ipa_context *ctx;
377 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
381 mutex_init(&ctx->ipa_lock);
384 err = reset_ipa_groups(ctx);
388 err = sysfs_create_group(&kbdev->dev->kobj, &kbase_ipa_attr_group);
398 void kbase_ipa_term(struct kbase_ipa_context *ctx)
400 struct kbase_device *kbdev = ctx->kbdev;
403 sysfs_remove_group(&kbdev->dev->kobj, &kbase_ipa_attr_group);
407 u32 kbase_ipa_dynamic_power(struct kbase_ipa_context *ctx, int *err)
409 struct ipa_group *group;
413 mutex_lock(&ctx->ipa_lock);
414 if (!ctx->vinstr_cli) {
415 *err = attach_vinstr(ctx);
419 *err = kbase_vinstr_hwc_dump(ctx->vinstr_cli,
420 BASE_HWCNT_READER_EVENT_MANUAL);
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));
428 mutex_unlock(&ctx->ipa_lock);
431 KBASE_EXPORT_TEST_API(kbase_ipa_dynamic_power);