mali_kbase_ipa.c 10 KB

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