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