2 * SPDX-License-Identifier: MIT
4 * Copyright © 2019 Intel Corporation
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
);
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
]);
35 u32
intel_sseu_get_subslices(const struct sseu_dev_info
*sseu
, u8 slice
)
37 int i
, offset
= slice
* sseu
->ss_stride
;
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
] <<
49 void intel_sseu_set_subslices(struct sseu_dev_info
*sseu
, int slice
,
52 int offset
= slice
* sseu
->ss_stride
;
54 memcpy(&sseu
->subslice_mask
[offset
], &ss_mask
, sseu
->ss_stride
);
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
;
73 * No explicit RPCS request is needed to ensure full
74 * slice/subslice/EU enablement prior to Gen9.
76 if (INTEL_GEN(i915
) < 9)
80 * If i915/perf is active, we want a stable powergating configuration
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
) {
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:
119 * If enabled subslice count is greater than four, two whole slices must
120 * be enabled instead.
123 * When more than one slice is enabled, hardware ignores the subslice
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
132 if (IS_GEN(i915
, 11) &&
134 subslices
> min_t(u8
, 4, hweight8(sseu
->subslice_mask
[0]) / 2)) {
135 GEM_BUG_ON(subslices
& 1);
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
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
;
154 mask
= GEN8_RPCS_S_CNT_MASK
;
155 val
<<= GEN8_RPCS_S_CNT_SHIFT
;
158 GEM_BUG_ON(val
& ~mask
);
161 rpcs
|= GEN8_RPCS_ENABLE
| GEN8_RPCS_S_CNT_ENABLE
| val
;
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
) {
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
;
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
;
190 rpcs
|= GEN8_RPCS_ENABLE
;