root/drivers/gpu/drm/i915/gt/intel_sseu.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. intel_sseu_subslice_total
  2. intel_sseu_subslices_per_slice
  3. intel_sseu_make_rpcs

   1 /*
   2  * SPDX-License-Identifier: MIT
   3  *
   4  * Copyright © 2019 Intel Corporation
   5  */
   6 
   7 #include "i915_drv.h"
   8 #include "intel_lrc_reg.h"
   9 #include "intel_sseu.h"
  10 
  11 unsigned int
  12 intel_sseu_subslice_total(const struct sseu_dev_info *sseu)
  13 {
  14         unsigned int i, total = 0;
  15 
  16         for (i = 0; i < ARRAY_SIZE(sseu->subslice_mask); i++)
  17                 total += hweight8(sseu->subslice_mask[i]);
  18 
  19         return total;
  20 }
  21 
  22 unsigned int
  23 intel_sseu_subslices_per_slice(const struct sseu_dev_info *sseu, u8 slice)
  24 {
  25         return hweight8(sseu->subslice_mask[slice]);
  26 }
  27 
  28 u32 intel_sseu_make_rpcs(struct drm_i915_private *i915,
  29                          const struct intel_sseu *req_sseu)
  30 {
  31         const struct sseu_dev_info *sseu = &RUNTIME_INFO(i915)->sseu;
  32         bool subslice_pg = sseu->has_subslice_pg;
  33         struct intel_sseu ctx_sseu;
  34         u8 slices, subslices;
  35         u32 rpcs = 0;
  36 
  37         /*
  38          * No explicit RPCS request is needed to ensure full
  39          * slice/subslice/EU enablement prior to Gen9.
  40          */
  41         if (INTEL_GEN(i915) < 9)
  42                 return 0;
  43 
  44         /*
  45          * If i915/perf is active, we want a stable powergating configuration
  46          * on the system.
  47          *
  48          * We could choose full enablement, but on ICL we know there are use
  49          * cases which disable slices for functional, apart for performance
  50          * reasons. So in this case we select a known stable subset.
  51          */
  52         if (!i915->perf.exclusive_stream) {
  53                 ctx_sseu = *req_sseu;
  54         } else {
  55                 ctx_sseu = intel_sseu_from_device_info(sseu);
  56 
  57                 if (IS_GEN(i915, 11)) {
  58                         /*
  59                          * We only need subslice count so it doesn't matter
  60                          * which ones we select - just turn off low bits in the
  61                          * amount of half of all available subslices per slice.
  62                          */
  63                         ctx_sseu.subslice_mask =
  64                                 ~(~0 << (hweight8(ctx_sseu.subslice_mask) / 2));
  65                         ctx_sseu.slice_mask = 0x1;
  66                 }
  67         }
  68 
  69         slices = hweight8(ctx_sseu.slice_mask);
  70         subslices = hweight8(ctx_sseu.subslice_mask);
  71 
  72         /*
  73          * Since the SScount bitfield in GEN8_R_PWR_CLK_STATE is only three bits
  74          * wide and Icelake has up to eight subslices, specfial programming is
  75          * needed in order to correctly enable all subslices.
  76          *
  77          * According to documentation software must consider the configuration
  78          * as 2x4x8 and hardware will translate this to 1x8x8.
  79          *
  80          * Furthemore, even though SScount is three bits, maximum documented
  81          * value for it is four. From this some rules/restrictions follow:
  82          *
  83          * 1.
  84          * If enabled subslice count is greater than four, two whole slices must
  85          * be enabled instead.
  86          *
  87          * 2.
  88          * When more than one slice is enabled, hardware ignores the subslice
  89          * count altogether.
  90          *
  91          * From these restrictions it follows that it is not possible to enable
  92          * a count of subslices between the SScount maximum of four restriction,
  93          * and the maximum available number on a particular SKU. Either all
  94          * subslices are enabled, or a count between one and four on the first
  95          * slice.
  96          */
  97         if (IS_GEN(i915, 11) &&
  98             slices == 1 &&
  99             subslices > min_t(u8, 4, hweight8(sseu->subslice_mask[0]) / 2)) {
 100                 GEM_BUG_ON(subslices & 1);
 101 
 102                 subslice_pg = false;
 103                 slices *= 2;
 104         }
 105 
 106         /*
 107          * Starting in Gen9, render power gating can leave
 108          * slice/subslice/EU in a partially enabled state. We
 109          * must make an explicit request through RPCS for full
 110          * enablement.
 111          */
 112         if (sseu->has_slice_pg) {
 113                 u32 mask, val = slices;
 114 
 115                 if (INTEL_GEN(i915) >= 11) {
 116                         mask = GEN11_RPCS_S_CNT_MASK;
 117                         val <<= GEN11_RPCS_S_CNT_SHIFT;
 118                 } else {
 119                         mask = GEN8_RPCS_S_CNT_MASK;
 120                         val <<= GEN8_RPCS_S_CNT_SHIFT;
 121                 }
 122 
 123                 GEM_BUG_ON(val & ~mask);
 124                 val &= mask;
 125 
 126                 rpcs |= GEN8_RPCS_ENABLE | GEN8_RPCS_S_CNT_ENABLE | val;
 127         }
 128 
 129         if (subslice_pg) {
 130                 u32 val = subslices;
 131 
 132                 val <<= GEN8_RPCS_SS_CNT_SHIFT;
 133 
 134                 GEM_BUG_ON(val & ~GEN8_RPCS_SS_CNT_MASK);
 135                 val &= GEN8_RPCS_SS_CNT_MASK;
 136 
 137                 rpcs |= GEN8_RPCS_ENABLE | GEN8_RPCS_SS_CNT_ENABLE | val;
 138         }
 139 
 140         if (sseu->has_eu_pg) {
 141                 u32 val;
 142 
 143                 val = ctx_sseu.min_eus_per_subslice << GEN8_RPCS_EU_MIN_SHIFT;
 144                 GEM_BUG_ON(val & ~GEN8_RPCS_EU_MIN_MASK);
 145                 val &= GEN8_RPCS_EU_MIN_MASK;
 146 
 147                 rpcs |= val;
 148 
 149                 val = ctx_sseu.max_eus_per_subslice << GEN8_RPCS_EU_MAX_SHIFT;
 150                 GEM_BUG_ON(val & ~GEN8_RPCS_EU_MAX_MASK);
 151                 val &= GEN8_RPCS_EU_MAX_MASK;
 152 
 153                 rpcs |= val;
 154 
 155                 rpcs |= GEN8_RPCS_ENABLE;
 156         }
 157 
 158         return rpcs;
 159 }

/* [<][>][^][v][top][bottom][index][help] */