LCOV - code coverage report
Current view: top level - drivers/gpu/drm/i915/gt - intel_llc.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 0 60 0.0 %
Date: 2022-03-28 15:32:58 Functions: 0 6 0.0 %
Branches: 0 20 0.0 %

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

Generated by: LCOV version 1.14