Linux-libre 5.4.48-gnu
[librecmc/linux-libre.git] / drivers / gpu / drm / i915 / gt / intel_sseu.c
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 }