1a00eda7dSDaniele Ceraolo Spurio // SPDX-License-Identifier: MIT
2a00eda7dSDaniele Ceraolo Spurio
3a00eda7dSDaniele Ceraolo Spurio /*
4a00eda7dSDaniele Ceraolo Spurio * Copyright © 2020 Intel Corporation
5a00eda7dSDaniele Ceraolo Spurio */
6a00eda7dSDaniele Ceraolo Spurio
7*b87d3901SMatt Roper #include <linux/bitmap.h>
801fabda8SLucas De Marchi #include <linux/string_helpers.h>
901fabda8SLucas De Marchi
10a00eda7dSDaniele Ceraolo Spurio #include "i915_drv.h"
11022f324cSLucas De Marchi #include "intel_gt_debugfs.h"
120d6419e9SMatt Roper #include "intel_gt_regs.h"
13022f324cSLucas De Marchi #include "intel_sseu_debugfs.h"
14a00eda7dSDaniele Ceraolo Spurio
cherryview_sseu_device_status(struct intel_gt * gt,struct sseu_dev_info * sseu)15a00eda7dSDaniele Ceraolo Spurio static void cherryview_sseu_device_status(struct intel_gt *gt,
16a00eda7dSDaniele Ceraolo Spurio struct sseu_dev_info *sseu)
17a00eda7dSDaniele Ceraolo Spurio {
18a00eda7dSDaniele Ceraolo Spurio #define SS_MAX 2
19a00eda7dSDaniele Ceraolo Spurio struct intel_uncore *uncore = gt->uncore;
20a00eda7dSDaniele Ceraolo Spurio const int ss_max = SS_MAX;
21a00eda7dSDaniele Ceraolo Spurio u32 sig1[SS_MAX], sig2[SS_MAX];
22a00eda7dSDaniele Ceraolo Spurio int ss;
23a00eda7dSDaniele Ceraolo Spurio
24a00eda7dSDaniele Ceraolo Spurio sig1[0] = intel_uncore_read(uncore, CHV_POWER_SS0_SIG1);
25a00eda7dSDaniele Ceraolo Spurio sig1[1] = intel_uncore_read(uncore, CHV_POWER_SS1_SIG1);
26a00eda7dSDaniele Ceraolo Spurio sig2[0] = intel_uncore_read(uncore, CHV_POWER_SS0_SIG2);
27a00eda7dSDaniele Ceraolo Spurio sig2[1] = intel_uncore_read(uncore, CHV_POWER_SS1_SIG2);
28a00eda7dSDaniele Ceraolo Spurio
29a00eda7dSDaniele Ceraolo Spurio for (ss = 0; ss < ss_max; ss++) {
30a00eda7dSDaniele Ceraolo Spurio unsigned int eu_cnt;
31a00eda7dSDaniele Ceraolo Spurio
32a00eda7dSDaniele Ceraolo Spurio if (sig1[ss] & CHV_SS_PG_ENABLE)
33a00eda7dSDaniele Ceraolo Spurio /* skip disabled subslice */
34a00eda7dSDaniele Ceraolo Spurio continue;
35a00eda7dSDaniele Ceraolo Spurio
36a00eda7dSDaniele Ceraolo Spurio sseu->slice_mask = BIT(0);
37*b87d3901SMatt Roper sseu->subslice_mask.hsw[0] |= BIT(ss);
38a00eda7dSDaniele Ceraolo Spurio eu_cnt = ((sig1[ss] & CHV_EU08_PG_ENABLE) ? 0 : 2) +
39a00eda7dSDaniele Ceraolo Spurio ((sig1[ss] & CHV_EU19_PG_ENABLE) ? 0 : 2) +
40a00eda7dSDaniele Ceraolo Spurio ((sig1[ss] & CHV_EU210_PG_ENABLE) ? 0 : 2) +
41a00eda7dSDaniele Ceraolo Spurio ((sig2[ss] & CHV_EU311_PG_ENABLE) ? 0 : 2);
42a00eda7dSDaniele Ceraolo Spurio sseu->eu_total += eu_cnt;
43a00eda7dSDaniele Ceraolo Spurio sseu->eu_per_subslice = max_t(unsigned int,
44a00eda7dSDaniele Ceraolo Spurio sseu->eu_per_subslice, eu_cnt);
45a00eda7dSDaniele Ceraolo Spurio }
46a00eda7dSDaniele Ceraolo Spurio #undef SS_MAX
47a00eda7dSDaniele Ceraolo Spurio }
48a00eda7dSDaniele Ceraolo Spurio
gen11_sseu_device_status(struct intel_gt * gt,struct sseu_dev_info * sseu)496266992cSLucas De Marchi static void gen11_sseu_device_status(struct intel_gt *gt,
50a00eda7dSDaniele Ceraolo Spurio struct sseu_dev_info *sseu)
51a00eda7dSDaniele Ceraolo Spurio {
52eb962faeSMatt Roper #define SS_MAX 8
53a00eda7dSDaniele Ceraolo Spurio struct intel_uncore *uncore = gt->uncore;
54a00eda7dSDaniele Ceraolo Spurio const struct intel_gt_info *info = >->info;
55a00eda7dSDaniele Ceraolo Spurio u32 s_reg[SS_MAX], eu_reg[2 * SS_MAX], eu_mask[2];
56a00eda7dSDaniele Ceraolo Spurio int s, ss;
57a00eda7dSDaniele Ceraolo Spurio
58a00eda7dSDaniele Ceraolo Spurio for (s = 0; s < info->sseu.max_slices; s++) {
59a00eda7dSDaniele Ceraolo Spurio /*
60a00eda7dSDaniele Ceraolo Spurio * FIXME: Valid SS Mask respects the spec and read
61a00eda7dSDaniele Ceraolo Spurio * only valid bits for those registers, excluding reserved
62a00eda7dSDaniele Ceraolo Spurio * although this seems wrong because it would leave many
63a00eda7dSDaniele Ceraolo Spurio * subslices without ACK.
64a00eda7dSDaniele Ceraolo Spurio */
65a00eda7dSDaniele Ceraolo Spurio s_reg[s] = intel_uncore_read(uncore, GEN10_SLICE_PGCTL_ACK(s)) &
66a00eda7dSDaniele Ceraolo Spurio GEN10_PGCTL_VALID_SS_MASK(s);
67a00eda7dSDaniele Ceraolo Spurio eu_reg[2 * s] = intel_uncore_read(uncore,
68a00eda7dSDaniele Ceraolo Spurio GEN10_SS01_EU_PGCTL_ACK(s));
69a00eda7dSDaniele Ceraolo Spurio eu_reg[2 * s + 1] = intel_uncore_read(uncore,
70a00eda7dSDaniele Ceraolo Spurio GEN10_SS23_EU_PGCTL_ACK(s));
71a00eda7dSDaniele Ceraolo Spurio }
72a00eda7dSDaniele Ceraolo Spurio
73a00eda7dSDaniele Ceraolo Spurio eu_mask[0] = GEN9_PGCTL_SSA_EU08_ACK |
74a00eda7dSDaniele Ceraolo Spurio GEN9_PGCTL_SSA_EU19_ACK |
75a00eda7dSDaniele Ceraolo Spurio GEN9_PGCTL_SSA_EU210_ACK |
76a00eda7dSDaniele Ceraolo Spurio GEN9_PGCTL_SSA_EU311_ACK;
77a00eda7dSDaniele Ceraolo Spurio eu_mask[1] = GEN9_PGCTL_SSB_EU08_ACK |
78a00eda7dSDaniele Ceraolo Spurio GEN9_PGCTL_SSB_EU19_ACK |
79a00eda7dSDaniele Ceraolo Spurio GEN9_PGCTL_SSB_EU210_ACK |
80a00eda7dSDaniele Ceraolo Spurio GEN9_PGCTL_SSB_EU311_ACK;
81a00eda7dSDaniele Ceraolo Spurio
82a00eda7dSDaniele Ceraolo Spurio for (s = 0; s < info->sseu.max_slices; s++) {
83a00eda7dSDaniele Ceraolo Spurio if ((s_reg[s] & GEN9_PGCTL_SLICE_ACK) == 0)
84a00eda7dSDaniele Ceraolo Spurio /* skip disabled slice */
85a00eda7dSDaniele Ceraolo Spurio continue;
86a00eda7dSDaniele Ceraolo Spurio
87a00eda7dSDaniele Ceraolo Spurio sseu->slice_mask |= BIT(s);
88*b87d3901SMatt Roper sseu->subslice_mask.hsw[s] = info->sseu.subslice_mask.hsw[s];
89a00eda7dSDaniele Ceraolo Spurio
90a00eda7dSDaniele Ceraolo Spurio for (ss = 0; ss < info->sseu.max_subslices; ss++) {
91a00eda7dSDaniele Ceraolo Spurio unsigned int eu_cnt;
92a00eda7dSDaniele Ceraolo Spurio
93a00eda7dSDaniele Ceraolo Spurio if (info->sseu.has_subslice_pg &&
94a00eda7dSDaniele Ceraolo Spurio !(s_reg[s] & (GEN9_PGCTL_SS_ACK(ss))))
95a00eda7dSDaniele Ceraolo Spurio /* skip disabled subslice */
96a00eda7dSDaniele Ceraolo Spurio continue;
97a00eda7dSDaniele Ceraolo Spurio
98a00eda7dSDaniele Ceraolo Spurio eu_cnt = 2 * hweight32(eu_reg[2 * s + ss / 2] &
99a00eda7dSDaniele Ceraolo Spurio eu_mask[ss % 2]);
100a00eda7dSDaniele Ceraolo Spurio sseu->eu_total += eu_cnt;
101a00eda7dSDaniele Ceraolo Spurio sseu->eu_per_subslice = max_t(unsigned int,
102a00eda7dSDaniele Ceraolo Spurio sseu->eu_per_subslice,
103a00eda7dSDaniele Ceraolo Spurio eu_cnt);
104a00eda7dSDaniele Ceraolo Spurio }
105a00eda7dSDaniele Ceraolo Spurio }
106a00eda7dSDaniele Ceraolo Spurio #undef SS_MAX
107a00eda7dSDaniele Ceraolo Spurio }
108a00eda7dSDaniele Ceraolo Spurio
gen9_sseu_device_status(struct intel_gt * gt,struct sseu_dev_info * sseu)109a00eda7dSDaniele Ceraolo Spurio static void gen9_sseu_device_status(struct intel_gt *gt,
110a00eda7dSDaniele Ceraolo Spurio struct sseu_dev_info *sseu)
111a00eda7dSDaniele Ceraolo Spurio {
112a00eda7dSDaniele Ceraolo Spurio #define SS_MAX 3
113a00eda7dSDaniele Ceraolo Spurio struct intel_uncore *uncore = gt->uncore;
114a00eda7dSDaniele Ceraolo Spurio const struct intel_gt_info *info = >->info;
115a00eda7dSDaniele Ceraolo Spurio u32 s_reg[SS_MAX], eu_reg[2 * SS_MAX], eu_mask[2];
116a00eda7dSDaniele Ceraolo Spurio int s, ss;
117a00eda7dSDaniele Ceraolo Spurio
118a00eda7dSDaniele Ceraolo Spurio for (s = 0; s < info->sseu.max_slices; s++) {
119a00eda7dSDaniele Ceraolo Spurio s_reg[s] = intel_uncore_read(uncore, GEN9_SLICE_PGCTL_ACK(s));
120a00eda7dSDaniele Ceraolo Spurio eu_reg[2 * s] =
121a00eda7dSDaniele Ceraolo Spurio intel_uncore_read(uncore, GEN9_SS01_EU_PGCTL_ACK(s));
122a00eda7dSDaniele Ceraolo Spurio eu_reg[2 * s + 1] =
123a00eda7dSDaniele Ceraolo Spurio intel_uncore_read(uncore, GEN9_SS23_EU_PGCTL_ACK(s));
124a00eda7dSDaniele Ceraolo Spurio }
125a00eda7dSDaniele Ceraolo Spurio
126a00eda7dSDaniele Ceraolo Spurio eu_mask[0] = GEN9_PGCTL_SSA_EU08_ACK |
127a00eda7dSDaniele Ceraolo Spurio GEN9_PGCTL_SSA_EU19_ACK |
128a00eda7dSDaniele Ceraolo Spurio GEN9_PGCTL_SSA_EU210_ACK |
129a00eda7dSDaniele Ceraolo Spurio GEN9_PGCTL_SSA_EU311_ACK;
130a00eda7dSDaniele Ceraolo Spurio eu_mask[1] = GEN9_PGCTL_SSB_EU08_ACK |
131a00eda7dSDaniele Ceraolo Spurio GEN9_PGCTL_SSB_EU19_ACK |
132a00eda7dSDaniele Ceraolo Spurio GEN9_PGCTL_SSB_EU210_ACK |
133a00eda7dSDaniele Ceraolo Spurio GEN9_PGCTL_SSB_EU311_ACK;
134a00eda7dSDaniele Ceraolo Spurio
135a00eda7dSDaniele Ceraolo Spurio for (s = 0; s < info->sseu.max_slices; s++) {
136a00eda7dSDaniele Ceraolo Spurio if ((s_reg[s] & GEN9_PGCTL_SLICE_ACK) == 0)
137a00eda7dSDaniele Ceraolo Spurio /* skip disabled slice */
138a00eda7dSDaniele Ceraolo Spurio continue;
139a00eda7dSDaniele Ceraolo Spurio
140a00eda7dSDaniele Ceraolo Spurio sseu->slice_mask |= BIT(s);
141a00eda7dSDaniele Ceraolo Spurio
142a00eda7dSDaniele Ceraolo Spurio if (IS_GEN9_BC(gt->i915))
143*b87d3901SMatt Roper sseu->subslice_mask.hsw[s] = info->sseu.subslice_mask.hsw[s];
144a00eda7dSDaniele Ceraolo Spurio
145a00eda7dSDaniele Ceraolo Spurio for (ss = 0; ss < info->sseu.max_subslices; ss++) {
146a00eda7dSDaniele Ceraolo Spurio unsigned int eu_cnt;
147a00eda7dSDaniele Ceraolo Spurio
148a00eda7dSDaniele Ceraolo Spurio if (IS_GEN9_LP(gt->i915)) {
149a00eda7dSDaniele Ceraolo Spurio if (!(s_reg[s] & (GEN9_PGCTL_SS_ACK(ss))))
150a00eda7dSDaniele Ceraolo Spurio /* skip disabled subslice */
151a00eda7dSDaniele Ceraolo Spurio continue;
152a00eda7dSDaniele Ceraolo Spurio
153*b87d3901SMatt Roper sseu->subslice_mask.hsw[s] |= BIT(ss);
154a00eda7dSDaniele Ceraolo Spurio }
155a00eda7dSDaniele Ceraolo Spurio
156a00eda7dSDaniele Ceraolo Spurio eu_cnt = eu_reg[2 * s + ss / 2] & eu_mask[ss % 2];
157a00eda7dSDaniele Ceraolo Spurio eu_cnt = 2 * hweight32(eu_cnt);
158a00eda7dSDaniele Ceraolo Spurio
159a00eda7dSDaniele Ceraolo Spurio sseu->eu_total += eu_cnt;
160a00eda7dSDaniele Ceraolo Spurio sseu->eu_per_subslice = max_t(unsigned int,
161a00eda7dSDaniele Ceraolo Spurio sseu->eu_per_subslice,
162a00eda7dSDaniele Ceraolo Spurio eu_cnt);
163a00eda7dSDaniele Ceraolo Spurio }
164a00eda7dSDaniele Ceraolo Spurio }
165a00eda7dSDaniele Ceraolo Spurio #undef SS_MAX
166a00eda7dSDaniele Ceraolo Spurio }
167a00eda7dSDaniele Ceraolo Spurio
bdw_sseu_device_status(struct intel_gt * gt,struct sseu_dev_info * sseu)168a00eda7dSDaniele Ceraolo Spurio static void bdw_sseu_device_status(struct intel_gt *gt,
169a00eda7dSDaniele Ceraolo Spurio struct sseu_dev_info *sseu)
170a00eda7dSDaniele Ceraolo Spurio {
171a00eda7dSDaniele Ceraolo Spurio const struct intel_gt_info *info = >->info;
172a00eda7dSDaniele Ceraolo Spurio u32 slice_info = intel_uncore_read(gt->uncore, GEN8_GT_SLICE_INFO);
173a00eda7dSDaniele Ceraolo Spurio int s;
174a00eda7dSDaniele Ceraolo Spurio
175a00eda7dSDaniele Ceraolo Spurio sseu->slice_mask = slice_info & GEN8_LSLICESTAT_MASK;
176a00eda7dSDaniele Ceraolo Spurio
177a00eda7dSDaniele Ceraolo Spurio if (sseu->slice_mask) {
178a00eda7dSDaniele Ceraolo Spurio sseu->eu_per_subslice = info->sseu.eu_per_subslice;
179a00eda7dSDaniele Ceraolo Spurio for (s = 0; s < fls(sseu->slice_mask); s++)
180*b87d3901SMatt Roper sseu->subslice_mask.hsw[s] = info->sseu.subslice_mask.hsw[s];
181a00eda7dSDaniele Ceraolo Spurio sseu->eu_total = sseu->eu_per_subslice *
182a00eda7dSDaniele Ceraolo Spurio intel_sseu_subslice_total(sseu);
183a00eda7dSDaniele Ceraolo Spurio
184a00eda7dSDaniele Ceraolo Spurio /* subtract fused off EU(s) from enabled slice(s) */
185a00eda7dSDaniele Ceraolo Spurio for (s = 0; s < fls(sseu->slice_mask); s++) {
186a00eda7dSDaniele Ceraolo Spurio u8 subslice_7eu = info->sseu.subslice_7eu[s];
187a00eda7dSDaniele Ceraolo Spurio
188a00eda7dSDaniele Ceraolo Spurio sseu->eu_total -= hweight8(subslice_7eu);
189a00eda7dSDaniele Ceraolo Spurio }
190a00eda7dSDaniele Ceraolo Spurio }
191a00eda7dSDaniele Ceraolo Spurio }
192a00eda7dSDaniele Ceraolo Spurio
i915_print_sseu_info(struct seq_file * m,bool is_available_info,bool has_pooled_eu,const struct sseu_dev_info * sseu)193a00eda7dSDaniele Ceraolo Spurio static void i915_print_sseu_info(struct seq_file *m,
194a00eda7dSDaniele Ceraolo Spurio bool is_available_info,
195a00eda7dSDaniele Ceraolo Spurio bool has_pooled_eu,
196a00eda7dSDaniele Ceraolo Spurio const struct sseu_dev_info *sseu)
197a00eda7dSDaniele Ceraolo Spurio {
198a00eda7dSDaniele Ceraolo Spurio const char *type = is_available_info ? "Available" : "Enabled";
199a00eda7dSDaniele Ceraolo Spurio
200a00eda7dSDaniele Ceraolo Spurio seq_printf(m, " %s Slice Mask: %04x\n", type,
201a00eda7dSDaniele Ceraolo Spurio sseu->slice_mask);
202a00eda7dSDaniele Ceraolo Spurio seq_printf(m, " %s Slice Total: %u\n", type,
203a00eda7dSDaniele Ceraolo Spurio hweight8(sseu->slice_mask));
204a00eda7dSDaniele Ceraolo Spurio seq_printf(m, " %s Subslice Total: %u\n", type,
205a00eda7dSDaniele Ceraolo Spurio intel_sseu_subslice_total(sseu));
206*b87d3901SMatt Roper intel_sseu_print_ss_info(type, sseu, m);
207a00eda7dSDaniele Ceraolo Spurio seq_printf(m, " %s EU Total: %u\n", type,
208a00eda7dSDaniele Ceraolo Spurio sseu->eu_total);
209a00eda7dSDaniele Ceraolo Spurio seq_printf(m, " %s EU Per Subslice: %u\n", type,
210a00eda7dSDaniele Ceraolo Spurio sseu->eu_per_subslice);
211a00eda7dSDaniele Ceraolo Spurio
212a00eda7dSDaniele Ceraolo Spurio if (!is_available_info)
213a00eda7dSDaniele Ceraolo Spurio return;
214a00eda7dSDaniele Ceraolo Spurio
21501fabda8SLucas De Marchi seq_printf(m, " Has Pooled EU: %s\n", str_yes_no(has_pooled_eu));
216a00eda7dSDaniele Ceraolo Spurio if (has_pooled_eu)
217a00eda7dSDaniele Ceraolo Spurio seq_printf(m, " Min EU in pool: %u\n", sseu->min_eu_in_pool);
218a00eda7dSDaniele Ceraolo Spurio
219a00eda7dSDaniele Ceraolo Spurio seq_printf(m, " Has Slice Power Gating: %s\n",
22001fabda8SLucas De Marchi str_yes_no(sseu->has_slice_pg));
221a00eda7dSDaniele Ceraolo Spurio seq_printf(m, " Has Subslice Power Gating: %s\n",
22201fabda8SLucas De Marchi str_yes_no(sseu->has_subslice_pg));
223a00eda7dSDaniele Ceraolo Spurio seq_printf(m, " Has EU Power Gating: %s\n",
22401fabda8SLucas De Marchi str_yes_no(sseu->has_eu_pg));
225a00eda7dSDaniele Ceraolo Spurio }
226a00eda7dSDaniele Ceraolo Spurio
227a00eda7dSDaniele Ceraolo Spurio /*
228a00eda7dSDaniele Ceraolo Spurio * this is called from top-level debugfs as well, so we can't get the gt from
229a00eda7dSDaniele Ceraolo Spurio * the seq_file.
230a00eda7dSDaniele Ceraolo Spurio */
intel_sseu_status(struct seq_file * m,struct intel_gt * gt)231a00eda7dSDaniele Ceraolo Spurio int intel_sseu_status(struct seq_file *m, struct intel_gt *gt)
232a00eda7dSDaniele Ceraolo Spurio {
233a00eda7dSDaniele Ceraolo Spurio struct drm_i915_private *i915 = gt->i915;
234a00eda7dSDaniele Ceraolo Spurio const struct intel_gt_info *info = >->info;
2354dc3a1e5SJohn Harrison struct sseu_dev_info *sseu;
236a00eda7dSDaniele Ceraolo Spurio intel_wakeref_t wakeref;
237a00eda7dSDaniele Ceraolo Spurio
238fa20cbddSLucas De Marchi if (GRAPHICS_VER(i915) < 8)
239a00eda7dSDaniele Ceraolo Spurio return -ENODEV;
240a00eda7dSDaniele Ceraolo Spurio
241a00eda7dSDaniele Ceraolo Spurio seq_puts(m, "SSEU Device Info\n");
242a00eda7dSDaniele Ceraolo Spurio i915_print_sseu_info(m, true, HAS_POOLED_EU(i915), &info->sseu);
243a00eda7dSDaniele Ceraolo Spurio
244a00eda7dSDaniele Ceraolo Spurio seq_puts(m, "SSEU Device Status\n");
2454dc3a1e5SJohn Harrison
2464dc3a1e5SJohn Harrison sseu = kzalloc(sizeof(*sseu), GFP_KERNEL);
2474dc3a1e5SJohn Harrison if (!sseu)
2484dc3a1e5SJohn Harrison return -ENOMEM;
2494dc3a1e5SJohn Harrison
2504dc3a1e5SJohn Harrison intel_sseu_set_info(sseu, info->sseu.max_slices,
251a00eda7dSDaniele Ceraolo Spurio info->sseu.max_subslices,
252a00eda7dSDaniele Ceraolo Spurio info->sseu.max_eus_per_subslice);
253a00eda7dSDaniele Ceraolo Spurio
254a00eda7dSDaniele Ceraolo Spurio with_intel_runtime_pm(&i915->runtime_pm, wakeref) {
255a00eda7dSDaniele Ceraolo Spurio if (IS_CHERRYVIEW(i915))
2564dc3a1e5SJohn Harrison cherryview_sseu_device_status(gt, sseu);
257a00eda7dSDaniele Ceraolo Spurio else if (IS_BROADWELL(i915))
2584dc3a1e5SJohn Harrison bdw_sseu_device_status(gt, sseu);
259fa20cbddSLucas De Marchi else if (GRAPHICS_VER(i915) == 9)
2604dc3a1e5SJohn Harrison gen9_sseu_device_status(gt, sseu);
2616266992cSLucas De Marchi else if (GRAPHICS_VER(i915) >= 11)
2624dc3a1e5SJohn Harrison gen11_sseu_device_status(gt, sseu);
263a00eda7dSDaniele Ceraolo Spurio }
264a00eda7dSDaniele Ceraolo Spurio
2654dc3a1e5SJohn Harrison i915_print_sseu_info(m, false, HAS_POOLED_EU(i915), sseu);
2664dc3a1e5SJohn Harrison
2674dc3a1e5SJohn Harrison kfree(sseu);
268a00eda7dSDaniele Ceraolo Spurio
269a00eda7dSDaniele Ceraolo Spurio return 0;
270a00eda7dSDaniele Ceraolo Spurio }
271a00eda7dSDaniele Ceraolo Spurio
sseu_status_show(struct seq_file * m,void * unused)272a00eda7dSDaniele Ceraolo Spurio static int sseu_status_show(struct seq_file *m, void *unused)
273a00eda7dSDaniele Ceraolo Spurio {
274a00eda7dSDaniele Ceraolo Spurio struct intel_gt *gt = m->private;
275a00eda7dSDaniele Ceraolo Spurio
276a00eda7dSDaniele Ceraolo Spurio return intel_sseu_status(m, gt);
277a00eda7dSDaniele Ceraolo Spurio }
278022f324cSLucas De Marchi DEFINE_INTEL_GT_DEBUGFS_ATTRIBUTE(sseu_status);
279a00eda7dSDaniele Ceraolo Spurio
sseu_topology_show(struct seq_file * m,void * unused)280cc1338f2SMatt Roper static int sseu_topology_show(struct seq_file *m, void *unused)
281a00eda7dSDaniele Ceraolo Spurio {
282a00eda7dSDaniele Ceraolo Spurio struct intel_gt *gt = m->private;
283a00eda7dSDaniele Ceraolo Spurio struct drm_printer p = drm_seq_file_printer(m);
284a00eda7dSDaniele Ceraolo Spurio
285cc1338f2SMatt Roper intel_sseu_print_topology(gt->i915, >->info.sseu, &p);
286a00eda7dSDaniele Ceraolo Spurio
287a00eda7dSDaniele Ceraolo Spurio return 0;
288a00eda7dSDaniele Ceraolo Spurio }
289cc1338f2SMatt Roper DEFINE_INTEL_GT_DEBUGFS_ATTRIBUTE(sseu_topology);
290a00eda7dSDaniele Ceraolo Spurio
intel_sseu_debugfs_register(struct intel_gt * gt,struct dentry * root)291a00eda7dSDaniele Ceraolo Spurio void intel_sseu_debugfs_register(struct intel_gt *gt, struct dentry *root)
292a00eda7dSDaniele Ceraolo Spurio {
293022f324cSLucas De Marchi static const struct intel_gt_debugfs_file files[] = {
294a00eda7dSDaniele Ceraolo Spurio { "sseu_status", &sseu_status_fops, NULL },
295cc1338f2SMatt Roper { "sseu_topology", &sseu_topology_fops, NULL },
296a00eda7dSDaniele Ceraolo Spurio };
297a00eda7dSDaniele Ceraolo Spurio
298a00eda7dSDaniele Ceraolo Spurio intel_gt_debugfs_register_files(root, files, ARRAY_SIZE(files), gt);
299a00eda7dSDaniele Ceraolo Spurio }
300