intel_llc.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. // SPDX-License-Identifier: MIT
  2. /*
  3. * Copyright © 2019 Intel Corporation
  4. */
  5. #include <asm/tsc.h>
  6. #include <linux/cpufreq.h>
  7. #include "i915_drv.h"
  8. #include "i915_reg.h"
  9. #include "intel_gt.h"
  10. #include "intel_llc.h"
  11. #include "intel_mchbar_regs.h"
  12. #include "intel_pcode.h"
  13. #include "intel_rps.h"
  14. struct ia_constants {
  15. unsigned int min_gpu_freq;
  16. unsigned int max_gpu_freq;
  17. unsigned int min_ring_freq;
  18. unsigned int max_ia_freq;
  19. };
  20. static struct intel_gt *llc_to_gt(struct intel_llc *llc)
  21. {
  22. return container_of(llc, struct intel_gt, llc);
  23. }
  24. static unsigned int cpu_max_MHz(void)
  25. {
  26. struct cpufreq_policy *policy;
  27. unsigned int max_khz;
  28. policy = cpufreq_cpu_get(0);
  29. if (policy) {
  30. max_khz = policy->cpuinfo.max_freq;
  31. cpufreq_cpu_put(policy);
  32. } else {
  33. /*
  34. * Default to measured freq if none found, PCU will ensure we
  35. * don't go over
  36. */
  37. max_khz = tsc_khz;
  38. }
  39. return max_khz / 1000;
  40. }
  41. static bool get_ia_constants(struct intel_llc *llc,
  42. struct ia_constants *consts)
  43. {
  44. struct drm_i915_private *i915 = llc_to_gt(llc)->i915;
  45. struct intel_rps *rps = &llc_to_gt(llc)->rps;
  46. if (!HAS_LLC(i915) || IS_DGFX(i915))
  47. return false;
  48. consts->max_ia_freq = cpu_max_MHz();
  49. consts->min_ring_freq =
  50. intel_uncore_read(llc_to_gt(llc)->uncore, DCLK) & 0xf;
  51. /* convert DDR frequency from units of 266.6MHz to bandwidth */
  52. consts->min_ring_freq = mult_frac(consts->min_ring_freq, 8, 3);
  53. consts->min_gpu_freq = intel_rps_get_min_raw_freq(rps);
  54. consts->max_gpu_freq = intel_rps_get_max_raw_freq(rps);
  55. return true;
  56. }
  57. static void calc_ia_freq(struct intel_llc *llc,
  58. unsigned int gpu_freq,
  59. const struct ia_constants *consts,
  60. unsigned int *out_ia_freq,
  61. unsigned int *out_ring_freq)
  62. {
  63. struct drm_i915_private *i915 = llc_to_gt(llc)->i915;
  64. const int diff = consts->max_gpu_freq - gpu_freq;
  65. unsigned int ia_freq = 0, ring_freq = 0;
  66. if (GRAPHICS_VER(i915) >= 9) {
  67. /*
  68. * ring_freq = 2 * GT. ring_freq is in 100MHz units
  69. * No floor required for ring frequency on SKL.
  70. */
  71. ring_freq = gpu_freq;
  72. } else if (GRAPHICS_VER(i915) >= 8) {
  73. /* max(2 * GT, DDR). NB: GT is 50MHz units */
  74. ring_freq = max(consts->min_ring_freq, gpu_freq);
  75. } else if (IS_HASWELL(i915)) {
  76. ring_freq = mult_frac(gpu_freq, 5, 4);
  77. ring_freq = max(consts->min_ring_freq, ring_freq);
  78. /* leave ia_freq as the default, chosen by cpufreq */
  79. } else {
  80. const int min_freq = 15;
  81. const int scale = 180;
  82. /*
  83. * On older processors, there is no separate ring
  84. * clock domain, so in order to boost the bandwidth
  85. * of the ring, we need to upclock the CPU (ia_freq).
  86. *
  87. * For GPU frequencies less than 750MHz,
  88. * just use the lowest ring freq.
  89. */
  90. if (gpu_freq < min_freq)
  91. ia_freq = 800;
  92. else
  93. ia_freq = consts->max_ia_freq - diff * scale / 2;
  94. ia_freq = DIV_ROUND_CLOSEST(ia_freq, 100);
  95. }
  96. *out_ia_freq = ia_freq;
  97. *out_ring_freq = ring_freq;
  98. }
  99. static void gen6_update_ring_freq(struct intel_llc *llc)
  100. {
  101. struct ia_constants consts;
  102. unsigned int gpu_freq;
  103. if (!get_ia_constants(llc, &consts))
  104. return;
  105. /*
  106. * Although this is unlikely on any platform during initialization,
  107. * let's ensure we don't get accidentally into infinite loop
  108. */
  109. if (consts.max_gpu_freq <= consts.min_gpu_freq)
  110. return;
  111. /*
  112. * For each potential GPU frequency, load a ring frequency we'd like
  113. * to use for memory access. We do this by specifying the IA frequency
  114. * the PCU should use as a reference to determine the ring frequency.
  115. */
  116. for (gpu_freq = consts.max_gpu_freq;
  117. gpu_freq >= consts.min_gpu_freq;
  118. gpu_freq--) {
  119. unsigned int ia_freq, ring_freq;
  120. calc_ia_freq(llc, gpu_freq, &consts, &ia_freq, &ring_freq);
  121. snb_pcode_write(llc_to_gt(llc)->uncore, GEN6_PCODE_WRITE_MIN_FREQ_TABLE,
  122. ia_freq << GEN6_PCODE_FREQ_IA_RATIO_SHIFT |
  123. ring_freq << GEN6_PCODE_FREQ_RING_RATIO_SHIFT |
  124. gpu_freq);
  125. }
  126. }
  127. void intel_llc_enable(struct intel_llc *llc)
  128. {
  129. gen6_update_ring_freq(llc);
  130. }
  131. void intel_llc_disable(struct intel_llc *llc)
  132. {
  133. /* Currently there is no HW configuration to be done to disable. */
  134. }
  135. #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
  136. #include "selftest_llc.c"
  137. #endif