treewide: remove redundant IS_ERR() before error code check
[linux/fpc-iii.git] / drivers / gpu / drm / i915 / gt / intel_sseu.c
blob74f793423231bcbfb8c7e578b229bfa4be55395a
1 /*
2 * SPDX-License-Identifier: MIT
4 * Copyright © 2019 Intel Corporation
5 */
7 #include "i915_drv.h"
8 #include "intel_lrc_reg.h"
9 #include "intel_sseu.h"
11 void intel_sseu_set_info(struct sseu_dev_info *sseu, u8 max_slices,
12 u8 max_subslices, u8 max_eus_per_subslice)
14 sseu->max_slices = max_slices;
15 sseu->max_subslices = max_subslices;
16 sseu->max_eus_per_subslice = max_eus_per_subslice;
18 sseu->ss_stride = GEN_SSEU_STRIDE(sseu->max_subslices);
19 GEM_BUG_ON(sseu->ss_stride > GEN_MAX_SUBSLICE_STRIDE);
20 sseu->eu_stride = GEN_SSEU_STRIDE(sseu->max_eus_per_subslice);
21 GEM_BUG_ON(sseu->eu_stride > GEN_MAX_EU_STRIDE);
24 unsigned int
25 intel_sseu_subslice_total(const struct sseu_dev_info *sseu)
27 unsigned int i, total = 0;
29 for (i = 0; i < ARRAY_SIZE(sseu->subslice_mask); i++)
30 total += hweight8(sseu->subslice_mask[i]);
32 return total;
35 u32 intel_sseu_get_subslices(const struct sseu_dev_info *sseu, u8 slice)
37 int i, offset = slice * sseu->ss_stride;
38 u32 mask = 0;
40 GEM_BUG_ON(slice >= sseu->max_slices);
42 for (i = 0; i < sseu->ss_stride; i++)
43 mask |= (u32)sseu->subslice_mask[offset + i] <<
44 i * BITS_PER_BYTE;
46 return mask;
49 void intel_sseu_set_subslices(struct sseu_dev_info *sseu, int slice,
50 u32 ss_mask)
52 int offset = slice * sseu->ss_stride;
54 memcpy(&sseu->subslice_mask[offset], &ss_mask, sseu->ss_stride);
57 unsigned int
58 intel_sseu_subslices_per_slice(const struct sseu_dev_info *sseu, u8 slice)
60 return hweight32(intel_sseu_get_subslices(sseu, slice));
63 u32 intel_sseu_make_rpcs(struct drm_i915_private *i915,
64 const struct intel_sseu *req_sseu)
66 const struct sseu_dev_info *sseu = &RUNTIME_INFO(i915)->sseu;
67 bool subslice_pg = sseu->has_subslice_pg;
68 struct intel_sseu ctx_sseu;
69 u8 slices, subslices;
70 u32 rpcs = 0;
73 * No explicit RPCS request is needed to ensure full
74 * slice/subslice/EU enablement prior to Gen9.
76 if (INTEL_GEN(i915) < 9)
77 return 0;
80 * If i915/perf is active, we want a stable powergating configuration
81 * on the system.
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.
87 if (!i915->perf.exclusive_stream) {
88 ctx_sseu = *req_sseu;
89 } else {
90 ctx_sseu = intel_sseu_from_device_info(sseu);
92 if (IS_GEN(i915, 11)) {
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.
98 ctx_sseu.subslice_mask =
99 ~(~0 << (hweight8(ctx_sseu.subslice_mask) / 2));
100 ctx_sseu.slice_mask = 0x1;
104 slices = hweight8(ctx_sseu.slice_mask);
105 subslices = hweight8(ctx_sseu.subslice_mask);
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.
112 * According to documentation software must consider the configuration
113 * as 2x4x8 and hardware will translate this to 1x8x8.
115 * Furthemore, even though SScount is three bits, maximum documented
116 * value for it is four. From this some rules/restrictions follow:
118 * 1.
119 * If enabled subslice count is greater than four, two whole slices must
120 * be enabled instead.
122 * 2.
123 * When more than one slice is enabled, hardware ignores the subslice
124 * count altogether.
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.
132 if (IS_GEN(i915, 11) &&
133 slices == 1 &&
134 subslices > min_t(u8, 4, hweight8(sseu->subslice_mask[0]) / 2)) {
135 GEM_BUG_ON(subslices & 1);
137 subslice_pg = false;
138 slices *= 2;
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.
147 if (sseu->has_slice_pg) {
148 u32 mask, val = slices;
150 if (INTEL_GEN(i915) >= 11) {
151 mask = GEN11_RPCS_S_CNT_MASK;
152 val <<= GEN11_RPCS_S_CNT_SHIFT;
153 } else {
154 mask = GEN8_RPCS_S_CNT_MASK;
155 val <<= GEN8_RPCS_S_CNT_SHIFT;
158 GEM_BUG_ON(val & ~mask);
159 val &= mask;
161 rpcs |= GEN8_RPCS_ENABLE | GEN8_RPCS_S_CNT_ENABLE | val;
164 if (subslice_pg) {
165 u32 val = subslices;
167 val <<= GEN8_RPCS_SS_CNT_SHIFT;
169 GEM_BUG_ON(val & ~GEN8_RPCS_SS_CNT_MASK);
170 val &= GEN8_RPCS_SS_CNT_MASK;
172 rpcs |= GEN8_RPCS_ENABLE | GEN8_RPCS_SS_CNT_ENABLE | val;
175 if (sseu->has_eu_pg) {
176 u32 val;
178 val = ctx_sseu.min_eus_per_subslice << GEN8_RPCS_EU_MIN_SHIFT;
179 GEM_BUG_ON(val & ~GEN8_RPCS_EU_MIN_MASK);
180 val &= GEN8_RPCS_EU_MIN_MASK;
182 rpcs |= val;
184 val = ctx_sseu.max_eus_per_subslice << GEN8_RPCS_EU_MAX_SHIFT;
185 GEM_BUG_ON(val & ~GEN8_RPCS_EU_MAX_MASK);
186 val &= GEN8_RPCS_EU_MAX_MASK;
188 rpcs |= val;
190 rpcs |= GEN8_RPCS_ENABLE;
193 return rpcs;