i915_sysfs.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /*
  2. * Copyright © 2012 Intel Corporation
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a
  5. * copy of this software and associated documentation files (the "Software"),
  6. * to deal in the Software without restriction, including without limitation
  7. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8. * and/or sell copies of the Software, and to permit persons to whom the
  9. * Software is furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice (including the next
  12. * paragraph) shall be included in all copies or substantial portions of the
  13. * Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  18. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  20. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  21. * IN THE SOFTWARE.
  22. *
  23. * Authors:
  24. * Ben Widawsky <ben@bwidawsk.net>
  25. *
  26. */
  27. #include <linux/device.h>
  28. #include <linux/module.h>
  29. #include <linux/stat.h>
  30. #include <linux/sysfs.h>
  31. #include "i915_drv.h"
  32. static u32 calc_residency(struct drm_device *dev, const u32 reg)
  33. {
  34. struct drm_i915_private *dev_priv = dev->dev_private;
  35. u64 raw_time; /* 32b value may overflow during fixed point math */
  36. if (!intel_enable_rc6(dev))
  37. return 0;
  38. raw_time = I915_READ(reg) * 128ULL;
  39. return DIV_ROUND_UP_ULL(raw_time, 100000);
  40. }
  41. static ssize_t
  42. show_rc6_mask(struct device *dev, struct device_attribute *attr, char *buf)
  43. {
  44. struct drm_minor *dminor = container_of(dev, struct drm_minor, kdev);
  45. return snprintf(buf, PAGE_SIZE, "%x", intel_enable_rc6(dminor->dev));
  46. }
  47. static ssize_t
  48. show_rc6_ms(struct device *dev, struct device_attribute *attr, char *buf)
  49. {
  50. struct drm_minor *dminor = container_of(dev, struct drm_minor, kdev);
  51. u32 rc6_residency = calc_residency(dminor->dev, GEN6_GT_GFX_RC6);
  52. return snprintf(buf, PAGE_SIZE, "%u", rc6_residency);
  53. }
  54. static ssize_t
  55. show_rc6p_ms(struct device *dev, struct device_attribute *attr, char *buf)
  56. {
  57. struct drm_minor *dminor = container_of(dev, struct drm_minor, kdev);
  58. u32 rc6p_residency = calc_residency(dminor->dev, GEN6_GT_GFX_RC6p);
  59. return snprintf(buf, PAGE_SIZE, "%u", rc6p_residency);
  60. }
  61. static ssize_t
  62. show_rc6pp_ms(struct device *dev, struct device_attribute *attr, char *buf)
  63. {
  64. struct drm_minor *dminor = container_of(dev, struct drm_minor, kdev);
  65. u32 rc6pp_residency = calc_residency(dminor->dev, GEN6_GT_GFX_RC6pp);
  66. return snprintf(buf, PAGE_SIZE, "%u", rc6pp_residency);
  67. }
  68. static DEVICE_ATTR(rc6_enable, S_IRUGO, show_rc6_mask, NULL);
  69. static DEVICE_ATTR(rc6_residency_ms, S_IRUGO, show_rc6_ms, NULL);
  70. static DEVICE_ATTR(rc6p_residency_ms, S_IRUGO, show_rc6p_ms, NULL);
  71. static DEVICE_ATTR(rc6pp_residency_ms, S_IRUGO, show_rc6pp_ms, NULL);
  72. static struct attribute *rc6_attrs[] = {
  73. &dev_attr_rc6_enable.attr,
  74. &dev_attr_rc6_residency_ms.attr,
  75. &dev_attr_rc6p_residency_ms.attr,
  76. &dev_attr_rc6pp_residency_ms.attr,
  77. NULL
  78. };
  79. static struct attribute_group rc6_attr_group = {
  80. .name = power_group_name,
  81. .attrs = rc6_attrs
  82. };
  83. void i915_setup_sysfs(struct drm_device *dev)
  84. {
  85. int ret;
  86. /* ILK doesn't have any residency information */
  87. if (INTEL_INFO(dev)->gen < 6)
  88. return;
  89. ret = sysfs_merge_group(&dev->primary->kdev.kobj, &rc6_attr_group);
  90. if (ret)
  91. DRM_ERROR("sysfs setup failed\n");
  92. }
  93. void i915_teardown_sysfs(struct drm_device *dev)
  94. {
  95. sysfs_unmerge_group(&dev->primary->kdev.kobj, &rc6_attr_group);
  96. }